pryv 2.4.4 → 2.4.6

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pryv",
3
- "version": "2.4.4",
3
+ "version": "2.4.6",
4
4
  "description": "Pryv JavaScript library",
5
5
  "keywords": [
6
6
  "Pryv",
@@ -21,4 +21,4 @@
21
21
  "dependencies": {
22
22
  "superagent": "^9.0.0"
23
23
  }
24
- }
24
+ }
package/src/Connection.js CHANGED
@@ -81,7 +81,69 @@ class Connection {
81
81
  function httpHandler (batchCall) {
82
82
  return this.post('', batchCall);
83
83
  }
84
- return await this._chunkedBatchCall(arrayOfAPICalls, progress, httpHandler.bind(this));
84
+ return await this._chunkedBatchCall(
85
+ arrayOfAPICalls,
86
+ progress,
87
+ httpHandler.bind(this)
88
+ );
89
+ }
90
+
91
+ /**
92
+ * Make one api Api call
93
+ * @param {string} method - methodId
94
+ * @param {Object|Array} [params] - the params associated with this methodId
95
+ * @param {string} [resultKey] - if given, returns the value or throws an error if not present
96
+ * @throws {Error} if .error is present the response
97
+ */
98
+ async apiOne (method, params = {}, expectedKey) {
99
+ const result = await this.api([{ method, params }]);
100
+ if (
101
+ result[0] == null ||
102
+ result[0].error ||
103
+ (expectedKey != null && result[0][expectedKey] == null)
104
+ ) {
105
+ const innerObject = result[0]?.error || result;
106
+ const error = new Error(
107
+ `Error for api method: "${method}" with params: ${JSON.stringify(
108
+ params
109
+ )} >> Result: ${JSON.stringify(innerObject)}"`
110
+ );
111
+ error.innerObject = innerObject;
112
+ throw error;
113
+ }
114
+ if (expectedKey != null) return result[0][expectedKey];
115
+ return result[0];
116
+ }
117
+
118
+ /**
119
+ * Revoke : Delete the accessId
120
+ * - Do not thow error if access is already revoked, just return null;
121
+ * @param {boolean} [throwOnFail = true] - if set to false do not throw Error on failure
122
+ * @param {Connection} [usingConnection] - specify which connection issues the revoke, might be necessary when selfRovke
123
+ */
124
+ async revoke (throwOnFail = true, usingConnection) {
125
+ usingConnection = usingConnection || this;
126
+ let accessInfo = null;
127
+ // get accessId
128
+ try {
129
+ accessInfo = await this.accessInfo();
130
+ } catch (e) {
131
+ if (e.response?.body?.error?.id === 'invalid-access-token') {
132
+ return null; // Already revoked OK..
133
+ }
134
+ if (throwOnFail) throw e;
135
+ return null;
136
+ }
137
+ // delete access
138
+ try {
139
+ const result = usingConnection.apiOne('accesses.delete', {
140
+ id: accessInfo.id
141
+ });
142
+ return result;
143
+ } catch (e) {
144
+ if (throwOnFail) throw e;
145
+ return null;
146
+ }
85
147
  }
86
148
 
