pryv 2.1.8 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +12 -45
- package/src/Auth/AuthController.js +43 -50
- package/src/Auth/AuthStates.js +12 -12
- package/src/Auth/LoginMessages.js +17 -14
- package/src/Auth/index.js +18 -15
- package/src/Browser/CookieUtils.js +37 -27
- package/src/Browser/LoginButton.js +42 -37
- package/src/Browser/index.js +16 -42
- package/src/Connection.js +102 -95
- package/src/Service.js +47 -45
- package/src/ServiceAssets.js +42 -34
- package/src/browser-index-bundle.js +8 -0
- package/src/browser-index.js +7 -0
- package/src/index.d.ts +833 -0
- package/src/index.js +20 -3
- package/src/lib/browser-getEventStreamed.js +21 -19
- package/src/lib/json-parser.js +23 -24
- package/src/utils.js +55 -43
- package/test/Browser.AuthController.test.js +19 -21
- package/test/Browser.test.js +23 -26
- package/test/Connection.test.js +164 -162
- package/test/Service.test.js +30 -44
- package/test/ServiceAssets.test.js +16 -22
- package/test/browser-index.html +26 -0
- package/test/utils.test.js +30 -35
- package/.jsdoc-conf.json +0 -29
- package/.mocharc.js +0 -13
- package/LICENSE.md +0 -27
- package/README.md +0 -723
- package/scripts/setup-environment-dev.sh +0 -28
- package/scripts/upload.sh +0 -15
- package/src/Pryv.js +0 -19
- package/src/index-socket.io-monitor.js +0 -4
- package/src/index.html +0 -17
- package/test/browser-index.js +0 -11
- package/test/browser-tests.html +0 -31
- package/test/helpers.js +0 -8
- package/test/load-test-account.js +0 -108
- package/test/test-data.js +0 -92
- package/web-demos/auth-with-redirection.html +0 -72
- package/web-demos/auth.html +0 -77
- package/web-demos/custom-login-button.html +0 -158
- package/web-demos/index.html +0 -186
- package/web-demos/service-info.json +0 -13
- package/web-demos/stream-examples.html +0 -80
- package/webpack.config.js +0 -71
|
@@ -1,16 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* [BSD-3-Clause](https://github.com/pryv/lib-js/blob/master/LICENSE)
|
|
4
|
+
*/
|
|
1
5
|
const Cookies = require('./CookieUtils');
|
|
2
6
|
const AuthStates = require('../Auth/AuthStates');
|
|
3
7
|
const AuthController = require('../Auth/AuthController');
|
|
4
|
-
const Service = require('../Service');
|
|
5
8
|
const Messages = require('../Auth/LoginMessages');
|
|
6
9
|
const utils = require('../utils');
|
|
7
10
|
|
|
11
|
+
/* global location, confirm */
|
|
12
|
+
|
|
8
13
|
/**
|
|
9
|
-
* @memberof
|
|
14
|
+
* @memberof pryv.Browser
|
|
10
15
|
*/
|
|
11
16
|
class LoginButton {
|
|
12
|
-
|
|
13
|
-
constructor(authSettings, service) {
|
|
17
|
+
constructor (authSettings, service) {
|
|
14
18
|
this.authSettings = authSettings;
|
|
15
19
|
this.service = service;
|
|
16
20
|
this.serviceInfo = service.infoSync();
|
|
@@ -22,14 +26,14 @@ class LoginButton {
|
|
|
22
26
|
async init () {
|
|
23
27
|
// initialize button visuals
|
|
24
28
|
setupButton(this);
|
|
25
|
-
this.languageCode = this.authSettings.authRequest.languageCode || 'en';
|
|
29
|
+
this.languageCode = this.authSettings.authRequest.languageCode || 'en';
|
|
26
30
|
this.messages = Messages(this.languageCode);
|
|
27
31
|
if (this.loginButtonText) {
|
|
28
32
|
await loadAssets(this);
|
|
29
33
|
}
|
|
30
34
|
// set cookie key for authorization data
|
|
31
35
|
this._cookieKey = 'pryv-libjs-' + this.authSettings.authRequest.requestingAppId;
|
|
32
|
-
|
|
36
|
+
|
|
33
37
|
// initialize controller
|
|
34
38
|
this.auth = new AuthController(this.authSettings, this.service, this);
|
|
35
39
|
await this.auth.init();
|
|
@@ -49,15 +53,16 @@ class LoginButton {
|
|
|
49
53
|
case AuthStates.INITIALIZED:
|
|
50
54
|
this.text = getInitializedMessage(this, this.serviceInfo.name);
|
|
51
55
|
break;
|
|
52
|
-
case AuthStates.NEED_SIGNIN:
|
|
56
|
+
case AuthStates.NEED_SIGNIN: {
|
|
53
57
|
const loginUrl = state.authUrl || state.url; // url is deprecated
|
|
54
|
-
if (this.authSettings.authRequest.returnURL) { // open on same page (no Popup)
|
|
55
|
-
location.href = loginUrl;
|
|
58
|
+
if (this.authSettings.authRequest.returnURL) { // open on same page (no Popup)
|
|
59
|
+
location.href = loginUrl;
|
|
56
60
|
return;
|
|
57
61
|
} else {
|
|
58
62
|
startLoginScreen(this, loginUrl);
|
|
59
63
|
}
|
|
60
64
|
break;
|
|
65
|
+
}
|
|
61
66
|
case AuthStates.AUTHORIZED:
|
|
62
67
|
this.text = state.username;
|
|
63
68
|
this.saveAuthorizationData({
|
|
@@ -65,13 +70,14 @@ class LoginButton {
|
|
|
65
70
|
username: state.username
|
|
66
71
|
});
|
|
67
72
|
break;
|
|
68
|
-
case AuthStates.SIGNOUT:
|
|
73
|
+
case AuthStates.SIGNOUT: {
|
|
69
74
|
const message = this.messages.SIGNOUT_CONFIRM ? this.messages.SIGNOUT_CONFIRM : 'Logout ?';
|
|
70
75
|
if (confirm(message)) {
|
|
71
76
|
this.deleteAuthorizationData();
|
|
72
77
|
this.auth.init();
|
|
73
78
|
}
|
|
74
79
|
break;
|
|
80
|
+
}
|
|
75
81
|
case AuthStates.ERROR:
|
|
76
82
|
this.text = getErrorMessage(this, state.message);
|
|
77
83
|
break;
|
|
@@ -88,7 +94,7 @@ class LoginButton {
|
|
|
88
94
|
}
|
|
89
95
|
|
|
90
96
|
saveAuthorizationData (authData) {
|
|
91
|
-
Cookies.set(this._cookieKey,authData);
|
|
97
|
+
Cookies.set(this._cookieKey, authData);
|
|
92
98
|
}
|
|
93
99
|
|
|
94
100
|
async deleteAuthorizationData () {
|
|
@@ -97,7 +103,7 @@ class LoginButton {
|
|
|
97
103
|
|
|
98
104
|
/**
|
|
99
105
|
* not mandatory to implement as non-browsers don't have this behaviour
|
|
100
|
-
* @param {*} authController
|
|
106
|
+
* @param {*} authController
|
|
101
107
|
*/
|
|
102
108
|
async finishAuthProcessAfterRedirection (authController) {
|
|
103
109
|
// this step should be applied only for the browser
|
|
@@ -105,7 +111,7 @@ class LoginButton {
|
|
|
105
111
|
|
|
106
112
|
// 3. Check if there is a prYvkey as result of "out of page login"
|
|
107
113
|
const url = window.location.href;
|
|
108
|
-
|
|
114
|
+
const pollUrl = retrievePollUrl(url);
|
|
109
115
|
if (pollUrl !== null) {
|
|
110
116
|
try {
|
|
111
117
|
const res = await utils.superagent.get(pollUrl);
|
|
@@ -133,26 +139,26 @@ class LoginButton {
|
|
|
133
139
|
}
|
|
134
140
|
}
|
|
135
141
|
|
|
142
|
+
module.exports = LoginButton;
|
|
143
|
+
|
|
136
144
|
async function startLoginScreen (loginButton, authUrl) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
loginButton.popup = window.open(authUrl, 'prYv Sign-in', features);
|
|
155
|
-
|
|
145
|
+
const screenX = typeof window.screenX !== 'undefined' ? window.screenX : window.screenLeft;
|
|
146
|
+
const screenY = typeof window.screenY !== 'undefined' ? window.screenY : window.screenTop;
|
|
147
|
+
const outerWidth = typeof window.outerWidth !== 'undefined' ? window.outerWidth : document.body.clientWidth;
|
|
148
|
+
const outerHeight = typeof window.outerHeight !== 'undefined' ? window.outerHeight : (document.body.clientHeight - 22);
|
|
149
|
+
const width = 400;
|
|
150
|
+
const height = 620;
|
|
151
|
+
const left = parseInt(screenX + ((outerWidth - width) / 2), 10);
|
|
152
|
+
const top = parseInt(screenY + ((outerHeight - height) / 2.5), 10);
|
|
153
|
+
const features = (
|
|
154
|
+
'width=' + width +
|
|
155
|
+
',height=' + height +
|
|
156
|
+
',left=' + left +
|
|
157
|
+
',top=' + top +
|
|
158
|
+
',scrollbars=yes'
|
|
159
|
+
);
|
|
160
|
+
loginButton.popup = window.open(authUrl, 'prYv Sign-in', features);
|
|
161
|
+
|
|
156
162
|
if (!loginButton.popup) {
|
|
157
163
|
// loginButton.auth.stopAuthRequest('FAILED_TO_OPEN_WINDOW');
|
|
158
164
|
console.log('Pop-up blocked. A second click should allow it.');
|
|
@@ -161,13 +167,13 @@ async function startLoginScreen (loginButton, authUrl) {
|
|
|
161
167
|
}
|
|
162
168
|
}
|
|
163
169
|
|
|
164
|
-
function setupButton(loginBtn) {
|
|
170
|
+
function setupButton (loginBtn) {
|
|
165
171
|
loginBtn.loginButtonSpan = document.getElementById(loginBtn.authSettings.spanButtonID);
|
|
166
172
|
|
|
167
173
|
if (!loginBtn.loginButtonSpan) {
|
|
168
|
-
console.log('WARNING:
|
|
174
|
+
console.log('WARNING: pryv.Browser initialized with no spanButtonID');
|
|
169
175
|
} else {
|
|
170
|
-
// up to the time the button is loaded use the Span to display eventual
|
|
176
|
+
// up to the time the button is loaded use the Span to display eventual
|
|
171
177
|
// error messages
|
|
172
178
|
loginBtn.loginButtonText = loginBtn.loginButtonSpan;
|
|
173
179
|
|
|
@@ -179,12 +185,11 @@ function setupButton(loginBtn) {
|
|
|
179
185
|
/**
|
|
180
186
|
* Loads the style from the service info
|
|
181
187
|
*/
|
|
182
|
-
async function loadAssets(loginBtn) {
|
|
188
|
+
async function loadAssets (loginBtn) {
|
|
183
189
|
const assets = await loginBtn.service.assets();
|
|
184
190
|
loginBtn.loginButtonSpan.innerHTML = await assets.loginButtonGetHTML();
|
|
185
191
|
loginBtn.loginButtonText = document.getElementById('pryv-access-btn-text');
|
|
186
192
|
}
|
|
187
|
-
module.exports = LoginButton;
|
|
188
193
|
|
|
189
194
|
function getErrorMessage (loginButton, message) {
|
|
190
195
|
return loginButton.messages.ERROR + ': ' + message;
|
package/src/Browser/index.js
CHANGED
|
@@ -1,55 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* [BSD-3-Clause](https://github.com/pryv/lib-js/blob/master/LICENSE)
|
|
4
|
+
*/
|
|
1
5
|
const LoginButton = require('./LoginButton');
|
|
2
6
|
const CookieUtils = require('./CookieUtils');
|
|
3
|
-
const Service = require('../Service');
|
|
4
7
|
const utils = require('../utils');
|
|
5
8
|
|
|
6
9
|
/**
|
|
7
|
-
* @memberof
|
|
8
|
-
* @namespace
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Start an authentication process
|
|
13
|
-
* @memberof Pryv.Browser
|
|
14
|
-
* @param {Object} settings
|
|
15
|
-
* @param {Object} settings.authRequest See https://api.pryv.com/reference/#data-structure-access
|
|
16
|
-
* @param {string} [settings.authRequest.languageCode] Language code, as per LoginButton Messages: 'en', 'fr
|
|
17
|
-
* @param {string} settings.authRequest.requestingAppId Application id, ex: 'my-app'
|
|
18
|
-
* @param {Object} settings.authRequest.requestedPermissions
|
|
19
|
-
* @param {string | boolean} settings.authRequest.returnURL : false, // set this if you don't want a popup
|
|
20
|
-
* @param {string} [settings.authRequest.referer] To track registration source
|
|
21
|
-
* @param {string} settings.spanButtonID set and <span> id in DOM to insert default login button or null for custom
|
|
22
|
-
* @param {Browser.AuthStateChangeHandler} settings.onStateChange
|
|
23
|
-
* @param {string} [settings.returnURL=auto#] Set to "self#" to disable popup and force using the same page. Set a custom url when process is finished (specific use cases). Should always end by # ? or &
|
|
24
|
-
* @param {string} serviceInfoUrl
|
|
25
|
-
* @param {Object} [serviceCustomizations] override properties of serviceInfoUrl
|
|
26
|
-
* @returns {Pryv.Service}
|
|
10
|
+
* @memberof pryv
|
|
11
|
+
* @namespace pryv.Browser
|
|
27
12
|
*/
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return service;
|
|
37
|
-
}
|
|
13
|
+
module.exports = {
|
|
14
|
+
LoginButton,
|
|
15
|
+
CookieUtils,
|
|
16
|
+
// retro-compatibility for lib-js < 2.0.9
|
|
17
|
+
AuthStates: require('../Auth/AuthStates'),
|
|
18
|
+
setupAuth: require('../Auth').setupAuth,
|
|
19
|
+
serviceInfoFromUrl: getServiceInfoFromURL
|
|
20
|
+
};
|
|
38
21
|
|
|
39
22
|
/**
|
|
40
23
|
* Util to grab parameters from url query string
|
|
41
|
-
* @param {*} url
|
|
24
|
+
* @param {*} url
|
|
42
25
|
*/
|
|
43
26
|
function getServiceInfoFromURL (url) {
|
|
44
27
|
const queryParams = utils.getQueryParamsFromURL(url || window.location.href);
|
|
45
|
-
return queryParams
|
|
28
|
+
return queryParams.pryvServiceInfoUrl;
|
|
46
29
|
}
|
|
47
|
-
|
|
48
|
-
module.exports = {
|
|
49
|
-
LoginButton: LoginButton,
|
|
50
|
-
CookieUtils: CookieUtils,
|
|
51
|
-
// retro-compatibility for lib-js < 2.0.9
|
|
52
|
-
AuthStates: require('../Auth/AuthStates'),
|
|
53
|
-
setupAuth: require('../Auth').setupAuth,
|
|
54
|
-
serviceInfoFromUrl: getServiceInfoFromURL
|
|
55
|
-
};
|
package/src/Connection.js
CHANGED
|
@@ -1,61 +1,62 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* [BSD-3-Clause](https://github.com/pryv/lib-js/blob/master/LICENSE)
|
|
4
|
+
*/
|
|
2
5
|
const utils = require('./utils.js');
|
|
3
|
-
|
|
4
6
|
const jsonParser = require('./lib/json-parser');
|
|
5
|
-
|
|
6
7
|
const browserGetEventStreamed = require('./lib/browser-getEventStreamed');
|
|
7
8
|
|
|
8
|
-
|
|
9
9
|
/**
|
|
10
10
|
* @class Connection
|
|
11
11
|
* A connection is an authenticated link to a Pryv.io account.
|
|
12
|
-
*
|
|
12
|
+
*
|
|
13
13
|
* @type {TokenAndEndpoint}
|
|
14
14
|
*
|
|
15
15
|
* @example
|
|
16
16
|
* create a connection for the user 'tom' on 'pryv.me' backend with the token 'TTZycvBTiq'
|
|
17
|
-
* const conn = new
|
|
17
|
+
* const conn = new pryv.Connection('https://TTZycvBTiq@tom.pryv.me');
|
|
18
18
|
*
|
|
19
19
|
* @property {string} [token]
|
|
20
20
|
* @property {string} endpoint
|
|
21
|
-
* @memberof
|
|
22
|
-
*
|
|
21
|
+
* @memberof pryv
|
|
22
|
+
*
|
|
23
23
|
* @constructor
|
|
24
|
-
* @this {Connection}
|
|
25
|
-
* @param {
|
|
26
|
-
* @param {
|
|
24
|
+
* @this {Connection}
|
|
25
|
+
* @param {APIEndpoint} apiEndpoint
|
|
26
|
+
* @param {pryv.Service} [service] - eventually initialize Connection with a Service
|
|
27
27
|
*/
|
|
28
28
|
class Connection {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const { token, endpoint } = utils.extractTokenAndApiEndpoint(pryvApiEndpoint);
|
|
29
|
+
constructor (apiEndpoint, service) {
|
|
30
|
+
const { token, endpoint } = utils.extractTokenAndAPIEndpoint(apiEndpoint);
|
|
32
31
|
this.token = token;
|
|
33
32
|
this.endpoint = endpoint;
|
|
34
33
|
this.options = {};
|
|
35
34
|
this.options.chunkSize = 1000;
|
|
36
35
|
this._deltaTime = { value: 0, weight: 0 };
|
|
37
|
-
if (!
|
|
36
|
+
if (service && !(service instanceof Service)) {
|
|
37
|
+
throw new Error('Invalid service param');
|
|
38
|
+
}
|
|
38
39
|
this._service = service;
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
/**
|
|
42
|
-
* get
|
|
43
|
+
* get pryv.Service object relative to this connection
|
|
43
44
|
* @readonly
|
|
44
|
-
* @property {
|
|
45
|
+
* @property {pryv.Service} service
|
|
45
46
|
*/
|
|
46
|
-
get service() {
|
|
47
|
+
get service () {
|
|
47
48
|
if (this._service) return this._service;
|
|
48
49
|
this._service = new Service(this.endpoint + 'service/info');
|
|
49
50
|
return this._service;
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
/**
|
|
53
|
-
* get username.
|
|
54
|
+
* get username.
|
|
54
55
|
* It's async as in it constructed from access info
|
|
55
|
-
* @param {*} arrayOfAPICalls
|
|
56
|
-
* @param {*} progress
|
|
56
|
+
* @param {*} arrayOfAPICalls
|
|
57
|
+
* @param {*} progress
|
|
57
58
|
*/
|
|
58
|
-
async username() {
|
|
59
|
+
async username () {
|
|
59
60
|
const accessInfo = await this.accessInfo();
|
|
60
61
|
return accessInfo.user.username;
|
|
61
62
|
}
|
|
@@ -64,8 +65,8 @@ class Connection {
|
|
|
64
65
|
* get access info
|
|
65
66
|
* It's async as it is constructed with get function.
|
|
66
67
|
*/
|
|
67
|
-
async accessInfo(){
|
|
68
|
-
return this.get(
|
|
68
|
+
async accessInfo () {
|
|
69
|
+
return this.get('access-info', null);
|
|
69
70
|
}
|
|
70
71
|
|
|
71
72
|
/**
|
|
@@ -76,19 +77,19 @@ class Connection {
|
|
|
76
77
|
* @param {Function} [progress] Return percentage of progress (0 - 100);
|
|
77
78
|
* @returns {Promise<Array>} Promise to Array of results matching each method call in order
|
|
78
79
|
*/
|
|
79
|
-
async api(arrayOfAPICalls, progress) {
|
|
80
|
-
function httpHandler(batchCall) {
|
|
80
|
+
async api (arrayOfAPICalls, progress) {
|
|
81
|
+
function httpHandler (batchCall) {
|
|
81
82
|
return this.post('', batchCall);
|
|
82
|
-
}
|
|
83
|
+
}
|
|
83
84
|
return await this._chunkedBatchCall(arrayOfAPICalls, progress, httpHandler.bind(this));
|
|
84
85
|
}
|
|
85
86
|
|
|
86
87
|
/**
|
|
87
88
|
* @private
|
|
88
89
|
*/
|
|
89
|
-
async _chunkedBatchCall(arrayOfAPICalls, progress, callHandler) {
|
|
90
|
-
if (!
|
|
91
|
-
throw new Error('
|
|
90
|
+
async _chunkedBatchCall (arrayOfAPICalls, progress, callHandler) {
|
|
91
|
+
if (!Array.isArray(arrayOfAPICalls)) {
|
|
92
|
+
throw new Error('Connection.api() takes an array as input');
|
|
92
93
|
}
|
|
93
94
|
|
|
94
95
|
const res = [];
|
|
@@ -97,86 +98,85 @@ class Connection {
|
|
|
97
98
|
const thisBatch = [];
|
|
98
99
|
const cursorMax = Math.min(cursor + this.options.chunkSize, arrayOfAPICalls.length);
|
|
99
100
|
// copy only method and params into a back call to be exuted
|
|
100
|
-
for (let i = cursor; i < cursorMax
|
|
101
|
-
thisBatch.push({ method: arrayOfAPICalls[i].method, params: arrayOfAPICalls[i].params});
|
|
101
|
+
for (let i = cursor; i < cursorMax; i++) {
|
|
102
|
+
thisBatch.push({ method: arrayOfAPICalls[i].method, params: arrayOfAPICalls[i].params });
|
|
102
103
|
}
|
|
103
104
|
const resRequest = await callHandler(thisBatch);
|
|
104
|
-
|
|
105
|
+
|
|
105
106
|
// result checks
|
|
106
|
-
if (!
|
|
107
|
+
if (!resRequest || !Array.isArray(resRequest.results)) {
|
|
107
108
|
throw new Error('API call result is not an Array: ' + JSON.stringify(resRequest));
|
|
108
109
|
}
|
|
109
|
-
if (resRequest.results.length
|
|
110
|
+
if (resRequest.results.length !== thisBatch.length) {
|
|
110
111
|
throw new Error('API call result Array does not match request: ' + JSON.stringify(resRequest));
|
|
111
112
|
}
|
|
112
113
|
|
|
113
|
-
|
|
114
|
-
// eventually call handleResult
|
|
114
|
+
// eventually call handleResult
|
|
115
115
|
for (let i = 0; i < resRequest.results.length; i++) {
|
|
116
116
|
if (arrayOfAPICalls[i + cursor].handleResult) {
|
|
117
117
|
await arrayOfAPICalls[i + cursor].handleResult.call(null, resRequest.results[i]);
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
|
-
Array.prototype.push.apply(res, resRequest.results)
|
|
121
|
-
percent =
|
|
120
|
+
Array.prototype.push.apply(res, resRequest.results);
|
|
121
|
+
percent = Math.round(100 * res.length / arrayOfAPICalls.length);
|
|
122
122
|
if (progress) { progress(percent, res); }
|
|
123
123
|
}
|
|
124
124
|
return res;
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
/**
|
|
128
|
-
* Post to API return results
|
|
129
|
-
* @param {(Array |
|
|
128
|
+
* Post to API return results
|
|
129
|
+
* @param {(Array | Object)} data
|
|
130
130
|
* @param {Object} queryParams
|
|
131
|
-
* @param {string} path
|
|
132
|
-
* @returns {Promise<Array|Object>}
|
|
131
|
+
* @param {string} path
|
|
132
|
+
* @returns {Promise<Array|Object>} Promise to result.body
|
|
133
133
|
*/
|
|
134
|
-
async post(path, data, queryParams) {
|
|
135
|
-
const now =
|
|
134
|
+
async post (path, data, queryParams) {
|
|
135
|
+
const now = getTimestamp();
|
|
136
136
|
const res = await this.postRaw(path, data, queryParams);
|
|
137
137
|
this._handleMeta(res.body, now);
|
|
138
138
|
return res.body;
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
/**
|
|
142
|
-
* Raw Post to API return superagent object
|
|
143
|
-
* @param {Array |
|
|
142
|
+
* Raw Post to API return superagent object
|
|
143
|
+
* @param {Array | Object} data
|
|
144
144
|
* @param {Object} queryParams
|
|
145
|
-
* @param {string} path
|
|
145
|
+
* @param {string} path
|
|
146
146
|
* @returns {request.superagent} Promise from superagent's post request
|
|
147
147
|
*/
|
|
148
|
-
async postRaw(path, data, queryParams) {
|
|
148
|
+
async postRaw (path, data, queryParams) {
|
|
149
149
|
return this._post(path)
|
|
150
150
|
.query(queryParams)
|
|
151
151
|
.send(data);
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
|
|
154
|
+
_post (path) {
|
|
155
155
|
return utils.superagent.post(this.endpoint + path)
|
|
156
156
|
.set('Authorization', this.token)
|
|
157
157
|
.set('accept', 'json');
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
/**
|
|
161
|
-
* Post to API return results
|
|
161
|
+
* Post to API return results
|
|
162
162
|
* @param {Object} queryParams
|
|
163
|
-
* @param {string} path
|
|
163
|
+
* @param {string} path
|
|
164
164
|
* @returns {Promise<Array|Object>} Promise to result.body
|
|
165
165
|
*/
|
|
166
|
-
async get(path, queryParams) {
|
|
167
|
-
const now =
|
|
166
|
+
async get (path, queryParams) {
|
|
167
|
+
const now = getTimestamp();
|
|
168
168
|
const res = await this.getRaw(path, queryParams);
|
|
169
169
|
this._handleMeta(res.body, now);
|
|
170
|
-
return res.body
|
|
170
|
+
return res.body;
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
/**
|
|
174
174
|
* Raw Get to API return superagent object
|
|
175
|
-
* @param {Object} queryParams
|
|
176
|
-
* @param {string} path
|
|
175
|
+
* @param {Object} queryParams
|
|
176
|
+
* @param {string} path
|
|
177
177
|
* @returns {request.superagent} Promise from superagent's get request
|
|
178
178
|
*/
|
|
179
|
-
getRaw(path, queryParams) {
|
|
179
|
+
getRaw (path, queryParams) {
|
|
180
180
|
path = path || '';
|
|
181
181
|
return utils.superagent.get(this.endpoint + path)
|
|
182
182
|
.set('Authorization', this.token)
|
|
@@ -188,7 +188,7 @@ class Connection {
|
|
|
188
188
|
* ADD Data Points to HFEvent (flatJSON format)
|
|
189
189
|
* https://api.pryv.com/reference/#add-hf-series-data-points
|
|
190
190
|
*/
|
|
191
|
-
async addPointsToHFEvent(eventId, fields, points) {
|
|
191
|
+
async addPointsToHFEvent (eventId, fields, points) {
|
|
192
192
|
const res = await this.post('events/' + eventId + '/series',
|
|
193
193
|
{
|
|
194
194
|
format: 'flatJSON',
|
|
@@ -202,26 +202,24 @@ class Connection {
|
|
|
202
202
|
}
|
|
203
203
|
|
|
204
204
|
/**
|
|
205
|
-
* Streamed get Event.
|
|
206
|
-
* Fallbacks to not streamed, for browsers that does not support `fetch()` API
|
|
205
|
+
* Streamed get Event.
|
|
206
|
+
* Fallbacks to not streamed, for browsers that does not support `fetch()` API
|
|
207
207
|
* @see https://api.pryv.com/reference/#get-events
|
|
208
208
|
* @param {Object} queryParams See `events.get` parameters
|
|
209
|
-
* @param {Function} forEachEvent Function taking one event as parameter. Will be called for each event
|
|
209
|
+
* @param {Function} forEachEvent Function taking one event as parameter. Will be called for each event
|
|
210
210
|
* @returns {Promise<Object>} Promise to result.body transformed with `eventsCount: {count}` replacing `events: [...]`
|
|
211
211
|
*/
|
|
212
|
-
async getEventsStreamed(queryParams, forEachEvent) {
|
|
212
|
+
async getEventsStreamed (queryParams, forEachEvent) {
|
|
213
213
|
const myParser = jsonParser(forEachEvent, queryParams.includeDeletions);
|
|
214
214
|
let res = null;
|
|
215
215
|
if (typeof window === 'undefined') { // node
|
|
216
216
|
res = await this.getRaw('events', queryParams)
|
|
217
217
|
.buffer(false)
|
|
218
218
|
.parse(myParser);
|
|
219
|
-
|
|
220
|
-
} else if (typeof fetch !== 'undefined' && !(typeof navigator != 'undefined' && navigator.product == 'ReactNative')) { // browser supports fetch and it is not react native
|
|
219
|
+
} else if (typeof fetch !== 'undefined' && !(typeof navigator !== 'undefined' && navigator.product === 'ReactNative')) { // browser supports fetch and it is not react native
|
|
221
220
|
res = await browserGetEventStreamed(this, queryParams, myParser);
|
|
222
|
-
|
|
223
221
|
} else { // browser no fetch supports
|
|
224
|
-
console.log('WARNING: Browser does not support fetch() required by
|
|
222
|
+
console.log('WARNING: Browser does not support fetch() required by pryv.Connection.getEventsStreamed()');
|
|
225
223
|
res = await this.getRaw('events', queryParams);
|
|
226
224
|
res.body.eventsCount = 0;
|
|
227
225
|
if (res.body.events) {
|
|
@@ -229,16 +227,16 @@ class Connection {
|
|
|
229
227
|
res.body.eventsCount += res.body.events.length;
|
|
230
228
|
delete res.body.events;
|
|
231
229
|
}
|
|
232
|
-
if (res.body.eventDeletions) { // deletions are in a seprated Array
|
|
230
|
+
if (res.body.eventDeletions) { // deletions are in a seprated Array
|
|
233
231
|
res.body.eventDeletions.forEach(forEachEvent);
|
|
234
232
|
res.body.eventsCount += res.body.eventDeletions.length;
|
|
235
233
|
delete res.body.eventDeletions;
|
|
236
234
|
}
|
|
237
235
|
}
|
|
238
236
|
|
|
239
|
-
const now =
|
|
237
|
+
const now = getTimestamp();
|
|
240
238
|
this._handleMeta(res.body, now);
|
|
241
|
-
return res.body
|
|
239
|
+
return res.body;
|
|
242
240
|
}
|
|
243
241
|
|
|
244
242
|
/**
|
|
@@ -247,31 +245,38 @@ class Connection {
|
|
|
247
245
|
* @param {Event} event
|
|
248
246
|
* @param {string} filePath
|
|
249
247
|
*/
|
|
250
|
-
async createEventWithFile(event, filePath) {
|
|
248
|
+
async createEventWithFile (event, filePath) {
|
|
251
249
|
const res = await this._post('events')
|
|
252
250
|
.field('event', JSON.stringify(event))
|
|
253
251
|
.attach('file', filePath);
|
|
254
252
|
|
|
255
|
-
const now =
|
|
253
|
+
const now = getTimestamp();
|
|
256
254
|
this._handleMeta(res.body, now);
|
|
257
|
-
return res.body
|
|
255
|
+
return res.body;
|
|
258
256
|
}
|
|
259
257
|
|
|
260
258
|
/**
|
|
261
259
|
* Create an event from a Buffer
|
|
262
|
-
* NODE.jS ONLY
|
|
263
260
|
* @param {Event} event
|
|
264
|
-
* @param {Buffer} bufferData
|
|
261
|
+
* @param {Buffer|Blob} bufferData - Buffer for node, Blob for browser
|
|
265
262
|
* @param {string} fileName
|
|
266
263
|
*/
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
.
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
264
|
+
async createEventWithFileFromBuffer (event, bufferData, filename) {
|
|
265
|
+
if (typeof window === 'undefined') { // node
|
|
266
|
+
const res = await this._post('events')
|
|
267
|
+
.field('event', JSON.stringify(event))
|
|
268
|
+
.attach('file', bufferData, filename);
|
|
269
|
+
|
|
270
|
+
const now = getTimestamp();
|
|
271
|
+
this._handleMeta(res.body, now);
|
|
272
|
+
return res.body;
|
|
273
|
+
} else {
|
|
274
|
+
/* global FormData */
|
|
275
|
+
const formData = new FormData();
|
|
276
|
+
formData.append('file', bufferData, filename);
|
|
277
|
+
const body = await this.createEventWithFormData(event, formData);
|
|
278
|
+
return body;
|
|
279
|
+
}
|
|
275
280
|
}
|
|
276
281
|
|
|
277
282
|
/**
|
|
@@ -280,10 +285,10 @@ class Connection {
|
|
|
280
285
|
* @param {Event} event
|
|
281
286
|
* @param {FormData} formData https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData
|
|
282
287
|
*/
|
|
283
|
-
async createEventWithFormData(event, formData) {
|
|
288
|
+
async createEventWithFormData (event, formData) {
|
|
284
289
|
formData.append('event', JSON.stringify(event));
|
|
285
290
|
const res = await this._post('events').send(formData);
|
|
286
|
-
return res.body
|
|
291
|
+
return res.body;
|
|
287
292
|
}
|
|
288
293
|
|
|
289
294
|
/**
|
|
@@ -292,33 +297,35 @@ class Connection {
|
|
|
292
297
|
* @readonly
|
|
293
298
|
* @property {number} deltaTime
|
|
294
299
|
*/
|
|
295
|
-
get deltaTime() {
|
|
300
|
+
get deltaTime () {
|
|
296
301
|
return this._deltaTime.value;
|
|
297
302
|
}
|
|
298
303
|
|
|
299
304
|
/**
|
|
300
|
-
*
|
|
305
|
+
* API Endpoint of this connection
|
|
301
306
|
* @readonly
|
|
302
|
-
* @property {
|
|
307
|
+
* @property {APIEndpoint} deltaTime
|
|
303
308
|
*/
|
|
304
|
-
get apiEndpoint() {
|
|
305
|
-
return utils.
|
|
309
|
+
get apiEndpoint () {
|
|
310
|
+
return utils.buildAPIEndpoint(this);
|
|
306
311
|
}
|
|
307
312
|
|
|
308
313
|
// private method that handle meta data parsing
|
|
309
|
-
|
|
314
|
+
_handleMeta (res, requestLocalTimestamp) {
|
|
310
315
|
if (!res.meta) throw new Error('Cannot find .meta in response.');
|
|
311
316
|
if (!res.meta.serverTime) throw new Error('Cannot find .meta.serverTime in response.');
|
|
312
317
|
|
|
313
|
-
// update deltaTime and weight it
|
|
318
|
+
// update deltaTime and weight it
|
|
314
319
|
this._deltaTime.value = (this._deltaTime.value * this._deltaTime.weight + res.meta.serverTime - requestLocalTimestamp) / ++this._deltaTime.weight;
|
|
315
320
|
}
|
|
316
|
-
|
|
317
321
|
}
|
|
318
322
|
|
|
319
|
-
|
|
320
323
|
module.exports = Connection;
|
|
321
324
|
|
|
325
|
+
function getTimestamp () {
|
|
326
|
+
return Date.now() / 1000;
|
|
327
|
+
}
|
|
328
|
+
|
|
322
329
|
// service is require "after" to allow circular require
|
|
323
330
|
const Service = require('./Service');
|
|
324
331
|
|
|
@@ -328,4 +335,4 @@ const Service = require('./Service');
|
|
|
328
335
|
* @property {string} method - The method id
|
|
329
336
|
* @property {(Object|Array)} params - The call parameters as required by the method.
|
|
330
337
|
* @property {(Function|Promise)} [handleResult] - Will be called with the result corresponding to this specific call.
|
|
331
|
-
*/
|
|
338
|
+
*/
|