Skip to content

Commit e99860e

Browse files
committed
Completed doc - making it v0.1.0
1 parent 1aee274 commit e99860e

10 files changed

Lines changed: 191 additions & 11 deletions

AppTemplates.md

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
This document is part of [Generic toolkit for server and web applications](README.md).
2+
3+
# APPLICATION TEMPLATES
4+
5+
6+
App templates based on HDS Model, provide frameworks to build applications for HDS.
7+
8+
- **AppManagingAccount**: App which manages Collectors. A "Collector" handles a "Request" and set of "Responses". => With access to some HDS data from other accounts.
9+
- **AppClientAccount**: Handles requests from `AppManagingAccount` and corresponding responses (agree, refuse, revoke).
10+
11+
## Application class
12+
Both templates extend `Application` class
13+
14+
An application is based on
15+
- one `connection`: an instance of `pryv.Connection`
16+
- one `baseStreamId`: the streamId where the application will store its own operation data (i.e. state management) - This stream should be a children of stream `applications`.
17+
- one `appName`
18+
19+
### instantiating an Application
20+
Either use:
21+
- `App{ExtensionName}.newFromApiEndpoint(baseStreamId, apiEndpoint, appName)`
22+
- `App{ExtensionName}.newFromConnection(baseStreamId, connection, appName)`
23+
24+
It will return an instance already initialized with eventual necessary streams created.
25+
26+
### extending Application class
27+
Check the code for mode details.
28+
29+
## AppManagingAccount
30+
31+
### instantiating
32+
Either use:
33+
- `AppManagingAccount.newFromApiEndpoint(baseStreamId, apiEndpoint, appName)`
34+
- `AppManagingAccount.newFromConnection(baseStreamId, connection, appName)`
35+
36+
Params:
37+
- **apiEndpoint or connection** must have `master` or `personnal` access rights.
38+
39+
### appManagingAccount.getCollectors();
40+
Get current `Collector` instances related to this app
41+
42+
### appManagingAccount.getCollectorById();
43+
Get one `Collector`from its id.
44+
45+
### appManagingAccount.createCollector(name)
46+
Create new `Collector`
47+
48+
49+
### AppManagingAccount Collectors class
50+
A collector is holding
51+
- A single request for accessing a set of streams
52+
- A set of `CollectorInvite` which are to be submitted to **clients**
53+
54+
It has 3 possible states `draft`=> `active` => `deactivated`
55+
56+
Collector instances are created and managed by AppManagingAccount.
57+
58+
#### collector.id
59+
You may use this as a reference to retrieve a specific collector from an app
60+
61+
#### collector.statusCode
62+
One of 'draft', 'active', 'deactivated'
63+
64+
#### collector.statusData
65+
Payload that can be modified
66+
67+
#### async collector.save()
68+
After modifying `collector.statusData` you should save it.
69+
70+
#### async collector.publish()
71+
Once the edition is done and saved, validate and publish. (Can be done just once);
72+
73+
#### async collector.getInvites()
74+
List of current invites
75+
76+
#### async collector.checkInbox ()
77+
Check if new 'accept', 'refuse', 'revoke' messages have been received.
78+
79+
#### AppManagingAccount - CollectorInvite class
80+
A collector invite represents the state of a 1 - 1 relationship between a Collector => A User
81+
It's materialized by an `event` in one of the streams of the Collector
82+
83+
`collectorInvite` instances are created and retrieved by `Collector` instances.
84+
85+
##### collectorInvite.displayName()
86+
Returns the display name set at creation
87+
88+
89+
##### collectorInvite.getSharingData()
90+
When `pending` this will return an `apiEndpoint` and an `eventId` to be shared with a 3rd party app using `ApplicationClient`. This data will be consumed by `appclient.handleIncomingRequest(apiEndpoint, eventId)` to initiate the relationship.
91+
92+
##### collectorInvite.status()
93+
Returns one of `pending`, `active`, `error`.
94+
95+
In case of error, (meaning, means not accessible) the call `collectorInvite.errorType()` will return `revoked` or `refused`.
96+
97+
##### collectorInvite.connection and collectorInvite.apiEndpoint
98+
As an invite is a 1 - 1 relationship, when active, it holds a connection to the matching account.
99+
100+
#### collectorInvite.dateCreation()
101+
Returns a `Date`object.
102+
103+
##### async collectorInvite.checkAndGetAccessInfo()
104+
Check if connection is valid. (only if active)
105+
If the result is "forbidden" update and set as revoked.
106+
107+
Returns the `accessInfo` on success, which can be useful to get the hds username or other infos and the account.
108+
109+
## AppClientAccount
110+
111+
The counterpart of `AppManagingAccount` for "client" applications.
112+
113+
### instantiating
114+
Either use:
115+
- `AppClientAccount.newFromApiEndpoint(baseStreamId, apiEndpoint, appName)`
116+
- `AppClientAccount.newFromConnection(baseStreamId, connection, appName)`
117+
### appClientAccount.handleIncomingRequest(apiEndpoint, incomingEventId)
118+
To be called when the app receives a new request issued by `AppManagingAccount's collectorInvite.getSharingData()`. Returns a `CollectorClient` instance.
119+
120+
### appClientAccount.getCollectorClients()
121+
Get current `CollectorClient` instances.
122+
123+
### appClientAccount.getCollectorClientByKey(collectorKey)
124+
Get a specific `CollectorClient` instance.
125+
126+
### CollectorClient class
127+
128+
#### collectorClient.key
129+
Identifier to retrieve a collector from appClientAccount.
130+
131+
#### collectorClient.status
132+
One of 'Incoming', 'Active', 'Deactivated', 'Refused'
133+
134+
#### collectorClient.requestData
135+
The data holding the requestFrom the invite
136+
137+
#### collectorClient.accept()
138+
Accept current request
139+
140+
#### collectorClient.revoke()
141+
Revoke current request
142+
143+
#### collectorClient.refuse()
144+
Refuse current request