87
149
  /**
@@ -94,32 +156,52 @@ class Connection {
94
156
 
95
157
  const res = [];
96
158
  let percent = 0;
97
- for (let cursor = 0; arrayOfAPICalls.length >= cursor; cursor += this.options.chunkSize) {
159
+ for (
160
+ let cursor = 0;
161
+ arrayOfAPICalls.length >= cursor;
162
+ cursor += this.options.chunkSize
163
+ ) {
98
164
  const thisBatch = [];
99
- const cursorMax = Math.min(cursor + this.options.chunkSize, arrayOfAPICalls.length);
165
+ const cursorMax = Math.min(
166
+ cursor + this.options.chunkSize,
167
+ arrayOfAPICalls.length
168
+ );
100
169
  // copy only method and params into a back call to be exuted
101
170
  for (let i = cursor; i < cursorMax; i++) {
102
- thisBatch.push({ method: arrayOfAPICalls[i].method, params: arrayOfAPICalls[i].params });
171
+ thisBatch.push({
172
+ method: arrayOfAPICalls[i].method,
173
+ params: arrayOfAPICalls[i].params
174
+ });
103
175
  }
104
176
  const resRequest = await callHandler(thisBatch);
105
177
 
106
178
  // result checks
107
179
  if (!resRequest || !Array.isArray(resRequest.results)) {
108
- throw new Error('API call result is not an Array: ' + JSON.stringify(resRequest));
180
+ throw new Error(
181
+ 'API call result is not an Array: ' + JSON.stringify(resRequest)
182
+ );
109
183
  }
110
184
  if (resRequest.results.length !== thisBatch.length) {
111
- throw new Error('API call result Array does not match request: ' + JSON.stringify(resRequest));
185
+ throw new Error(
186
+ 'API call result Array does not match request: ' +
187
+ JSON.stringify(resRequest)
188
+ );
112
189
  }
113
190
 
114
191
  // eventually call handleResult
115
192
  for (let i = 0; i < resRequest.results.length; i++) {
116
193
  if (arrayOfAPICalls[i + cursor].handleResult) {
117
- await arrayOfAPICalls[i + cursor].handleResult.call(null, resRequest.results[i]);
194
+ await arrayOfAPICalls[i + cursor].handleResult.call(
195
+ null,
196
+ resRequest.results[i]
197
+ );
118
198
  }
119
199
  }
120
200
  Array.prototype.push.apply(res, resRequest.results);
121
- percent = Math.round(100 * res.length / arrayOfAPICalls.length);
122
- if (progress) { progress(percent, res); }
201
+ percent = Math.round((100 * res.length) / arrayOfAPICalls.length);
202
+ if (progress) {
203
+ progress(percent, res);
204
+ }
123
205
  }
124
206
  return res;
125
207
  }
@@ -146,13 +228,12 @@ class Connection {
146
228
  * @returns {request.superagent} Promise from superagent's post request
147
229
  */
148
230
  async postRaw (path, data, queryParams) {
149
- return this._post(path)
150
- .query(queryParams)
151
- .send(data);
231
+ return this._post(path).query(queryParams).send(data);
152
232
  }
153
233
 
154
234
  _post (path) {
155
- return utils.superagent.post(this.endpoint + path)
235
+ return utils.superagent
236
+ .post(this.endpoint + path)
156
237
  .set('Authorization', this.token)
157
238
  .set('accept', 'json');
158
239
  }
