pryv 2.1.6 → 2.2.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/LICENSE.md +1 -1
- package/README.md +70 -23
- package/package.json +12 -12
- package/src/Connection.js +17 -0
- package/src/index.d.ts +845 -0
- package/test/Connection.test.js +73 -29
- package/test/test-data.js +4 -1
- package/webpack.config.js +16 -4
package/LICENSE.md
CHANGED
package/README.md
CHANGED
|
@@ -7,11 +7,19 @@ This JavaScript library is meant to facilitate writing NodeJS and browser apps f
|
|
|
7
7
|
*Prerequisites*: Node 12
|
|
8
8
|
|
|
9
9
|
- Setup: `npm run setup`
|
|
10
|
+
|
|
10
11
|
- Build pryv.js library for browsers: `npm run build`, the result is published in `./dist`
|
|
12
|
+
|
|
11
13
|
- Build documentation: `npm run doc`, the result is published in `./dist/docs`
|
|
14
|
+
|
|
15
|
+
Note: as per v2.1.7 `jsdoc` dev dependency has been removed from package.json .. it should be installed with `npm install jsoc --dev`
|
|
16
|
+
|
|
12
17
|
- Node Tests: `npm run test`
|
|
18
|
+
|
|
13
19
|
- Coverage: `npm run cover`, the result is visible in `./coverage`
|
|
20
|
+
|
|
14
21
|
- Browser tests: **build**, then `npm run webserver` and open [https://l.rec.la:9443/tests/browser-tests.html?pryvServiceInfoUrl=https://zouzou.com/service/info](https://l.rec.la:9443/tests/browser-tests.html?pryvServiceInfoUrl=https://zouzou.com/service/info)
|
|
22
|
+
|
|
15
23
|
- Update on CDN: After running **setup** and **build** scripts, run `npm run gh-pages ${COMMIT_MESSAGE}`. If this fails, run `npm run clear` to rebuild a fresh `dist/` folder
|
|
16
24
|
|
|
17
25
|
## Usage
|
|
@@ -59,10 +67,10 @@ This JavaScript library is meant to facilitate writing NodeJS and browser apps f
|
|
|
59
67
|
|
|
60
68
|
#### Others distributions for browsers & extensions:
|
|
61
69
|
|
|
62
|
-
- ES6: `https://api.pryv.com/lib-js/pryv-es6.js`
|
|
70
|
+
- ES6: `https://api.pryv.com/lib-js/pryv-es6.js`
|
|
63
71
|
- Bundle: (Socket.io + Monitor + Lib-js) `https://api.pryv.com/lib-js/pryv-socket.io-monitor.js`.
|
|
64
|
-
This library can be extended with two packages:
|
|
65
|
-
- Socket.io extension: [https://github.com/pryv/lib-js-socket.io](https://github.com/pryv/lib-js-socket.io)
|
|
72
|
+
This library can be extended with two packages:
|
|
73
|
+
- Socket.io extension: [https://github.com/pryv/lib-js-socket.io](https://github.com/pryv/lib-js-socket.io)
|
|
66
74
|
- Monitor extension: [https://github.com/pryv/lib-js-monitor](https://github.com/pryv/lib-js-monitor)
|
|
67
75
|
|
|
68
76
|
#### Example on code pen:
|
|
@@ -71,7 +79,7 @@ This JavaScript library is meant to facilitate writing NodeJS and browser apps f
|
|
|
71
79
|
|
|
72
80
|
#### Node.js
|
|
73
81
|
|
|
74
|
-
Install with: `npm install pryv --save `
|
|
82
|
+
Install with: `npm install pryv --save `
|
|
75
83
|
|
|
76
84
|
```javascript
|
|
77
85
|
const Pryv = require('pryv');
|
|
@@ -100,7 +108,7 @@ const connection = new Pryv.Connection(apiEndpoint);
|
|
|
100
108
|
|
|
101
109
|
#### Within a WebPage with a login button
|
|
102
110
|
|
|
103
|
-
The following code is an implementation of the [Pryv.io Authentication process](https://api.pryv.com/reference/#authenticate-your-app).
|
|
111
|
+
The following code is an implementation of the [Pryv.io Authentication process](https://api.pryv.com/reference/#authenticate-your-app).
|
|
104
112
|
|
|
105
113
|
```html
|
|
106
114
|
<!doctype html>
|
|
@@ -135,7 +143,7 @@ The following code is an implementation of the [Pryv.io Authentication process](
|
|
|
135
143
|
// referer: 'my test with lib-js', // optional string to track registration source
|
|
136
144
|
}
|
|
137
145
|
};
|
|
138
|
-
|
|
146
|
+
|
|
139
147
|
function pryvAuthStateChange(state) { // called each time the authentication state changed
|
|
140
148
|
console.log('##pryvAuthStateChange', state);
|
|
141
149
|
if (state.id === Pryv.Auth.AuthStates.AUTHORIZED) {
|
|
@@ -266,7 +274,7 @@ try {
|
|
|
266
274
|
#### result:
|
|
267
275
|
|
|
268
276
|
```javascript
|
|
269
|
-
{
|
|
277
|
+
{
|
|
270
278
|
eventsCount: 10000,
|
|
271
279
|
meta:
|
|
272
280
|
{
|
|
@@ -298,7 +306,7 @@ try {
|
|
|
298
306
|
#### result:
|
|
299
307
|
|
|
300
308
|
```javascript
|
|
301
|
-
{
|
|
309
|
+
{
|
|
302
310
|
eventDeletionsCount: 150,
|
|
303
311
|
eventsCount: 10000,
|
|
304
312
|
meta:
|
|
@@ -331,6 +339,22 @@ const result = await connection.createEventWithFile(
|
|
|
331
339
|
);
|
|
332
340
|
```
|
|
333
341
|
|
|
342
|
+
or from a Buffer
|
|
343
|
+
|
|
344
|
+
```javascript
|
|
345
|
+
const filePath = './test/my_image.png';
|
|
346
|
+
const bufferData = fs.readFileSync(filePath);
|
|
347
|
+
|
|
348
|
+
const result = await connection.createEventWithFileFromBuffer(
|
|
349
|
+
{
|
|
350
|
+
type: 'picture/attached',
|
|
351
|
+
streamId: 'data'
|
|
352
|
+
},
|
|
353
|
+
bufferData,
|
|
354
|
+
'my_image.png' // filename
|
|
355
|
+
);
|
|
356
|
+
```
|
|
357
|
+
|
|
334
358
|
#### Browser
|
|
335
359
|
|
|
336
360
|
From an Input field
|
|
@@ -344,7 +368,7 @@ From an Input field
|
|
|
344
368
|
'file0',
|
|
345
369
|
document.getElementById('create-file').files[0]
|
|
346
370
|
) ;
|
|
347
|
-
|
|
371
|
+
|
|
348
372
|
connection.createEventWithFormData(
|
|
349
373
|
{
|
|
350
374
|
type: 'file/attached',
|
|
@@ -378,9 +402,24 @@ connect.createEventWithFormData(
|
|
|
378
402
|
// handle result here
|
|
379
403
|
}
|
|
380
404
|
);
|
|
405
|
+
|
|
406
|
+
// -- alternative with a filename
|
|
407
|
+
|
|
408
|
+
connect.createEventWithFileFromBuffer(
|
|
409
|
+
{
|
|
410
|
+
type: 'file/attached',
|
|
411
|
+
streamId: 'data'
|
|
412
|
+
},
|
|
413
|
+
blob, 'filename.txt') // here we can directly use the blob
|
|
414
|
+
.then(function (res, err) {
|
|
415
|
+
// handle result here
|
|
416
|
+
}
|
|
417
|
+
);
|
|
418
|
+
|
|
419
|
+
|
|
381
420
|
```
|
|
382
421
|
|
|
383
|
-
### High Frequency Events
|
|
422
|
+
### High Frequency Events
|
|
384
423
|
|
|
385
424
|
Reference: [https://api.pryv.com/reference/#hf-events](https://api.pryv.com/reference/#hf-events)
|
|
386
425
|
|
|
@@ -436,9 +475,9 @@ A Pryv.io deployment is a unique "Service", as an example **Pryv Lab** is a serv
|
|
|
436
475
|
|
|
437
476
|
It relies on the content of a **service information** configuration, See: [Service Information API reference](https://api.pryv.com/reference/#service-info)
|
|
438
477
|
|
|
439
|
-
#### Pryv.Service
|
|
478
|
+
#### Pryv.Service
|
|
440
479
|
|
|
441
|
-
Exposes tools to interact with Pryv.io at a "Platform" level.
|
|
480
|
+
Exposes tools to interact with Pryv.io at a "Platform" level.
|
|
442
481
|
|
|
443
482
|
##### Initizalization with a service info URL
|
|
444
483
|
|
|
@@ -453,7 +492,7 @@ Service information properties can be overriden with specific values. This might
|
|
|
453
492
|
```javascript
|
|
454
493
|
const serviceInfoUrl = 'https://reg.pryv.me/service/info';
|
|
455
494
|
const serviceCustomizations = {
|
|
456
|
-
name: 'Pryv Lab 2',
|
|
495
|
+
name: 'Pryv Lab 2',
|
|
457
496
|
assets: {
|
|
458
497
|
definitions: 'https://pryv.github.io/assets-pryv.me/index.json'
|
|
459
498
|
}
|
|
@@ -465,7 +504,7 @@ const service = new Pryv.Service(serviceInfoUrl, serviceCustomizations);
|
|
|
465
504
|
|
|
466
505
|
See: [Pryv.Service](https://pryv.github.io/js-lib/docs/Pryv.Service.html) for more details
|
|
467
506
|
|
|
468
|
-
- `service.info()` - returns the content of the serviceInfo in a Promise
|
|
507
|
+
- `service.info()` - returns the content of the serviceInfo in a Promise
|
|
469
508
|
|
|
470
509
|
```javascript
|
|
471
510
|
// example: get the name of the platform
|
|
@@ -480,7 +519,7 @@ See: [Pryv.Service](https://pryv.github.io/js-lib/docs/Pryv.Service.html) for mo
|
|
|
480
519
|
|
|
481
520
|
#### Pryv.Browser - retrieve serviceInfo from query URL
|
|
482
521
|
|
|
483
|
-
A single Web App might need to be run on different Pryv.io platforms. This is the case of most Pryv.io demonstrators.
|
|
522
|
+
A single Web App might need to be run on different Pryv.io platforms. This is the case of most Pryv.io demonstrators.
|
|
484
523
|
|
|
485
524
|
The corresponding Pryv.io platform can be specified by providing the Service Information URL as query parameter `pryvServiceInfoUrl` as per the [Pryv App Guidelines](https://api.pryv.com/guides/app-guidelines/). It can be extracted using `Pryv.Browser.serviceInfoFromUrl()` .
|
|
486
525
|
|
|
@@ -488,7 +527,7 @@ Example of usage for web App with the url https://api.pryv.com/app-web-access/?p
|
|
|
488
527
|
|
|
489
528
|
```javascript
|
|
490
529
|
let defaultServiceInfoUrl = 'https://reg.pryv.me/service/info';
|
|
491
|
-
// if present override serviceInfoURL from URL query param "?pryvServiceInfoUrl=.."
|
|
530
|
+
// if present override serviceInfoURL from URL query param "?pryvServiceInfoUrl=.."
|
|
492
531
|
serviceInfoUrl = Pryv.Browser.serviceInfoFromUrl() || defaultServiceInfoUrl;
|
|
493
532
|
|
|
494
533
|
(async function () {
|
|
@@ -539,7 +578,7 @@ async init () {
|
|
|
539
578
|
|
|
540
579
|
// set cookie key for authorization data - browser only
|
|
541
580
|
this._cookieKey = 'pryv-libjs-' + this.authSettings.authRequest.requestingAppId;
|
|
542
|
-
|
|
581
|
+
|
|
543
582
|
// initialize controller
|
|
544
583
|
this.auth = new AuthController(this.authSettings, this.service, this);
|
|
545
584
|
await this.auth.init();
|
|
@@ -661,8 +700,8 @@ For a more advanced scenario, you can check the default button implementation at
|
|
|
661
700
|
|
|
662
701
|
#### Redirect user to the authentication page
|
|
663
702
|
|
|
664
|
-
There is a possibility that you would like to register the user in another page. You can check the [`./web-demos/auth-with-redirection.html`](./web-demos/auth-with-redirection.html) example.
|
|
665
|
-
Also you can try the same code in [https://api.pryv.com/lib-js/demos/auth-with-redirection.html](https://api.pryv.com/lib-js/demos/auth-with-redirection.html).
|
|
703
|
+
There is a possibility that you would like to register the user in another page. You can check the [`./web-demos/auth-with-redirection.html`](./web-demos/auth-with-redirection.html) example.
|
|
704
|
+
Also you can try the same code in [https://api.pryv.com/lib-js/demos/auth-with-redirection.html](https://api.pryv.com/lib-js/demos/auth-with-redirection.html).
|
|
666
705
|
Here is the explanation how to [launch web-demos locally](#launch-web-demos-locally)
|
|
667
706
|
|
|
668
707
|
### Launch web demos locally
|
|
@@ -674,22 +713,30 @@ You can find html examples in the [`./web-demos`](/web-demos) directory. You can
|
|
|
674
713
|
```bash
|
|
675
714
|
npm run webserver
|
|
676
715
|
```
|
|
677
|
-
|
|
716
|
+
|
|
678
717
|
and open an example with the following URL **https://l.rec.la:9443/demos/EXAMPLE_NAME.html**, like: [https://l.rec.la:9443/demos/auth.html](https://l.rec.la:9443/demos/auth.html)
|
|
679
718
|
|
|
680
719
|
2. as a simple html file (service information must be passed as JSON to avoid CORS problem).
|
|
681
720
|
|
|
682
721
|
# Change Log
|
|
683
722
|
|
|
723
|
+
## 2.2.0
|
|
724
|
+
|
|
725
|
+
- Added TypeScript typings – contribution from @ovesco
|
|
726
|
+
|
|
727
|
+
## 2.1.7
|
|
728
|
+
|
|
729
|
+
- Removed JSDOC dev dependency for security reason
|
|
730
|
+
|
|
684
731
|
## 2.1.0
|
|
685
732
|
|
|
686
733
|
- UI separated from the Authentication logic
|
|
687
734
|
- Extendable UI feature was added
|
|
688
735
|
|
|
689
|
-
## 2.0.3
|
|
736
|
+
## 2.0.3
|
|
690
737
|
|
|
691
|
-
- Added Connection.username()
|
|
738
|
+
- Added Connection.username()
|
|
692
739
|
- Various dependencies upgrades
|
|
693
740
|
- Fixing Origin header in Browser distribution
|
|
694
741
|
|
|
695
|
-
## 2.0.1 Initial Release
|
|
742
|
+
## 2.0.1 Initial Release
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pryv",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"homepage": "https://github.com/pryv/lib-js",
|
|
5
5
|
"description": "Pryv Javascript Library",
|
|
6
6
|
"keywords": [
|
|
@@ -17,11 +17,12 @@
|
|
|
17
17
|
"name": "Pryv S.A."
|
|
18
18
|
},
|
|
19
19
|
"main": "src/index.js",
|
|
20
|
+
"types": "src/index.d.ts",
|
|
20
21
|
"license": "BSD-3-Clause",
|
|
21
22
|
"scripts": {
|
|
22
23
|
"setup": "./scripts/setup-environment-dev.sh",
|
|
23
24
|
"build": "webpack --config webpack.config.js",
|
|
24
|
-
"doc": "
|
|
25
|
+
"doc": "npx jsdoc -c .jsdoc-conf.json",
|
|
25
26
|
"test": "mocha --reporter spec test/**/*.test.js --timeout 3000",
|
|
26
27
|
"test-debug": "mocha --inpect-brk=40000 --reporter spec test/**/*.test.js ",
|
|
27
28
|
"test:browser": "npm run build; ",
|
|
@@ -38,20 +39,19 @@
|
|
|
38
39
|
}
|
|
39
40
|
],
|
|
40
41
|
"dependencies": {
|
|
41
|
-
"superagent": "^
|
|
42
|
+
"superagent": "^7.0.2"
|
|
42
43
|
},
|
|
43
44
|
"devDependencies": {
|
|
44
|
-
"@pryv/lib-js-common": "
|
|
45
|
-
"@pryv/monitor": "^1.0.
|
|
46
|
-
"@pryv/socket.io": "^1.0.
|
|
47
|
-
"chai": "^4.
|
|
45
|
+
"@pryv/lib-js-common": "github:pryv/lib-js-common#1.0.6",
|
|
46
|
+
"@pryv/monitor": "^1.0.6",
|
|
47
|
+
"@pryv/socket.io": "^1.0.6",
|
|
48
|
+
"chai": "^4.3.4",
|
|
48
49
|
"chai-as-promised": "^7.1.1",
|
|
49
50
|
"cuid": "^2.1.8",
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
"
|
|
54
|
-
"rec-la": "latest",
|
|
51
|
+
"mocha": "^9.1.3",
|
|
52
|
+
"node-fetch": "^2.6.1",
|
|
53
|
+
"nyc": "^15.1.0",
|
|
54
|
+
"rec.la": "latest",
|
|
55
55
|
"universal-url": "^2.0.0",
|
|
56
56
|
"zombie": "^6.1.4"
|
|
57
57
|
}
|
package/src/Connection.js
CHANGED
|
@@ -257,6 +257,23 @@ class Connection {
|
|
|
257
257
|
return res.body
|
|
258
258
|
}
|
|
259
259
|
|
|
260
|
+
/**
|
|
261
|
+
* Create an event from a Buffer
|
|
262
|
+
* NODE.jS ONLY
|
|
263
|
+
* @param {Event} event
|
|
264
|
+
* @param {Buffer} bufferData
|
|
265
|
+
* @param {string} fileName
|
|
266
|
+
*/
|
|
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
|
|
275
|
+
}
|
|
276
|
+
|
|
260
277
|
/**
|
|
261
278
|
* Create an event with attached formData
|
|
262
279
|
* !! BROWSER ONLY
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,845 @@
|
|
|
1
|
+
declare module 'pryv' {
|
|
2
|
+
type Timestamp = number;
|
|
3
|
+
type Identifier = string;
|
|
4
|
+
type Level = 'read' | 'contribute' | 'manage' | 'create-only';
|
|
5
|
+
type KeyValue = { [key: string]: string | number };
|
|
6
|
+
|
|
7
|
+
type Attachment = {
|
|
8
|
+
id: Identifier;
|
|
9
|
+
fileName: string;
|
|
10
|
+
type: string;
|
|
11
|
+
size: number;
|
|
12
|
+
readToken: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
type Stream = {
|
|
16
|
+
id: Identifier;
|
|
17
|
+
name: string;
|
|
18
|
+
parentId?: Identifier;
|
|
19
|
+
clientData?: KeyValue;
|
|
20
|
+
children: Identifier[];
|
|
21
|
+
trashed?: boolean;
|
|
22
|
+
created: Timestamp;
|
|
23
|
+
createdBy: Identifier;
|
|
24
|
+
modified: Timestamp;
|
|
25
|
+
modifiedBy: Identifier;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
type Event = {
|
|
29
|
+
id: Identifier;
|
|
30
|
+
streamIds: Identifier[];
|
|
31
|
+
streamId: Identifier;
|
|
32
|
+
time: Timestamp;
|
|
33
|
+
duration?: Timestamp;
|
|
34
|
+
type: string;
|
|
35
|
+
content?: any;
|
|
36
|
+
tags?: string[];
|
|
37
|
+
description?: string;
|
|
38
|
+
attachments?: Attachment[];
|
|
39
|
+
clientData?: KeyValue;
|
|
40
|
+
trashed?: boolean;
|
|
41
|
+
created: Timestamp;
|
|
42
|
+
createdBy: Identifier;
|
|
43
|
+
modified: Timestamp;
|
|
44
|
+
modifiedBy: Identifier;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
type Permission = {
|
|
48
|
+
streamId: Identifier;
|
|
49
|
+
level: Level;
|
|
50
|
+
feature?: 'selfRevoke';
|
|
51
|
+
setting?: 'forbidden';
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
type Access = {
|
|
55
|
+
id: Identifier;
|
|
56
|
+
token: string;
|
|
57
|
+
type?: 'personal' | 'app' | 'shared';
|
|
58
|
+
name: string;
|
|
59
|
+
deviceName?: string;
|
|
60
|
+
permissions: Permission[];
|
|
61
|
+
lastUsed?: Timestamp;
|
|
62
|
+
expireAfter?: number;
|
|
63
|
+
expires?: Timestamp;
|
|
64
|
+
deleted?: Timestamp;
|
|
65
|
+
clientData?: KeyValue;
|
|
66
|
+
created: Timestamp;
|
|
67
|
+
createdBy: Identifier;
|
|
68
|
+
modified: Timestamp;
|
|
69
|
+
modifiedBy: Identifier;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
type FollowedSlice = {
|
|
73
|
+
id: Identifier;
|
|
74
|
+
name: string;
|
|
75
|
+
url: string;
|
|
76
|
+
accessToken: string;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
type AccountInformation = {
|
|
80
|
+
username: string;
|
|
81
|
+
email: string;
|
|
82
|
+
language: string;
|
|
83
|
+
storageUsed: {
|
|
84
|
+
dbDocuments: number;
|
|
85
|
+
attachedFiles: number;
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// HTTP only
|
|
90
|
+
type AuditLog = {
|
|
91
|
+
id: Identifier;
|
|
92
|
+
type: string;
|
|
93
|
+
time: Timestamp;
|
|
94
|
+
forwardedFor: string;
|
|
95
|
+
action: string;
|
|
96
|
+
query: string;
|
|
97
|
+
accessId: string;
|
|
98
|
+
status: number;
|
|
99
|
+
errorMessage?: string;
|
|
100
|
+
errorId?: string;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
type HFSeries = {
|
|
104
|
+
format: 'flatJSON';
|
|
105
|
+
fields: string[];
|
|
106
|
+
points: Array<number | string>;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
type Run = {
|
|
110
|
+
status: number;
|
|
111
|
+
timestamp: Timestamp;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
type WebHook = {
|
|
115
|
+
id: Identifier;
|
|
116
|
+
accessId: Identifier;
|
|
117
|
+
url: string;
|
|
118
|
+
minIntervalMs: number;
|
|
119
|
+
maxRetries: number;
|
|
120
|
+
currentRetries: number;
|
|
121
|
+
state: 'active' | 'inactive';
|
|
122
|
+
runCount: number;
|
|
123
|
+
failCount: number;
|
|
124
|
+
lastRun: Run;
|
|
125
|
+
runs: Run[];
|
|
126
|
+
created: Timestamp;
|
|
127
|
+
createdBy: Identifier;
|
|
128
|
+
modified: Timestamp;
|
|
129
|
+
modifiedBy: Identifier;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
type ItemDeletion = {
|
|
133
|
+
id: Identifier;
|
|
134
|
+
deleted?: Timestamp;
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
type Error = {
|
|
138
|
+
id: string;
|
|
139
|
+
message: string;
|
|
140
|
+
data?: any;
|
|
141
|
+
subErrors?: Error[];
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
type StreamsQuery = {
|
|
145
|
+
any?: Identifier[];
|
|
146
|
+
all?: Identifier[];
|
|
147
|
+
not?: Identifier[];
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
type EventQueryParams = {
|
|
151
|
+
fromTime: Timestamp;
|
|
152
|
+
toTime: Timestamp;
|
|
153
|
+
streams: string[];
|
|
154
|
+
tags: string[];
|
|
155
|
+
types: string[];
|
|
156
|
+
running: boolean;
|
|
157
|
+
sortAscending: boolean;
|
|
158
|
+
skip: number;
|
|
159
|
+
limit: number;
|
|
160
|
+
state: 'default' | 'trashed' | 'all';
|
|
161
|
+
modifiedSince: Timestamp;
|
|
162
|
+
includeDeletion: boolean;
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
type EventQueryParamsStreamQuery = Omit<EventQueryParams, 'streams'> & {
|
|
166
|
+
streams: string[] | StreamsQuery;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
type EditMetadata = 'created' | 'createdBy' | 'modified' | 'modifiedBy';
|
|
170
|
+
|
|
171
|
+
export type ApiCallMethods = {
|
|
172
|
+
// mfa
|
|
173
|
+
'mfa.challenge': {
|
|
174
|
+
params: null;
|
|
175
|
+
res: {
|
|
176
|
+
message: string;
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
'mfa.recover': {
|
|
180
|
+
params: {
|
|
181
|
+
recoveryCode: string;
|
|
182
|
+
username: string;
|
|
183
|
+
password: string;
|
|
184
|
+
appId: string;
|
|
185
|
+
};
|
|
186
|
+
res: {
|
|
187
|
+
message: string;
|
|
188
|
+
};
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
// events
|
|
192
|
+
'events.get': {
|
|
193
|
+
params: Partial<EventQueryParamsStreamQuery>;
|
|
194
|
+
res: {
|
|
195
|
+
eventDeletions?: ItemDeletion[];
|
|
196
|
+
events: Event[];
|
|
197
|
+
};
|
|
198
|
+
};
|
|
199
|
+
'events.getOne': {
|
|
200
|
+
params: {
|
|
201
|
+
id: Identifier;
|
|
202
|
+
includeHistory?: boolean;
|
|
203
|
+
};
|
|
204
|
+
res: {
|
|
205
|
+
event: Event;
|
|
206
|
+
history?: Event[];
|
|
207
|
+
};
|
|
208
|
+
};
|
|
209
|
+
'events.create': {
|
|
210
|
+
params: Partial<Omit<Event, 'attachments' | EditMetadata>>;
|
|
211
|
+
res: {
|
|
212
|
+
event: Event;
|
|
213
|
+
};
|
|
214
|
+
};
|
|
215
|
+
'events.update': {
|
|
216
|
+
params: {
|
|
217
|
+
id: Identifier;
|
|
218
|
+
update: Partial<Omit<Event, 'id' | 'attachments' | EditMetadata>>;
|
|
219
|
+
};
|
|
220
|
+
res: {
|
|
221
|
+
event: Event;
|
|
222
|
+
};
|
|
223
|
+
};
|
|
224
|
+
'events.deleteAttachment': {
|
|
225
|
+
params: {
|
|
226
|
+
id: Identifier;
|
|
227
|
+
fileId: Identifier;
|
|
228
|
+
};
|
|
229
|
+
res: {
|
|
230
|
+
event: Event;
|
|
231
|
+
};
|
|
232
|
+
};
|
|
233
|
+
'events.delete': {
|
|
234
|
+
params: {
|
|
235
|
+
id: Identifier;
|
|
236
|
+
};
|
|
237
|
+
res: {
|
|
238
|
+
event: Event;
|
|
239
|
+
};
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
// HFS
|
|
243
|
+
'hfs.create': {
|
|
244
|
+
params: Partial<Omit<Event, 'attachments' | EditMetadata>>;
|
|
245
|
+
res: {
|
|
246
|
+
event: Event;
|
|
247
|
+
};
|
|
248
|
+
};
|
|
249
|
+
'hfs.update': {
|
|
250
|
+
params: {
|
|
251
|
+
id: Identifier;
|
|
252
|
+
update: Partial<Omit<Event, 'id' | 'attachments' | EditMetadata>>;
|
|
253
|
+
};
|
|
254
|
+
res: {
|
|
255
|
+
event: Event;
|
|
256
|
+
};
|
|
257
|
+
};
|
|
258
|
+
'hfs.delete': {
|
|
259
|
+
params: {
|
|
260
|
+
id: Identifier;
|
|
261
|
+
};
|
|
262
|
+
res: {
|
|
263
|
+
event: Event;
|
|
264
|
+
};
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
// Streams
|
|
268
|
+
'streams.get': {
|
|
269
|
+
params: {
|
|
270
|
+
parentId?: Identifier;
|
|
271
|
+
state?: 'default' | 'all';
|
|
272
|
+
includeDeletionsSince?: Timestamp;
|
|
273
|
+
};
|
|
274
|
+
res: {
|
|
275
|
+
streams: Stream[];
|
|
276
|
+
streamDeletions?: ItemDeletion[];
|
|
277
|
+
};
|
|
278
|
+
};
|
|
279
|
+
'streams.create': {
|
|
280
|
+
params: Partial<Omit<Stream, 'children' | EditMetadata>>;
|
|
281
|
+
res: {
|
|
282
|
+
stream: Stream;
|
|
283
|
+
};
|
|
284
|
+
};
|
|
285
|
+
'streams.update': {
|
|
286
|
+
params: {
|
|
287
|
+
id: Identifier;
|
|
288
|
+
update: Partial<Stream>;
|
|
289
|
+
};
|
|
290
|
+
res: {
|
|
291
|
+
stream: Stream;
|
|
292
|
+
};
|
|
293
|
+
};
|
|
294
|
+
'streams.delete': {
|
|
295
|
+
params: {
|
|
296
|
+
id: Identifier;
|
|
297
|
+
mergeEventsWithParents: 'true' | 'false';
|
|
298
|
+
};
|
|
299
|
+
res: {
|
|
300
|
+
stream: Stream;
|
|
301
|
+
};
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
// Accesses
|
|
305
|
+
'accesses.get': {
|
|
306
|
+
params: {
|
|
307
|
+
includeExpired?: boolean;
|
|
308
|
+
includeDeletions?: boolean;
|
|
309
|
+
};
|
|
310
|
+
res: {
|
|
311
|
+
accesses: Access[];
|
|
312
|
+
accessDeletions?: Access[];
|
|
313
|
+
};
|
|
314
|
+
};
|
|
315
|
+
'accesses.create': {
|
|
316
|
+
params: Partial<
|
|
317
|
+
Omit<Access, 'id' | 'lastUsed' | 'expires' | 'deleted' | EditMetadata>
|
|
318
|
+
>;
|
|
319
|
+
res: {
|
|
320
|
+
access: Access;
|
|
321
|
+
};
|
|
322
|
+
};
|
|
323
|
+
'accesses.delete': {
|
|
324
|
+
params: {
|
|
325
|
+
id: Identifier;
|
|
326
|
+
};
|
|
327
|
+
res: {
|
|
328
|
+
accessDeletion: ItemDeletion;
|
|
329
|
+
relatedDeletions?: ItemDeletion[];
|
|
330
|
+
};
|
|
331
|
+
};
|
|
332
|
+
'accesses.checkApp': {
|
|
333
|
+
params: {
|
|
334
|
+
requestingAppId: string;
|
|
335
|
+
deviceName?: string;
|
|
336
|
+
requestedPermissions: Array<Permission & { defaultName: string }>;
|
|
337
|
+
};
|
|
338
|
+
res: {
|
|
339
|
+
checkedPermissions?: Permission[];
|
|
340
|
+
mismatchingAccess?: Access;
|
|
341
|
+
matchingAccess?: Access;
|
|
342
|
+
};
|
|
343
|
+
};
|
|
344
|
+
getAccessInfo: {
|
|
345
|
+
params: null;
|
|
346
|
+
res: {
|
|
347
|
+
calls: KeyValue;
|
|
348
|
+
user: KeyValue;
|
|
349
|
+
};
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
// Webhooks
|
|
353
|
+
'webhooks.get': {
|
|
354
|
+
params: null;
|
|
355
|
+
res: {
|
|
356
|
+
webhooks: WebHook[];
|
|
357
|
+
};
|
|
358
|
+
};
|
|
359
|
+
'webhooks.getOne': {
|
|
360
|
+
params: {
|
|
361
|
+
id: Identifier;
|
|
362
|
+
};
|
|
363
|
+
res: {
|
|
364
|
+
webhook: WebHook;
|
|
365
|
+
};
|
|
366
|
+
};
|
|
367
|
+
'webhooks.create': {
|
|
368
|
+
params: {
|
|
369
|
+
webhook: Partial<Pick<WebHook, 'url' | 'state'>>;
|
|
370
|
+
};
|
|
371
|
+
res: {
|
|
372
|
+
webhook: WebHook;
|
|
373
|
+
};
|
|
374
|
+
};
|
|
375
|
+
'webhooks.update': {
|
|
376
|
+
params: {
|
|
377
|
+
id: Identifier;
|
|
378
|
+
update: Partial<Pick<WebHook, 'state'>>;
|
|
379
|
+
};
|
|
380
|
+
res: {
|
|
381
|
+
webhook: WebHook;
|
|
382
|
+
};
|
|
383
|
+
};
|
|
384
|
+
'webhooks.delete': {
|
|
385
|
+
params: {
|
|
386
|
+
id: Identifier;
|
|
387
|
+
};
|
|
388
|
+
res: {
|
|
389
|
+
webhookDeletion: ItemDeletion;
|
|
390
|
+
};
|
|
391
|
+
};
|
|
392
|
+
'webhooks.test': {
|
|
393
|
+
params: {
|
|
394
|
+
id: Identifier;
|
|
395
|
+
};
|
|
396
|
+
res: {
|
|
397
|
+
webhook: WebHook;
|
|
398
|
+
};
|
|
399
|
+
};
|
|
400
|
+
|
|
401
|
+
// Followed Slices
|
|
402
|
+
'followedSlices.get': {
|
|
403
|
+
params: null;
|
|
404
|
+
res: {
|
|
405
|
+
followedSlices: FollowedSlice[];
|
|
406
|
+
};
|
|
407
|
+
};
|
|
408
|
+
'followedSlices.create': {
|
|
409
|
+
params: Partial<Pick<FollowedSlice, 'name' | 'url' | 'accessToken'>>;
|
|
410
|
+
res: {
|
|
411
|
+
followedSlice: FollowedSlice;
|
|
412
|
+
};
|
|
413
|
+
};
|
|
414
|
+
'followedSlices.update': {
|
|
415
|
+
params: {
|
|
416
|
+
id: Identifier;
|
|
417
|
+
update: Partial<Pick<FollowedSlice, 'name' | 'url' | 'accessToken'>>;
|
|
418
|
+
};
|
|
419
|
+
res: {
|
|
420
|
+
followedSlice: FollowedSlice;
|
|
421
|
+
};
|
|
422
|
+
};
|
|
423
|
+
'followedSlices.delete': {
|
|
424
|
+
params: {
|
|
425
|
+
id: Identifier;
|
|
426
|
+
};
|
|
427
|
+
res: {
|
|
428
|
+
followedSliceDeletion: ItemDeletion;
|
|
429
|
+
};
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
// Profile sets
|
|
433
|
+
'profile.getApp': {
|
|
434
|
+
params: null;
|
|
435
|
+
res: {
|
|
436
|
+
profile: KeyValue;
|
|
437
|
+
};
|
|
438
|
+
};
|
|
439
|
+
'profile.updateApp': {
|
|
440
|
+
params: {
|
|
441
|
+
update: KeyValue;
|
|
442
|
+
};
|
|
443
|
+
res: {
|
|
444
|
+
profile: KeyValue;
|
|
445
|
+
};
|
|
446
|
+
};
|
|
447
|
+
'profile.getPublic': {
|
|
448
|
+
params: null;
|
|
449
|
+
res: {
|
|
450
|
+
profile: KeyValue;
|
|
451
|
+
};
|
|
452
|
+
};
|
|
453
|
+
'profile.updatePublic': {
|
|
454
|
+
params: {
|
|
455
|
+
update: KeyValue;
|
|
456
|
+
};
|
|
457
|
+
res: {
|
|
458
|
+
profile: KeyValue;
|
|
459
|
+
};
|
|
460
|
+
};
|
|
461
|
+
'profile.getPrivate': {
|
|
462
|
+
params: null;
|
|
463
|
+
res: {
|
|
464
|
+
profile: KeyValue;
|
|
465
|
+
};
|
|
466
|
+
};
|
|
467
|
+
'profile.updatePrivate': {
|
|
468
|
+
params: {
|
|
469
|
+
update: KeyValue;
|
|
470
|
+
};
|
|
471
|
+
res: {
|
|
472
|
+
profile: KeyValue;
|
|
473
|
+
};
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
// Account management
|
|
477
|
+
'account.get': {
|
|
478
|
+
params: null;
|
|
479
|
+
res: {
|
|
480
|
+
account: AccountInformation;
|
|
481
|
+
};
|
|
482
|
+
};
|
|
483
|
+
'account.update': {
|
|
484
|
+
params: {
|
|
485
|
+
update: Partial<Omit<AccountInformation, 'username'>>;
|
|
486
|
+
};
|
|
487
|
+
res: {
|
|
488
|
+
account: AccountInformation;
|
|
489
|
+
};
|
|
490
|
+
};
|
|
491
|
+
'account.changePassword': {
|
|
492
|
+
params: {
|
|
493
|
+
oldPassword: string;
|
|
494
|
+
newPassword: string;
|
|
495
|
+
};
|
|
496
|
+
res: null;
|
|
497
|
+
};
|
|
498
|
+
'account.requestPasswordReset': {
|
|
499
|
+
params: {
|
|
500
|
+
appId: string;
|
|
501
|
+
};
|
|
502
|
+
res: null;
|
|
503
|
+
};
|
|
504
|
+
'account.resetPassword': {
|
|
505
|
+
params: {
|
|
506
|
+
resetToken: string;
|
|
507
|
+
newPassword: string;
|
|
508
|
+
appId: string;
|
|
509
|
+
};
|
|
510
|
+
res: null;
|
|
511
|
+
};
|
|
512
|
+
};
|
|
513
|
+
|
|
514
|
+
type UnionToIntersection<U> = (
|
|
515
|
+
U extends any ? (k: U) => any : never
|
|
516
|
+
) extends (k: infer I) => any
|
|
517
|
+
? I
|
|
518
|
+
: never;
|
|
519
|
+
type ApiCallResultUnion = ApiCallMethods[keyof ApiCallMethods]['res'];
|
|
520
|
+
type ApiCallResultTypes = UnionToIntersection<
|
|
521
|
+
NonNullable<ApiCallResultUnion>
|
|
522
|
+
>;
|
|
523
|
+
|
|
524
|
+
type PossibleError = {
|
|
525
|
+
error?: Error;
|
|
526
|
+
};
|
|
527
|
+
|
|
528
|
+
type ApiCallResult<K extends keyof ApiCallMethods> =
|
|
529
|
+
ApiCallMethods[K]['res'] & PossibleError;
|
|
530
|
+
|
|
531
|
+
export type ApiCallResultHandler<K extends keyof ApiCallMethods> = (
|
|
532
|
+
result: ApiCallResult<K>,
|
|
533
|
+
) => Promise<any>;
|
|
534
|
+
export type StreamedEventsHandler = (event: Event) => void;
|
|
535
|
+
|
|
536
|
+
type StreamedEventsResult = {
|
|
537
|
+
eventsCount?: number;
|
|
538
|
+
eventsDeletionsCount?: number;
|
|
539
|
+
meta: {
|
|
540
|
+
apiVersion: string;
|
|
541
|
+
serverTime: number;
|
|
542
|
+
serial: string;
|
|
543
|
+
};
|
|
544
|
+
};
|
|
545
|
+
|
|
546
|
+
export type EventFileCreationParams = Partial<
|
|
547
|
+
Omit<Event, 'attachments' | EditMetadata>
|
|
548
|
+
>;
|
|
549
|
+
export type ApiCall<K extends keyof ApiCallMethods = keyof ApiCallMethods> =
|
|
550
|
+
K extends keyof ApiCallMethods
|
|
551
|
+
? {
|
|
552
|
+
method: K;
|
|
553
|
+
params: ApiCallMethods[K]['params'];
|
|
554
|
+
handleResult?: ApiCallResultHandler<K>;
|
|
555
|
+
}
|
|
556
|
+
: never;
|
|
557
|
+
|
|
558
|
+
export type TypedApiCallResult = ApiCallResultTypes & PossibleError;
|
|
559
|
+
|
|
560
|
+
export type ApiCallProgressHandler = (percentage: number) => void;
|
|
561
|
+
|
|
562
|
+
interface AccessInfo extends Access {
|
|
563
|
+
calls: KeyValue;
|
|
564
|
+
user: KeyValue;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
type EventApiCallRes = {
|
|
568
|
+
event?: Event;
|
|
569
|
+
} & PossibleError;
|
|
570
|
+
|
|
571
|
+
export interface Connection {
|
|
572
|
+
new (pryvApiEndpoint: string, service?: Service): Connection;
|
|
573
|
+
get service(): Service;
|
|
574
|
+
username(): Promise<string>;
|
|
575
|
+
api<Calls extends ApiCall[] = ApiCall[]>(
|
|
576
|
+
apiCalls: Calls,
|
|
577
|
+
res?: ApiCallProgressHandler[],
|
|
578
|
+
): Promise<Array<TypedApiCallResult>>;
|
|
579
|
+
getEventsStreamed(
|
|
580
|
+
queryParams: Partial<EventQueryParamsStreamQuery>,
|
|
581
|
+
forEachEvent: StreamedEventsHandler,
|
|
582
|
+
): Promise<StreamedEventsResult>;
|
|
583
|
+
createEventWithFile(
|
|
584
|
+
params: EventFileCreationParams,
|
|
585
|
+
filePath: string | Buffer | Blob,
|
|
586
|
+
): Promise<EventApiCallRes>;
|
|
587
|
+
createEventWithFormData(
|
|
588
|
+
params: EventFileCreationParams,
|
|
589
|
+
formData: FormData,
|
|
590
|
+
): Promise<EventApiCallRes>;
|
|
591
|
+
createEventWithFileFromBuffer(
|
|
592
|
+
params: EventFileCreationParams,
|
|
593
|
+
bufferData: string | Buffer,
|
|
594
|
+
filename: string,
|
|
595
|
+
): Promise<EventApiCallRes>;
|
|
596
|
+
addPointsToHFEvent(
|
|
597
|
+
id: Identifier,
|
|
598
|
+
fields: string[],
|
|
599
|
+
values: Array<string | number>,
|
|
600
|
+
): Promise<void>;
|
|
601
|
+
accessInfo(): Promise<AccessInfo>;
|
|
602
|
+
|
|
603
|
+
post(
|
|
604
|
+
path: string,
|
|
605
|
+
data: Object | any[],
|
|
606
|
+
queryParams: Object,
|
|
607
|
+
): Promise<Object | Object[]>;
|
|
608
|
+
get(path: string, queryParams: Object): Promise<Object | Object[]>;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
export type serviceCustomizations = {
|
|
612
|
+
name?: string;
|
|
613
|
+
assets?: {
|
|
614
|
+
definitions?: string;
|
|
615
|
+
};
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
export type PryvServiceInfo = {
|
|
619
|
+
register: string;
|
|
620
|
+
access: string;
|
|
621
|
+
api: string;
|
|
622
|
+
name: string;
|
|
623
|
+
home: string;
|
|
624
|
+
support: string;
|
|
625
|
+
terms: string;
|
|
626
|
+
eventTypes: string;
|
|
627
|
+
version: string;
|
|
628
|
+
};
|
|
629
|
+
|
|
630
|
+
export type AssetsConfig = {
|
|
631
|
+
baseUrl: string;
|
|
632
|
+
href: string;
|
|
633
|
+
favicon: {
|
|
634
|
+
[key: string]: string;
|
|
635
|
+
default: string;
|
|
636
|
+
};
|
|
637
|
+
css: {
|
|
638
|
+
[key: string]: string;
|
|
639
|
+
default: string;
|
|
640
|
+
};
|
|
641
|
+
'lib-js': {
|
|
642
|
+
[key: string]: KeyValue | any;
|
|
643
|
+
};
|
|
644
|
+
|
|
645
|
+
[key: string]: any;
|
|
646
|
+
};
|
|
647
|
+
|
|
648
|
+
export interface Service {
|
|
649
|
+
new (
|
|
650
|
+
serviceInfoUrl: string,
|
|
651
|
+
serviceCustomizations?: serviceCustomizations,
|
|
652
|
+
): Service;
|
|
653
|
+
info(forceFetch?: boolean): Promise<PryvServiceInfo>;
|
|
654
|
+
setServiceInfo(serviceInfo: Partial<PryvServiceInfo>): Promise<void>;
|
|
655
|
+
assets(forceFetch?: boolean): Promise<AssetsConfig>;
|
|
656
|
+
infoSync(): PryvServiceInfo | null;
|
|
657
|
+
apiEndpointFor(username: string, token: string): Promise<string>;
|
|
658
|
+
login(
|
|
659
|
+
username: string,
|
|
660
|
+
password: string,
|
|
661
|
+
appId: string,
|
|
662
|
+
originHeader?: string,
|
|
663
|
+
): Promise<Connection>;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
export type AuthRequestedPermission = {
|
|
667
|
+
streamId: Identifier;
|
|
668
|
+
defaultName: string;
|
|
669
|
+
level: Level;
|
|
670
|
+
};
|
|
671
|
+
|
|
672
|
+
export type States =
|
|
673
|
+
| 'LOADING'
|
|
674
|
+
| 'INITIALIZED'
|
|
675
|
+
| 'NEED_SIGNIN'
|
|
676
|
+
| 'ACCEPTED'
|
|
677
|
+
| 'SIGNOUT';
|
|
678
|
+
|
|
679
|
+
type ServiceInfo = {
|
|
680
|
+
access: string;
|
|
681
|
+
api: string;
|
|
682
|
+
assets: {
|
|
683
|
+
definitions: string;
|
|
684
|
+
};
|
|
685
|
+
eventTypes: string;
|
|
686
|
+
home: string;
|
|
687
|
+
name: string;
|
|
688
|
+
register: string;
|
|
689
|
+
serial: string;
|
|
690
|
+
support: string;
|
|
691
|
+
terms: string;
|
|
692
|
+
version: string;
|
|
693
|
+
};
|
|
694
|
+
|
|
695
|
+
type StateChangeTypes = {
|
|
696
|
+
LOADING: {};
|
|
697
|
+
INITIALIZED: {
|
|
698
|
+
serviceInfo: ServiceInfo;
|
|
699
|
+
};
|
|
700
|
+
NEED_SIGNIN: {
|
|
701
|
+
authUrl: string;
|
|
702
|
+
clientData: any;
|
|
703
|
+
code: number;
|
|
704
|
+
key: string;
|
|
705
|
+
lang: string;
|
|
706
|
+
oauthState: any;
|
|
707
|
+
poll: string;
|
|
708
|
+
poll_rate_ms: number;
|
|
709
|
+
requestedPermissions: Array<{
|
|
710
|
+
streamId: string;
|
|
711
|
+
level: Level;
|
|
712
|
+
defaultName: string;
|
|
713
|
+
}>;
|
|
714
|
+
requestingAppId: string;
|
|
715
|
+
returnUrl: any;
|
|
716
|
+
serviceInfo: ServiceInfo;
|
|
717
|
+
};
|
|
718
|
+
ACCEPTED: {
|
|
719
|
+
serviceInfo: ServiceInfo;
|
|
720
|
+
apiEndpoint: string;
|
|
721
|
+
username: string;
|
|
722
|
+
token: string;
|
|
723
|
+
};
|
|
724
|
+
SIGNOUT: {};
|
|
725
|
+
};
|
|
726
|
+
|
|
727
|
+
export type StateChange<K extends States> = StateChangeTypes[K] & {
|
|
728
|
+
id: K;
|
|
729
|
+
status: K;
|
|
730
|
+
};
|
|
731
|
+
|
|
732
|
+
export type AuthSettings = {
|
|
733
|
+
spanButtonID?: string;
|
|
734
|
+
onStateChange?: (state: StateChange<States>) => void;
|
|
735
|
+
returnURL?: string;
|
|
736
|
+
authRequest: {
|
|
737
|
+
requestingAppId: string;
|
|
738
|
+
languageCode?: string;
|
|
739
|
+
requestedPermissions: AuthRequestedPermission[];
|
|
740
|
+
returnUrl?: string | boolean;
|
|
741
|
+
referer?: string;
|
|
742
|
+
clientData?: Object;
|
|
743
|
+
};
|
|
744
|
+
};
|
|
745
|
+
|
|
746
|
+
type SetupAuth = (
|
|
747
|
+
settings: AuthSettings,
|
|
748
|
+
serviceInfoUrl: string,
|
|
749
|
+
serviceCustomizations?: serviceCustomizations,
|
|
750
|
+
humanInteraction?: any,
|
|
751
|
+
) => Promise<Service>;
|
|
752
|
+
|
|
753
|
+
export type AuthStates = {
|
|
754
|
+
ERROR: 'ERROR';
|
|
755
|
+
LOADING: 'LOADING';
|
|
756
|
+
INITIALIZED: 'INITIALIZED';
|
|
757
|
+
NEED_SIGNIN: 'NEED_SIGNIN';
|
|
758
|
+
AUTHORIZED: 'ACCEPTED';
|
|
759
|
+
SIGNOUT: 'SIGNOUT';
|
|
760
|
+
REFUSED: 'REFUSED';
|
|
761
|
+
};
|
|
762
|
+
|
|
763
|
+
type AuthStatePayload = {
|
|
764
|
+
status: AuthStates[keyof AuthStates];
|
|
765
|
+
message?: string;
|
|
766
|
+
};
|
|
767
|
+
|
|
768
|
+
export interface CustomLoginButton {
|
|
769
|
+
init?: () => Promise<void>;
|
|
770
|
+
getAuthorizationData(): string;
|
|
771
|
+
onStateChange(state: AuthStatePayload): Promise<void>;
|
|
772
|
+
onClick(): void;
|
|
773
|
+
saveAuthorizationData?: (authData: string) => void;
|
|
774
|
+
deleteAuthorizationData?: () => Promise<void>;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
export interface AuthController {
|
|
778
|
+
new (
|
|
779
|
+
authSettings: AuthSettings,
|
|
780
|
+
service: Service,
|
|
781
|
+
loginButton: CustomLoginButton,
|
|
782
|
+
): AuthController;
|
|
783
|
+
init(): Promise<void>;
|
|
784
|
+
stopAuthRequest(msg: string): void;
|
|
785
|
+
handleClick(): Promise<void>;
|
|
786
|
+
getReturnURL(
|
|
787
|
+
returnURL: string,
|
|
788
|
+
windowLocationForTest: string,
|
|
789
|
+
navigatorForTests: string,
|
|
790
|
+
): string | boolean;
|
|
791
|
+
startAuthRequest(): Promise<any>;
|
|
792
|
+
doPolling(): Promise<void>;
|
|
793
|
+
set state(newState: AuthStatePayload);
|
|
794
|
+
get state(): AuthStatePayload;
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
export interface Auth {
|
|
798
|
+
setupAuth: SetupAuth;
|
|
799
|
+
AuthStates: AuthStates;
|
|
800
|
+
AuthController: AuthController;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
export interface CookieUtils {
|
|
804
|
+
set(cookieKey: string, value: any, expireInDays: number): void;
|
|
805
|
+
get(cookieKey: string): any;
|
|
806
|
+
del(cookieKey: string): void;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
type getServiceInfoFromURL = (url: string) => string;
|
|
810
|
+
|
|
811
|
+
export interface Browser {
|
|
812
|
+
LoginButton: CustomLoginButton;
|
|
813
|
+
CookieUtils: CookieUtils;
|
|
814
|
+
AuthStates: AuthStates;
|
|
815
|
+
setupAuth: SetupAuth;
|
|
816
|
+
serviceInfoFromUrl: getServiceInfoFromURL;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
type TokenAndApiEndpoint = {
|
|
820
|
+
endpoint: string;
|
|
821
|
+
token: string;
|
|
822
|
+
};
|
|
823
|
+
|
|
824
|
+
export interface utils {
|
|
825
|
+
isBrowser(): boolean;
|
|
826
|
+
extractTokenAndApiEndpoint(pryvApiEndpoint: string): TokenAndApiEndpoint;
|
|
827
|
+
buildPryvApiEndpoint(tokenAndApi: TokenAndApiEndpoint): string;
|
|
828
|
+
browserIsMobileOrTablet(navigator: string): boolean;
|
|
829
|
+
cleanURLFromPrYvParams(url: string): string;
|
|
830
|
+
getQueryParamsFromURL(url: string): KeyValue;
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
type version = string;
|
|
834
|
+
|
|
835
|
+
let Pryv: {
|
|
836
|
+
Service: Service;
|
|
837
|
+
Connection: Connection;
|
|
838
|
+
Auth: Auth;
|
|
839
|
+
Browser: Browser;
|
|
840
|
+
utils: utils;
|
|
841
|
+
version: version;
|
|
842
|
+
};
|
|
843
|
+
|
|
844
|
+
export default Pryv;
|
|
845
|
+
}
|
package/test/Connection.test.js
CHANGED
|
@@ -5,6 +5,13 @@ let conn = null;
|
|
|
5
5
|
const { URL, URLSearchParams } = require('universal-url');
|
|
6
6
|
const cuid = require('cuid');
|
|
7
7
|
|
|
8
|
+
const isNode = (typeof window === 'undefined');
|
|
9
|
+
|
|
10
|
+
let readFileSync;
|
|
11
|
+
if (isNode) { // node
|
|
12
|
+
readFileSync = require('fs').readFileSync;
|
|
13
|
+
}
|
|
14
|
+
|
|
8
15
|
describe('Connection', () => {
|
|
9
16
|
|
|
10
17
|
before(async function () {
|
|
@@ -183,35 +190,85 @@ describe('Connection', () => {
|
|
|
183
190
|
});
|
|
184
191
|
|
|
185
192
|
describe('Attachements', () => {
|
|
186
|
-
it('Create event with
|
|
187
|
-
|
|
193
|
+
it('Node Only: Create event with attachment from file', async function () {
|
|
194
|
+
if (!isNode) { this.skip(); }
|
|
195
|
+
const res = await conn.createEventWithFile({
|
|
196
|
+
type: 'picture/attached',
|
|
197
|
+
streamId: 'data'
|
|
198
|
+
}, './test/Y.png');
|
|
188
199
|
|
|
189
|
-
if (typeof window === 'undefined') { // node
|
|
190
200
|
|
|
191
|
-
|
|
201
|
+
should.exist(res);
|
|
202
|
+
should.exist(res.event);
|
|
203
|
+
should.exist(res.event.attachments);
|
|
204
|
+
res.event.attachments.length.should.equal(1);
|
|
205
|
+
res.event.attachments[0].size.should.equal(14798);
|
|
206
|
+
res.event.attachments[0].type.should.equal('image/png');
|
|
207
|
+
res.event.attachments[0].fileName.should.equal('Y.png');
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it('Node Only: Create event with attachment from Buffer', async function () {
|
|
211
|
+
if (!isNode) { this.skip(); }
|
|
212
|
+
|
|
213
|
+
const fileData = readFileSync('./test/Y.png');
|
|
214
|
+
const res = await conn.createEventWithFileFromBuffer({
|
|
192
215
|
type: 'picture/attached',
|
|
193
216
|
streamId: 'data'
|
|
194
|
-
}, '
|
|
217
|
+
}, fileData, 'Y.png');
|
|
195
218
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
219
|
+
should.exist(res);
|
|
220
|
+
should.exist(res.event);
|
|
221
|
+
should.exist(res.event.attachments);
|
|
222
|
+
res.event.attachments.length.should.equal(1);
|
|
223
|
+
res.event.attachments[0].size.should.equal(14798);
|
|
224
|
+
res.event.attachments[0].type.should.equal('image/png');
|
|
225
|
+
res.event.attachments[0].fileName.should.equal('Y.png');
|
|
200
226
|
|
|
201
|
-
|
|
202
|
-
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
it('Browser Only: Create event with attachment from Buffer', async function () {
|
|
230
|
+
if (isNode) { this.skip(); }
|
|
231
|
+
|
|
232
|
+
const blob = new Blob(['Hello'], { type: "text/txt" });
|
|
233
|
+
const res = await conn.createEventWithFileFromBuffer({
|
|
234
|
+
type: 'picture/attached',
|
|
203
235
|
streamId: 'data'
|
|
204
|
-
},
|
|
236
|
+
}, blob, 'Hello.txt');
|
|
237
|
+
|
|
238
|
+
should.exist(res);
|
|
239
|
+
should.exist(res.event);
|
|
240
|
+
console.log(res.event);
|
|
241
|
+
should.exist(res.event.attachments);
|
|
242
|
+
res.event.attachments.length.should.equal(1);
|
|
243
|
+
res.event.attachments[0].size.should.equal(5);
|
|
244
|
+
res.event.attachments[0].type.should.equal('text/txt');
|
|
245
|
+
res.event.attachments[0].fileName.should.equal('Hello.txt');
|
|
246
|
+
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it('Browser Only: Create event with attachment formData', async function () {
|
|
250
|
+
if (isNode) { this.skip(); }
|
|
205
251
|
|
|
206
|
-
|
|
252
|
+
const formData = new FormData();
|
|
253
|
+
const blob = new Blob(['Hello'], { type: "text/txt" });
|
|
254
|
+
formData.append("webmasterfile", blob);
|
|
255
|
+
|
|
256
|
+
const res = await conn.createEventWithFormData({
|
|
257
|
+
type: 'file/attached',
|
|
258
|
+
streamId: 'data'
|
|
259
|
+
}, formData);
|
|
207
260
|
|
|
208
261
|
|
|
209
262
|
should.exist(res);
|
|
210
263
|
should.exist(res.event);
|
|
211
264
|
should.exist(res.event.attachments);
|
|
212
265
|
res.event.attachments.length.should.equal(1);
|
|
213
|
-
|
|
266
|
+
res.event.attachments[0].size.should.equal(5);
|
|
267
|
+
res.event.attachments[0].type.should.equal('text/txt');
|
|
268
|
+
res.event.attachments[0].fileName.should.equal('blob');
|
|
214
269
|
});
|
|
270
|
+
|
|
271
|
+
|
|
215
272
|
});
|
|
216
273
|
|
|
217
274
|
describe('HF events', () => {
|
|
@@ -301,14 +358,14 @@ describe('Connection', () => {
|
|
|
301
358
|
});
|
|
302
359
|
|
|
303
360
|
it('no-events ', async () => {
|
|
304
|
-
const queryParams = { fromTime: 0, toTime: now,
|
|
361
|
+
const queryParams = { fromTime: 0, toTime: now, types: ['type/unexistent'] };
|
|
305
362
|
function forEachEvent(event) { }
|
|
306
363
|
const res = await conn.getEventsStreamed(queryParams, forEachEvent);
|
|
307
364
|
expect(0).to.equal(res.eventsCount);
|
|
308
365
|
});
|
|
309
366
|
|
|
310
367
|
it('no-events includeDeletions', async () => {
|
|
311
|
-
const queryParams = { fromTime: 0, toTime: now,
|
|
368
|
+
const queryParams = { fromTime: 0, toTime: now, types: ['type/unexistent'], includeDeletions: true, modifiedSince: 0 };
|
|
312
369
|
function forEachEvent(event) { }
|
|
313
370
|
const res = await conn.getEventsStreamed(queryParams, forEachEvent);
|
|
314
371
|
expect(0).to.equal(res.eventsCount);
|
|
@@ -406,19 +463,6 @@ describe('Connection', () => {
|
|
|
406
463
|
should.equal(newUser.access.name, accessInfoUser.name);
|
|
407
464
|
});
|
|
408
465
|
|
|
409
|
-
it('has same permissions', () => {
|
|
410
|
-
should.exist(accessInfoUser);
|
|
411
|
-
should.exist(accessInfoUser.permissions);
|
|
412
|
-
let lengthPermission = accessInfoUser.permissions.length;
|
|
413
|
-
should.equal(newUser.access.permissions.length, lengthPermission);
|
|
414
|
-
for (let i = 0; i < lengthPermission; i++) {
|
|
415
|
-
should.exist(accessInfoUser.permissions[i].streamId);
|
|
416
|
-
should.equal(newUser.access.permissions[i].streamId, accessInfoUser.permissions[i].streamId);
|
|
417
|
-
should.exist(accessInfoUser.permissions[i].level);
|
|
418
|
-
should.equal(newUser.access.permissions[i].level, accessInfoUser.permissions[i].level);
|
|
419
|
-
}
|
|
420
|
-
});
|
|
421
|
-
|
|
422
466
|
it('has same token', () => {
|
|
423
467
|
should.exist(accessInfoUser.token);
|
|
424
468
|
should.equal(newUser.access.token, accessInfoUser.token);
|
package/test/test-data.js
CHANGED
|
@@ -61,9 +61,12 @@ async function prepare() {
|
|
|
61
61
|
});
|
|
62
62
|
}
|
|
63
63
|
const apiEndpoint = serviceInfo.api.replace('{username}', username);
|
|
64
|
+
|
|
64
65
|
// login user
|
|
66
|
+
const headers = {};
|
|
67
|
+
if (typeof window === 'undefined') { headers.Origin = 'https://l.rec.la'; }; // node only
|
|
65
68
|
const loginRes = await superagent.post(apiEndpoint + 'auth/login')
|
|
66
|
-
.set(
|
|
69
|
+
.set(headers)
|
|
67
70
|
.send({ username: username, password: username, appId: 'js-lib-test' });
|
|
68
71
|
|
|
69
72
|
// create data stream
|
package/webpack.config.js
CHANGED
|
@@ -24,7 +24,7 @@ module.exports = [
|
|
|
24
24
|
{ // es5 version
|
|
25
25
|
mode: 'production',
|
|
26
26
|
entry: {
|
|
27
|
-
'pryv': ['
|
|
27
|
+
'pryv': ['./src/index.js'],
|
|
28
28
|
},
|
|
29
29
|
output: {
|
|
30
30
|
filename: '[name].js',
|
|
@@ -38,7 +38,7 @@ module.exports = [
|
|
|
38
38
|
{ // es5 version including socket.io and monitors
|
|
39
39
|
mode: 'production',
|
|
40
40
|
entry: {
|
|
41
|
-
'pryv-socket.io-monitor': ['
|
|
41
|
+
'pryv-socket.io-monitor': ['./src/index-socket.io-monitor.js'],
|
|
42
42
|
},
|
|
43
43
|
output: {
|
|
44
44
|
filename: '[name].js',
|
|
@@ -47,7 +47,13 @@ module.exports = [
|
|
|
47
47
|
library: 'Pryv'
|
|
48
48
|
},
|
|
49
49
|
devtool: 'source-map',
|
|
50
|
-
module: webpackBabelConfig
|
|
50
|
+
module: webpackBabelConfig,
|
|
51
|
+
resolve: {
|
|
52
|
+
fallback: {
|
|
53
|
+
'fs': false,
|
|
54
|
+
'path': false,
|
|
55
|
+
},
|
|
56
|
+
}
|
|
51
57
|
},
|
|
52
58
|
{ // browser test suite (es6)
|
|
53
59
|
mode: 'development',
|
|
@@ -61,11 +67,17 @@ module.exports = [
|
|
|
61
67
|
library: 'browserTest'
|
|
62
68
|
},
|
|
63
69
|
plugins: [
|
|
64
|
-
new webpack.IgnorePlugin(/zombie/),
|
|
70
|
+
new webpack.IgnorePlugin({resourceRegExp: /zombie/}),
|
|
65
71
|
new CopyPlugin({ patterns: [
|
|
66
72
|
{ from: 'test/browser-tests.html' },
|
|
67
73
|
]})
|
|
68
74
|
],
|
|
69
75
|
devtool: 'source-map',
|
|
76
|
+
resolve: {
|
|
77
|
+
fallback: {
|
|
78
|
+
'fs': false,
|
|
79
|
+
'path': false,
|
|
80
|
+
},
|
|
81
|
+
}
|
|
70
82
|
}
|
|
71
83
|
];
|