README.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,11 @@ const expected = [
161161

162162
App templates based on HDS Model, provide frameworks to build applications for HDS.
163163

164-
Some of the functionalities will be moved from the lib
164+
- **AppManagingAccount**: App which manages Collectors. A "Collector" handles a "Request" and set of "Responses". => With access to some HDS data from other accounts.
165+
- **AppClientAccount**: Handles requests from `AppManagingAccount` and corresponding responses (agree, refuse, revoke).
166+
167+
Details and examples for theses App templates can be found in [AppTemplates.md]
168+
165169

166170
### toolkit
167171
Misc. tools
@@ -184,7 +188,18 @@ await connection.streamsAutoCreate.ensureExistsForItems(['body-weight', 'profile
184188
<head>
185189
<script src="../docs/hds-lib.js"></script>
186190
<script>
187-
model = new HDSLib.HDSModel();
191+
HDSLib.settings.setServiceInfoURL('https://demo.datasafe.dev/reg/service/info');
192+
HDSLib.settings.setPreferredLocales(['fr', 'en']); // ordered
193+
194+
// init model in async code
195+
(async () => {
196+
await HDSLib.initHDSModel(); // need just one
197+
// from now on an in all your code you use HDSLib.model
198+
199+
// you may create new HDSService with:
200+
const service = new HDSService();
201+
202+
})();
188203
</script>
189204
</head>
190205
```

docs/hds-lib.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/tests-browser.js

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20406,7 +20406,7 @@ class HDSModelAuthorizations {
2040620406
* /!\ Does not handle requests with streamId = "*"
2040720407
* @param {Array<itemKeys>} itemKeys
2040820408
* @param {Object} [options]
20409-
* @param {string} [options.defaultLevel] (default = write) one of 'read', 'write', 'contribute', 'writeOnly'
20409+
* @param {string} [options.defaultLevel] (default = write) one of 'read', 'manage', 'contribute', 'writeOnly'
2041020410
* @param {boolean} [options.includeDefaultName] (default = true) defaultNames are needed for permission requests but not for access creation
2041120411
* @param {Array<AuthorizationRequestItem>} [options.preRequest]
2041220412
* @return {Array<AuthorizationRequestItem>}
@@ -20955,6 +20955,7 @@ class AppClientAccount extends Application {
2095520955
* When the app receives a new request for data sharing
2095620956
* @param {string} apiEndpoint
2095720957
* @param {string} [incomingEventId] - Information for the recipient
20958+
* @returns {CollectorClient}
2095820959
*/
2095920960
async handleIncomingRequest (apiEndpoint, incomingEventId) {
2096020961
// make sure that collectorClientsMap is initialized
@@ -21390,7 +21391,10 @@ class Collector {
2139021391
return this.streamId;
2139121392
}
2139221393

21393-
/** @type {StatusData} */
21394+
/**
21395+
* @type {StatusData}
21396+
* Payload that can be modified
21397+
* */
2139421398
get statusData () {
2139521399
if (this.#cache.status == null) throw new Error('Init Collector first');
2139621400
return this.#cache.status.content.data;
@@ -21841,7 +21845,8 @@ class CollectorClient {
2184121845
}
2184221846

2184321847
/**
21844-
* Create a new Event
21848+
* @private
21849+
* used by appClientAccount.handleIncomingRequest
2184521850
*/
2184621851
static async create (app, apiEndpoint, requesterEventId, accessInfo) {
2184721852
// check content of accessInfo
@@ -21867,6 +21872,7 @@ class CollectorClient {
2186721872
}
2186821873

2186921874
/**
21875+
* @private
2187021876
* reset with new request Event of ApiEndpoint
2187121877
* Identical as create but keep current event
2187221878
*/
@@ -22159,6 +22165,10 @@ class CollectorInvite {
2215922165
this.eventData = eventData;
2216022166
}
2216122167

22168+
/**
22169+
* private
22170+
* @param {*} eventData
22171+
*/
2216222172
setEventData (eventData) {
2216322173
if (eventData.id !== this.eventData.id) throw new HDSLibError('CollectInvite event id does not match new Event');
2216422174
this.eventData = eventData;
@@ -23849,7 +23859,7 @@ describe('[LOCX] Localization', () => {
2384923859
assert.deepEqual(getPreferredLocales(), defaultLocales);
2385023860
});
2385123861

23852-
it('[LOSE] setPreferredLocales throws error if language code unssuported', () => {
23862+
it('[LOSE] setPreferredLocales throws error if language code unsuported', () => {
2385323863
try {
2385423864
setPreferredLocales(['ex', 'en', 'fr', 'ut']);
2385523865
throw new Error('Should throw error');
@@ -24303,6 +24313,7 @@ __webpack_require__(/*! ./hdsModel.test */ "./tests/hdsModel.test.js");
2430324313
__webpack_require__(/*! ./libSettings.test */ "./tests/libSettings.test.js");
2430424314
__webpack_require__(/*! ./localizeText.test */ "./tests/localizeText.test.js");
2430524315
__webpack_require__(/*! ./toolkitStreamAutoCreate.test */ "./tests/toolkitStreamAutoCreate.test.js");
24316+
2430624317
})();
2430724318

2430824319
/******/ })()

docs/tests-browser.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "hds-lib",
3-
"version": "0.0.1",
3+
"version": "0.1.0",
44
"description": "Health Data Safe - Library",
55
"main": "src/index.js",
66
"scripts": {

src/appTemplates/AppClientAccount.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class AppClientAccount extends Application {
2727
* When the app receives a new request for data sharing
2828
* @param {string} apiEndpoint
2929
* @param {string} [incomingEventId] - Information for the recipient
30+
* @returns {CollectorClient}
3031
*/
3132
async handleIncomingRequest (apiEndpoint, incomingEventId) {
3233
// make sure that collectorClientsMap is initialized

src/appTemplates/Collector.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,10 @@ class Collector {
5656
return this.streamId;
5757
}
5858

59-
/** @type {StatusData} */
59+
/**
60+
* @type {StatusData}
61+
* Payload that can be modified
62+
* */
6063
get statusData () {
6164
if (this.#cache.status == null) throw new Error('Init Collector first');
6265
return this.#cache.status.content.data;

src/appTemplates/CollectorClient.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ class CollectorClient {
6868
}
6969

7070
/**
71-
* Create a new Event
71+
* @private
72+
* used by appClientAccount.handleIncomingRequest
7273
*/
7374
static async create (app, apiEndpoint, requesterEventId, accessInfo) {
7475
// check content of accessInfo
@@ -94,6 +95,7 @@ class CollectorClient {
9495
}
9596

9697
/**
98+
* @private
9799
* reset with new request Event of ApiEndpoint
98100
* Identical as create but keep current event
99101
*/

src/appTemplates/CollectorInvite.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ class CollectorInvite {
8686
this.eventData = eventData;
8787
}
8888

89+
/**
90+
* private
91+
* @param {*} eventData
92+
*/
8993
setEventData (eventData) {
9094
if (eventData.id !== this.eventData.id) throw new HDSLibError('CollectInvite event id does not match new Event');
9195
this.eventData = eventData;

0 commit comments

Comments
 (0)