pryv 2.2.0 → 2.3.2

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.
Files changed (46) hide show
  1. package/README.md +291 -299
  2. package/package.json +11 -45
  3. package/src/Auth/AuthController.js +43 -50
  4. package/src/Auth/AuthStates.js +12 -12
  5. package/src/Auth/LoginMessages.js +17 -14
  6. package/src/Auth/index.js +18 -15
  7. package/src/Browser/CookieUtils.js +37 -27
  8. package/src/Browser/LoginButton.js +42 -37
  9. package/src/Browser/index.js +16 -42
  10. package/src/Connection.js +102 -95
  11. package/src/Service.js +47 -45
  12. package/src/ServiceAssets.js +42 -34
  13. package/src/browser-index-bundle.js +8 -0
  14. package/src/browser-index.js +7 -0
  15. package/src/index.d.ts +37 -48
  16. package/src/index.js +20 -3
  17. package/src/lib/browser-getEventStreamed.js +21 -19
  18. package/src/lib/json-parser.js +23 -24
  19. package/src/utils.js +55 -43
  20. package/test/Browser.AuthController.test.js +19 -21
  21. package/test/Browser.test.js +23 -26
  22. package/test/Connection.test.js +135 -151
  23. package/test/Service.test.js +30 -44
  24. package/test/ServiceAssets.test.js +16 -22
  25. package/test/browser-index.html +26 -0
  26. package/test/utils.test.js +30 -35
  27. package/.jsdoc-conf.json +0 -29
  28. package/.mocharc.js +0 -13
  29. package/LICENSE.md +0 -27
  30. package/scripts/setup-environment-dev.sh +0 -28
  31. package/scripts/upload.sh +0 -15
  32. package/src/Pryv.js +0 -19
  33. package/src/index-socket.io-monitor.js +0 -4
  34. package/src/index.html +0 -17
  35. package/test/browser-index.js +0 -11
  36. package/test/browser-tests.html +0 -31
  37. package/test/helpers.js +0 -8
  38. package/test/load-test-account.js +0 -108
  39. package/test/test-data.js +0 -95
  40. package/web-demos/auth-with-redirection.html +0 -72
  41. package/web-demos/auth.html +0 -77
  42. package/web-demos/custom-login-button.html +0 -158
  43. package/web-demos/index.html +0 -186
  44. package/web-demos/service-info.json +0 -13
  45. package/web-demos/stream-examples.html +0 -80
  46. package/webpack.config.js +0 -83
@@ -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 Pryv.Browser
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
- let pollUrl = retrievePollUrl(url);
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
- let screenX = typeof window.screenX !== 'undefined' ? window.screenX : window.screenLeft,
138
- screenY = typeof window.screenY !== 'undefined' ? window.screenY : window.screenTop,
139
- outerWidth = typeof window.outerWidth !== 'undefined' ?
140
- window.outerWidth : document.body.clientWidth,
141
- outerHeight = typeof window.outerHeight !== 'undefined' ?
142
- window.outerHeight : (document.body.clientHeight - 22),
143
- width = 400,
144
- height = 620,
145
- left = parseInt(screenX + ((outerWidth - width) / 2), 10),
146
- top = parseInt(screenY + ((outerHeight - height) / 2.5), 10),
147
- features = (
148
- 'width=' + width +
149
- ',height=' + height +
150
- ',left=' + left +
151
- ',top=' + top +
152
- ',scrollbars=yes'
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: Pryv.Browser initialized with no spanButtonID');
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;
@@ -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 Pryv
8
- * @namespace Pryv.Browser
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
- async function setupAuth (settings, serviceInfoUrl, serviceCustomizations, HumanInteraction = LoginButton) {
29
-
30
- let service = new Service(serviceInfoUrl, serviceCustomizations);
31
- await service.info()
32
-
33
- const humanInteraction = new HumanInteraction(settings, service);
34
- await HumanInteraction.init();
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['pryvServiceInfoUrl'];
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 Pryv.Connection('https://TTZycvBTiq@tom.pryv.me');
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 Pryv
22
- *
21
+ * @memberof pryv
22
+ *
23
23
  * @constructor
24
- * @this {Connection}
25
- * @param {PryvApiEndpoint} pryvApiEndpoint
26
- * @param {Pryv.Service} [service] - eventually initialize Connection with a Service
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
- constructor(pryvApiEndpoint, service) {
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 (! service instanceof Service) { throw new Error('Invalid service param'); }
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 Pryv.Service object relative to this connection
43
+ * get pryv.Service object relative to this connection
43
44
  * @readonly
44
- * @property {Pryv.Service} service
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("access-info", null);
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 (! Array.isArray(arrayOfAPICalls)) {
91
- throw new Error('Pryv.api() takes an array as input');
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 ; i++) {
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 (! resRequest || ! Array.isArray(resRequest.results)) {
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 != thisBatch.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 = Math.round(100 * res.length / arrayOfAPICalls.length);
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 | Object)} data
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>} Promise to result.body
131
+ * @param {string} path
132
+ * @returns {Promise<Array|Object>} Promise to result.body
133
133
  */
134
- async post(path, data, queryParams) {
135
- const now = Date.now() / 1000;
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 | Object} data
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
- _post(path) {
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 = Date.now() / 1000;
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 Pryv.Connection.getEventsStreamed()');
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 = Date.now() / 1000;
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 = Date.now() / 1000;
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
- async createEventWithFileFromBuffer(event, bufferData, filename) {
268
- const res = await this._post('events')
269
- .field('event', JSON.stringify(event))
270
- .attach('file', bufferData, filename);
271
-
272
- const now = Date.now() / 1000;
273
- this._handleMeta(res.body, now);
274
- return res.body
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
- * Pryv API Endpoint of this connection
305
+ * API Endpoint of this connection
301
306
  * @readonly
302
- * @property {PryvApiEndpoint} deltaTime
307
+ * @property {APIEndpoint} deltaTime
303
308
  */
304
- get apiEndpoint() {
305
- return utils.buildPryvApiEndpoint(this);
309
+ get apiEndpoint () {
310
+ return utils.buildAPIEndpoint(this);
306
311
  }
307
312
 
308
313
  // private method that handle meta data parsing
309
- _handleMeta(res, requestLocalTimestamp) {
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
+ */