Created members-gateway-protocol package (#5)

This commit is contained in:
Fabien O'Carroll 2019-04-18 11:03:44 +02:00 committed by GitHub
parent 99c4a454ad
commit 182b43b5b2
13 changed files with 170 additions and 81 deletions

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2018-2019 Ghost Foundation
Copyright (c) 2019 Ghost Foundation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -0,0 +1,58 @@
# Members Gateway Protocol
This package provides a low-level wrapper around the gateway iframe, which is used to communicate with the members api.
## Install
`npm install @tryghost/members-gateway-protocol --save`
or
`yarn add @tryghost/members-gateway-protocol`
## Usage
```js
const gatewayProtocol = require('@tryghost/members-gateway-protocol');
const gatewayFrame = document.querySelector('iframe');
const { call, listen } = gatewayProtocol(gatewayFrame);
// Add listener for gateway events - limited to only once
// returns boolean indicating whether listener was added
listen(function ({event, payload}) {
// Called for every event emitted from the gateway
});
// Call method in gateway
call('getToken', {audience: 'whatever'}, function (err, result) {
// Called once when gateway responds
});
```
## Develop
This is a mono repository, managed with [lerna](https://lernajs.io/).
Follow the instructions for the top-level repo.
1. `git clone` this repo & `cd` into it as usual
2. Run `yarn` to install top-level dependencies.
## Run
- `yarn dev`
## Test
- `yarn lint` run just eslint
- `yarn test` run lint and tests
# Copyright & License
Copyright (c) 2019 Ghost Foundation - Released under the [MIT license](LICENSE).

View File

@ -7,7 +7,7 @@ module.exports = function layer0(frame) {
})(1);
var origin = new URL(frame.getAttribute('src')).origin;
var handlers = {};
var listener = function () {};
var listener = null;
window.addEventListener('message', function (event) {
if (event.origin !== origin) {
@ -15,7 +15,7 @@ module.exports = function layer0(frame) {
}
if (!event.data || !event.data.uid) {
if (event.data.event) {
return listener(event.data);
return listener && listener(event.data);
}
return;
}
@ -35,8 +35,15 @@ module.exports = function layer0(frame) {
}
function listen(fn) {
if (listener) {
return false;
}
listener = fn;
return true;
}
return {call, listen};
return {
call: call,
listen: listen
};
};

View File

@ -0,0 +1,29 @@
{
"name": "@tryghost/members-gateway-protocol",
"version": "0.0.0",
"repository": "https://github.com/TryGhost/Members/tree/master/packages/members-gateway-protocol",
"author": "Ghost Foundation",
"license": "MIT",
"main": "index.js",
"scripts": {
"dev": "echo \"Implement me!\"",
"test": "NODE_ENV=testing mocha './test/**/*.test.js'",
"lint": "eslint '**/*.js'",
"posttest": "yarn lint"
},
"files": [
"index.js",
"lib"
],
"devDependencies": {
"jsdom": "14.0.0",
"mocha": "6.1.3",
"should": "13.2.3",
"sinon": "7.3.1"
},
"dependencies": {
"bluebird": "^3.5.4",
"ghost-ignition": "^3.1.0",
"lodash": "^4.17.11"
}
}

View File

@ -0,0 +1,72 @@
// Switch these lines once there are useful utils
// const testUtils = require('./utils');
require('./utils');
const JSDOM = require('jsdom').JSDOM;
const gatewayProtocol = require('../');
const origin = 'https://sauce.net';
const dom = new JSDOM(`
<iframe src="${origin}"></iframe>
`);
const window = global.window = dom.window;
const document = global.document = dom.window.document;
const postMessage = data => window.dispatchEvent(new window.MessageEvent('message', {
origin,
data
}));
describe('@tryghost/members-gateway-protocol', function () {
it('exports a function', function () {
should.equal(typeof gatewayProtocol, 'function');
});
describe('gatewayProtocol: (frame: IFrame) -> {call: Function, listen: Function}', function () {
it('returns an object with call and listen methods', function () {
const iframe = document.body.querySelector('iframe');
const protocol = gatewayProtocol(iframe);
should.equal(typeof protocol.call, 'function');
should.equal(typeof protocol.listen, 'function');
});
describe('listen: (listener: (event: Object) -> void) -> listening: Boolean', function () {
it('attaches a single listener to messages posted to the window from the frame', function (done) {
const iframe = document.body.querySelector('iframe');
const protocol = gatewayProtocol(iframe);
const firstListening = protocol.listen(function ({event, payload}) {
should.equal(event, 'event-name');
should.equal(payload, 'payload-data');
done();
});
const secondListening = protocol.listen(function () {
done(should.fail());
});
should.equal(firstListening, true);
should.equal(secondListening, false);
postMessage({event: 'event-name', payload: 'payload-data'});
});
});
describe('call: (method: String, options: Object, callback: (err: Error, data: Object) -> void) -> void', function () {
it('calls a method on the iframe, and handles the result through callback', function (done) {
const iframe = document.body.querySelector('iframe');
const protocol = gatewayProtocol(iframe);
iframe.contentWindow.addEventListener('message', function (event) {
if (event.data.method === 'someMethod') {
return postMessage({
uid: event.data.uid,
error: null,
data: event.data.options.toJoin.join('-')
});
}
});
protocol.call('someMethod', {toJoin: ['some', 'data']}, function (err, result) {
should.equal(err, null);
should.equal(result, 'some-data');
done();
});
});
});
});
});

View File

@ -3,7 +3,6 @@
// Taken from the should wiki, this is how to make should global
// Should is a global in our eslint test config
global.should = require('should').noConflict();
should.extend();
// Sinon is a simple case
// Sinon is a global in our eslint test config

View File

@ -1,39 +0,0 @@
# Layer 0
## Install
`npm install @tryghost/layer-0 --save`
or
`yarn add @tryghost/layer-0`
## Usage
## Develop
This is a mono repository, managed with [lerna](https://lernajs.io/).
Follow the instructions for the top-level repo.
1. `git clone` this repo & `cd` into it as usual
2. Run `yarn` to install top-level dependencies.
## Run
- `yarn dev`
## Test
- `yarn lint` run just eslint
- `yarn test` run lint and tests
# Copyright & License
Copyright (c) 2018-2019 Ghost Foundation - Released under the [MIT license](LICENSE).

View File

@ -1,27 +0,0 @@
{
"name": "@tryghost/members-layer0",
"version": "0.0.0",
"repository": "https://github.com/TryGhost/Ghost-SDKs/tree/master/packages/layer0",
"author": "Ghost Foundation",
"license": "MIT",
"main": "index.js",
"scripts": {
"dev": "echo \"Implement me!\"",
"test": "NODE_ENV=testing mocha './test/**/*.test.js'",
"lint": "eslint . --ext .js --cache",
"posttest": "yarn lint"
},
"publishConfig": {
"access": "public"
},
"devDependencies": {
"mocha": "5.2.0",
"should": "13.2.3",
"sinon": "7.1.1"
},
"dependencies": {
"bluebird": "^3.5.3",
"ghost-ignition": "^2.9.6",
"lodash": "^4.17.11"
}
}

View File

@ -1,10 +0,0 @@
// Switch these lines once there are useful utils
// const testUtils = require('./utils');
require('./utils');
describe('Hello world', function () {
it('Runs a test', function () {
// TODO: Write me!
'hello'.should.eql('hello');
});
});