@@ -178,7 +259,8 @@ class Connection {
178
259
  */
179
260
  getRaw (path, queryParams) {
180
261
  path = path || '';
181
- return utils.superagent.get(this.endpoint + path)
262
+ return utils.superagent
263
+ .get(this.endpoint + path)
182
264
  .set('Authorization', this.token)
183
265
  .set('accept', 'json')
184
266
  .query(queryParams);
@@ -189,12 +271,11 @@ class Connection {
189
271
  * https://api.pryv.com/reference/#add-hf-series-data-points
190
272
  */
191
273
  async addPointsToHFEvent (eventId, fields, points) {
192
- const res = await this.post('events/' + eventId + '/series',
193
- {
194
- format: 'flatJSON',
195
- fields: fields,
196
- points: points
197
- });
274
+ const res = await this.post('events/' + eventId + '/series', {
275
+ format: 'flatJSON',
276
+ fields: fields,
277
+ points: points
278
+ });
198
279
  if (!res.status === 'ok') {
199
280
  throw new Error('Failed loading serie: ' + JSON.stringify(res.status));
200
281
  }
@@ -212,14 +293,22 @@ class Connection {
212
293
  async getEventsStreamed (queryParams, forEachEvent) {
213
294
  const myParser = jsonParser(forEachEvent, queryParams.includeDeletions);
214
295
  let res = null;
215
- if (typeof window === 'undefined') { // node
296
+ if (typeof window === 'undefined') {
297
+ // node
216
298
  res = await this.getRaw('events', queryParams)
217
299
  .buffer(false)
218
300
  .parse(myParser);
219
- } else if (typeof fetch !== 'undefined' && !(typeof navigator !== 'undefined' && navigator.product === 'ReactNative')) { // browser supports fetch and it is not react native
301
+ } else if (
302
+ typeof fetch !== 'undefined' &&
303
+ !(typeof navigator !== 'undefined' && navigator.product === 'ReactNative')
304
+ ) {
305
+ // browser supports fetch and it is not react native
220
306
  res = await browserGetEventStreamed(this, queryParams, myParser);
221
- } else { // browser no fetch supports
222
- console.log('WARNING: Browser does not support fetch() required by pryv.Connection.getEventsStreamed()');
307
+ } else {
308
+ // browser no fetch supports
309
+ console.log(
310
+ 'WARNING: Browser does not support fetch() required by pryv.Connection.getEventsStreamed()'
311
+ );
223
312
  res = await this.getRaw('events', queryParams);
224
313
  res.body.eventsCount = 0;
225
314
  if (res.body.events) {
@@ -227,7 +316,8 @@ class Connection {
227
316
  res.body.eventsCount += res.body.events.length;
228
317
  delete res.body.events;
229
318
  }
230
- if (res.body.eventDeletions) { // deletions are in a seprated Array
319
+ if (res.body.eventDeletions) {
320
+ // deletions are in a seprated Array
231
321
  res.body.eventDeletions.forEach(forEachEvent);
232
322
  res.body.eventsCount += res.body.eventDeletions.length;
233
323
  delete res.body.eventDeletions;
@@ -262,7 +352,8 @@ class Connection {
262
352
  * @param {string} fileName
263
353
  */
264
354
  async createEventWithFileFromBuffer (event, bufferData, filename) {
265
- if (typeof window === 'undefined') { // node
355
+ if (typeof window === 'undefined') {
356
+ // node
266
357
  const res = await this._post('events')
267
358
  .field('event', JSON.stringify(event))
268
359
  .attach('file', bufferData, filename);
@@ -280,11 +371,11 @@ class Connection {
280
371
  }
281
372
 
282
373
  /**
283
- * Create an event with attached formData
284
- * !! BROWSER ONLY
285
- * @param {Event} event
286
- * @param {FormData} formData https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData
287
- */
374
+ * Create an event with attached formData
375
+ * !! BROWSER ONLY
376
+ * @param {Event} event
377
+ * @param {FormData} formData https://developer.mozilla.org/en-US/docs/Web/API/FormData/FormData
378
+ */
288
379
  async createEventWithFormData (event, formData) {
289
380
  formData.append('event', JSON.stringify(event));
290
381
  const res = await this._post('events').send(formData);
@@ -313,10 +404,14 @@ class Connection {
313
404
  // private method that handle meta data parsing
314
405
  _handleMeta (res, requestLocalTimestamp) {
315
406
  if (!res.meta) throw new Error('Cannot find .meta in response.');
316
- if (!res.meta.serverTime) throw new Error('Cannot find .meta.serverTime in response.');
407
+ if (!res.meta.serverTime) { throw new Error('Cannot find .meta.serverTime in response.'); }
317
408
 
318
409
  // update deltaTime and weight it
319
- this._deltaTime.value = (this._deltaTime.value * this._deltaTime.weight + res.meta.serverTime - requestLocalTimestamp) / ++this._deltaTime.weight;
410
+ this._deltaTime.value =
411
+ (this._deltaTime.value * this._deltaTime.weight +
412
+ res.meta.serverTime -
413
+ requestLocalTimestamp) /
414
+ ++this._deltaTime.weight;
320
415
  }
321
416
  }
322
417
 
package/src/index.d.ts CHANGED
@@ -17,7 +17,7 @@ declare module 'pryv' {
17
17
  name: string;
18
18
  parentId?: Identifier;
19
19
  clientData?: KeyValue;
20
- children: Identifier[];
20
+ children: Stream[];
21
21
  trashed?: boolean;
22
22
  created: Timestamp;
23
23
  createdBy: Identifier;
@@ -575,8 +575,17 @@ declare module 'pryv' {
575
575
  username(): Promise<string>;
576
576
  api<Calls extends APICall[] = APICall[]>(
577
577
  apiCalls: Calls,
578
- res?: APICallProgressHandler[],
578
+ progress?: APICallProgressHandler,
579
579
  ): Promise<Array<TypedAPICallResult>>;
580
+ apiOne<T extends keyof APICallMethods>(
581
+ method: T,
582
+ params: APICallMethods[T]['params'],
583
+ ): Promise<APICallMethods[T]['res']>;
584
+ apiOne<T extends keyof APICallMethods, U extends keyof APICallMethods[T]['res']>(
585
+ method: T,
586
+ params: APICallMethods[T]['params'],
587
+ expectedKey: U
588
+ ): Promise<APICallMethods[T]['res'][U]>;
580
589
  getEventsStreamed(
581
590
  queryParams: Partial<EventQueryParamsStreamQuery>,
582
591
  forEachEvent: StreamedEventsHandler,
@@ -598,8 +607,11 @@ declare module 'pryv' {
598
607
  id: Identifier,
599
608
  fields: string[],
600
609
  values: Array<string | number>,
601
- ): Promise<void>;
610
+ ): Promise<any>;
602
611
  accessInfo(): Promise<AccessInfo>;
612
+ revoke(throwOnFail?: boolean, usingConnection?: Connection)
613
+ readonly deltaTime: number;
614
+ readonly apiEndpoint: string;
603
615
 
604
616
  post(
605
617
  path: string,
@@ -650,14 +662,27 @@ declare module 'pryv' {
650
662
  [key: string]: any;
651
663
  };
652
664
 
665
+ export class ServiceAssets {
666
+ static setup(pryvServiceAssetsSourceUrl: string): Promise<ServiceAssets>;
667
+ get(keyPath?: string): any;
668
+ getUrl(keyPath?: string): string;
669
+ relativeURL(url: string): string;
670
+ setAllDefaults(): Promise<void>;
671
+ setFavicon(): void;
672
+ loadCSS(): Promise<void>;
673
+ loginButtonLoadCSS(): Promise<void>;
674
+ loginButtonGetHTML(): Promise<string>;
675
+ loginButtonGetMessages(): Promise<KeyValue>;
676
+ }
677
+
653
678
  export class Service {
654
679
  constructor (
655
680
  serviceInfoUrl: string,
656
681
  serviceCustomizations?: serviceCustomizations,
657
682
  );
658
683
  info(forceFetch?: boolean): Promise<ServiceInfo>;
659
- setServiceInfo(serviceInfo: Partial<ServiceInfo>): Promise<void>;
660
- assets(forceFetch?: boolean): Promise<AssetsConfig>;
684
+ setServiceInfo(serviceInfo: Partial<ServiceInfo>): void;
685
+ assets(forceFetch?: boolean): Promise<ServiceAssets | null>;
661
686
  infoSync(): ServiceInfo | null;
662
687
  apiEndpointFor(username: string, token: string): Promise<string>;
663
688
  login(
@@ -666,6 +691,9 @@ declare module 'pryv' {
666
691
  appId: string,
667
692
  originHeader?: string,
668
693
  ): Promise<Connection>;
694
+
695
+ supportsHF(): Promise<boolean>;
696
+ isDnsLess(): Promise<boolean>;
669
697
  }
670
698
 
671
699
  export type AuthRequestedPermission = {
@@ -755,12 +783,13 @@ declare module 'pryv' {
755
783
  };
756
784
 
757
785
  export type CustomLoginButton = {
758
- init?: () => Promise<void>;
759
- getAuthorizationData(): string;
786
+ init?: () => Promise<Service>;
787
+ getAuthorizationData(): any;
760
788
  onStateChange(state: AuthStatePayload): Promise<void>;
761
789
  onClick(): void;
762
- saveAuthorizationData?: (authData: string) => void;
790
+ saveAuthorizationData?: (authData: any) => void;
763
791
  deleteAuthorizationData?: () => Promise<void>;
792
+ finishAuthProcessAfterRedirection?: (authController: AuthController) => Promise<void>;
764
793
  }
765
794
 
766
795
  export class AuthController {
@@ -769,16 +798,15 @@ declare module 'pryv' {
769
798
  service: Service,
770
799
  loginButton: CustomLoginButton,
771
800
  );
772
- init(): Promise<void>;
801
+ init(): Promise<Service>;
773
802
  stopAuthRequest(msg: string): void;
774
803
  handleClick(): Promise<void>;
775
804
  getReturnURL(
776
805
  returnURL: string,
777
- windowLocationForTest: string,
778
- navigatorForTests: string,
806
+ windowLocationForTest?: string,
807
+ navigatorForTests?: string,
779
808
  ): string | boolean;
780
809
  startAuthRequest(): Promise<any>;
781
- doPolling(): Promise<void>;
782
810
  set state(newState: AuthStatePayload);
783
811
  get state(): AuthStatePayload;
784
812
  }
@@ -805,7 +833,7 @@ declare module 'pryv' {
805
833
 
806
834
  export type TokenAndAPIEndpoint = {
807
835
  endpoint: string;
808
- token: string;
836
+ token: string | null;
809
837
  };
810
838
 
811
839
  export const utils: {
@@ -820,6 +848,32 @@ declare module 'pryv' {
820
848
  type version = string;
821
849
 
822
850
  let pryv: {
851
+ Service: typeof Service;
852
+ Connection: typeof Connection;
853
+ Auth: {
854
+ setupAuth: SetupAuth;
855
+ AuthStates: AuthStates;
856
+ AuthController: typeof AuthController;
857
+ };
858
+ Browser: {
859
+ LoginButton: CustomLoginButton;
860
+ CookieUtils: {
861
+ set(cookieKey: string, value: any, expireInDays: number): void;
862
+ get(cookieKey: string): any;
863
+ del(cookieKey: string): void;
864
+ };
865
+ AuthStates: AuthStates;
866
+ setupAuth: SetupAuth;
867
+ serviceInfoFromUrl: getServiceInfoFromURL;
868
+ };
869
+ utils: {
870
+ isBrowser(): boolean;
871
+ extractTokenAndAPIEndpoint(apiEndpoint: string): TokenAndAPIEndpoint;
872
+ buildAPIEndpoint(tokenAndAPI: TokenAndAPIEndpoint): string;
873
+ browserIsMobileOrTablet(navigator: string): boolean;
874
+ cleanURLFromPrYvParams(url: string): string;
875
+ getQueryParamsFromURL(url: string): KeyValue;
876
+ };
823
877
  version: version;
824
878
  };
825
879
 
@@ -89,6 +89,18 @@ describe('Connection', () => {
89
89
  });
90
90
  });
91
91
 
92
+ describe('.apiOne()', function () {
93
+ this.timeout(15000);
94
+ it('.apiOne("events.get")', async () => {
95
+ const res = await conn.apiOne('events.get');
96
+ expect(res.events).to.exist;
97
+ });
98
+ it('.apiOne("events.get")', async () => {
99
+ const res = await conn.apiOne('events.get', {}, 'events');
100
+ expect(Array.isArray(res)).to.equal(true);
101
+ });
102
+ });
103
+
92
104
  describe('.api()', function () {
93
105
  this.timeout(15000);
94
106
  it('.api() events.get', async () => {