├── .gitignore
├── package.json
├── main-integrate-custom-tests.js
├── mocha-start.js
├── LICENSE.md
├── README.md
├── main-integrate-remotestorage-tests.js
├── main.js
└── main-tests.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # NODE
2 | node_modules
3 | package-lock.json
4 |
5 | # BUILD
6 | **/__*/*
7 | .static
8 |
9 | # OS
10 | **/*.DS_Store
11 |
12 | # LOCAL
13 | .env*
14 | !.env-sample
15 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "main": "main.js",
3 | "scripts": {
4 | "test": "olsk-spec"
5 | },
6 | "devDependencies": {
7 | "OLSKSpec": "olsk/OLSKSpec",
8 | "remotestoragejs": "2.0.0-beta.8"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/main-integrate-custom-tests.js:
--------------------------------------------------------------------------------
1 | const { rejects, deepEqual } = require('assert');
2 |
3 | const mod = require('./main.js');
4 |
5 | describe('_ZDRWrap_Custom', function test__ZDRWrap_Custom() {
6 |
7 | context('ZDRParamDispatchReady', function test_ZDRParamDispatchReady() {
8 |
9 | it('calls immediately', async function () {
10 | const item = Math.random().toString();
11 | deepEqual(await (new Promise(function (res, rej) {
12 | mod._ZDRWrap({
13 | ZDRParamLibrary: uStubCustomClient(),
14 | ZDRParamScopes: [uStubScope()],
15 | ZDRParamDispatchReady: (function () {
16 | return res([item]);
17 | }),
18 | });
19 | })), [item]);
20 | });
21 |
22 | it('calls after ZDRClientPrepare if defined', async function () {
23 | const item = Math.random().toString();
24 | deepEqual(await (new Promise(function (res, rej) {
25 | mod._ZDRWrap({
26 | ZDRParamLibrary: uStubCustomClient({
27 | ZDRClientPrepare: (function () {
28 | return Promise.resolve(item);
29 | }),
30 | }),
31 | ZDRParamScopes: [uStubScope()],
32 | ZDRParamDispatchReady: (function () {
33 | return res(...arguments);
34 | }),
35 | });
36 | })), item);
37 | });
38 |
39 | });
40 |
41 | context('ZDRStorageClient', function test_ZDRStorageClient() {
42 |
43 | it('returns fs', function () {
44 | const ZDRParamLibrary = uStubCustomClient();
45 | deepEqual(mod._ZDRWrap({
46 | ZDRParamLibrary,
47 | ZDRParamScopes: [uStubScope()],
48 | ZDRParamDispatchReady: (function () {}),
49 | }).ZDRStorageClient(), ZDRParamLibrary);
50 | });
51 |
52 | });
53 |
54 | context('ZDRCloudReconnect', function test_ZDRCloudReconnect() {
55 |
56 | it('calls ZDRClientConnect', async function () {
57 | const item = Math.random().toString();
58 | deepEqual(uCapture(function (capture) {
59 | mod._ZDRWrap({
60 | ZDRParamLibrary: uStubCustomClient({
61 | ZDRClientConnect: (function () {
62 | capture(item);
63 | }),
64 | }),
65 | ZDRParamScopes: [uStubScope()],
66 | ZDRParamDispatchReady: (function () {}),
67 | }).ZDRCloudReconnect();
68 | }), [item]);
69 | });
70 |
71 | it('calls ZDRClientReconnect if defined', async function () {
72 | const item = Math.random().toString();
73 | deepEqual(uCapture(function (capture) {
74 | mod._ZDRWrap({
75 | ZDRParamLibrary: uStubCustomClient({
76 | ZDRClientReconnect: (function () {
77 | capture(item);
78 | }),
79 | ZDRClientConnect: (function () {
80 | capture(Math.random().toString());
81 | }),
82 | }),
83 | ZDRParamScopes: [uStubScope()],
84 | ZDRParamDispatchReady: (function () {}),
85 | }).ZDRCloudReconnect();
86 | }), [item]);
87 | });
88 |
89 | });
90 |
91 | });
92 |
--------------------------------------------------------------------------------
/mocha-start.js:
--------------------------------------------------------------------------------
1 | global.fetch = function () {}; // remotestorage.js requires a polyfill for global.fetch on node.js 17 and under
2 |
3 | (function KVCMochaStubs() {
4 | Object.entries({
5 |
6 | uStubSchema(inputData = {}) {
7 | return Object.assign({
8 | ZDRSchemaKey: Math.random().toString(),
9 | ZDRSchemaPath: (function () {
10 | return Math.random().toString();
11 | }),
12 | ZDRSchemaStub: (function () {
13 | return {};
14 | }),
15 | }, inputData);
16 | },
17 |
18 | uStubScope(inputData = {}) {
19 | return Object.assign({
20 | ZDRScopeKey: Math.random().toString(),
21 | ZDRScopeDirectory: Math.random().toString(),
22 | }, inputData);
23 | },
24 |
25 | uStubCustomClient(inputData = {}) {
26 | const tree = {};
27 | return Object.assign({
28 | ZDRClientWriteFile: (function (param1, param2, param3) {
29 | tree[param1] = param2;
30 | }),
31 | ZDRClientReadFile: (function (inputData) {
32 | return tree[inputData];
33 | }),
34 | ZDRClientListObjects: (function () {
35 | return tree;
36 | }),
37 | ZDRClientDelete: (function (inputData) {}),
38 | }, inputData);
39 | },
40 |
41 | uStubRemoteStorage(inputData = {}) {
42 | const RemoteStorage = function (params = {}) {
43 | return (params.modules || []).reduce(function (coll, item) {
44 | const scope = (function () {
45 | const tree = {};
46 | return Object.assign({
47 | storeFile: (function (param1, param2, param3) {
48 | tree[param2] = {
49 | data: param3,
50 | };
51 | }),
52 | getFile: (function (inputData) {
53 | return tree[inputData];
54 | }),
55 | getAll: (function () {
56 | return tree;
57 | }),
58 | getListing: (function () {
59 | return {};
60 | }),
61 | getItemURL: (function () {}),
62 | remove: (function () {}),
63 | }, inputData);
64 | });
65 |
66 | return Object.assign(coll, {
67 | [item.name]: {
68 | privateClient: Object.assign(scope(), inputData.FakePublicClient ? {} : inputData),
69 | publicClient: Object.assign(scope(), inputData.FakePublicClient ? inputData : {}),
70 | },
71 | });
72 | }, Object.assign({
73 | access: Object.assign({
74 | claim: (function () {}),
75 | }, inputData),
76 | caching: Object.assign({
77 | enable: (function () {}),
78 | }, inputData),
79 | connect: (function () {}),
80 | reconnect: (function () {}),
81 | disconnect: (function () {}),
82 | on: (function (param1, param2) {
83 | if (param1 !== 'ready') {
84 | return;
85 | }
86 |
87 | return param2();
88 | }),
89 | remote: {},
90 | }, inputData));
91 | };
92 |
93 | RemoteStorage.Unauthorized = Math.random().toString();
94 |
95 | return RemoteStorage;
96 | },
97 |
98 | uStubLocalStorage(inputData = {}) {
99 | return Object.assign({
100 | getItem: (function () {}),
101 | setItem: (function () {}),
102 | }, inputData);
103 | },
104 |
105 | uStubFilePath () {
106 | return Date.now().toString() + '/' + Date.now().toString();
107 | },
108 |
109 | }).map(function (e) {
110 | return global[e.shift()] = e.pop();
111 | });
112 | })();
113 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (2020) (Rosano Coutinho)
2 |
3 | Hippocratic License Version Number: 2.1.
4 |
5 | * Purpose. The purpose of this License is for the Licensor named above to permit the Licensee (as defined below) broad permission, if consistent with Human Rights Laws and Human Rights Principles (as each is defined below), to use and work with the Software (as defined below) within the full scope of Licensor's copyright and patent rights, if any, in the Software, while ensuring attribution and protecting the Licensor from liability.
6 |
7 | * Permission and Conditions. The Licensor grants permission by this license ("License"), free of charge, to the extent of Licensor's rights under applicable copyright and patent law, to any person or entity (the "Licensee") obtaining a copy of this software and associated documentation files (the "Software"), to do everything with the Software that would otherwise infringe (i) the Licensor's copyright in the Software or (ii) any patent claims to the Software that the Licensor can license or becomes able to license, subject to all of the following terms and conditions:
8 |
9 | * Acceptance. This License is automatically offered to every person and entity subject to its terms and conditions. Licensee accepts this License and agrees to its terms and conditions by taking any action with the Software that, absent this License, would infringe any intellectual property right held by Licensor.
10 |
11 | * Notice. Licensee must ensure that everyone who gets a copy of any part of this Software from Licensee, with or without changes, also receives the License and the above copyright notice (and if included by the Licensor, patent, trademark and attribution notice). Licensee must cause any modified versions of the Software to carry prominent notices stating that Licensee changed the Software. For clarity, although Licensee is free to create modifications of the Software and distribute only the modified portion created by Licensee with additional or different terms, the portion of the Software not modified must be distributed pursuant to this License. If anyone notifies Licensee in writing that Licensee has not complied with this Notice section, Licensee can keep this License by taking all practical steps to comply within 30 days after the notice. If Licensee does not do so, Licensee's License (and all rights licensed hereunder) shall end immediately.
12 |
13 | * Compliance.
14 |
15 | 1. Human Rights Principles.
16 |
17 | (a) Licensee is advised to consult the articles of the United Nations Universal Declaration of Human Rights and the United Nations Global Compact that define recognized principles of international human rights (the "Human Rights Principles"). Licensee shall use the Software in a manner consistent with Human Rights Principles.
18 |
19 | (b) Unless the Licensor and Licensee agree otherwise, any dispute, controversy, or claim arising out of or relating to (i) Section 1(a) regarding Human Rights Principles, including the breach of Section 1(a), termination of this License for breach of the Human Rights Principles, or invalidity of Section 1(a) or (ii) a determination of whether any Law is consistent or in conflict with Human Rights Principles pursuant to Section 2, below, shall be settled by arbitration in accordance with the Hague Rules on Business and Human Rights Arbitration (the "Rules"); provided, however, that Licensee may elect not to participate in such arbitration, in which event this License (and all rights licensed hereunder) shall end immediately. The number of arbitrators shall be one unless the Rules require otherwise.
20 |
21 | Unless both the Licensor and Licensee agree to the contrary: (1) All documents and information concerning the arbitration shall be public and may be disclosed by any party; (2) The repository referred to under Article 43 of the Rules shall make available to the public in a timely manner all documents concerning the arbitration which are communicated to it, including all submissions of the parties, all evidence admitted into the record of the proceedings, all transcripts or other recordings of hearings and all orders, decisions and awards of the arbitral tribunal, subject only to the arbitral tribunal's powers to take such measures as may be necessary to safeguard the integrity of the arbitral process pursuant to Articles 18, 33, 41 and 42 of the Rules; and (3) Article 26(6) of the Rules shall not apply.
22 |
23 | 2. Human Rights Laws. The Software shall not be used by any person or entity for any systems, activities, or other uses that violate any Human Rights Laws. "Human Rights Laws" means any applicable laws, regulations, or rules (collectively, "Laws") that protect human, civil, labor, privacy, political, environmental, security, economic, due process, or similar rights; provided, however, that such Laws are consistent and not in conflict with Human Rights Principles (a dispute over the consistency or a conflict between Laws and Human Rights Principles shall be determined by arbitration as stated above). Where the Human Rights Laws of more than one jurisdiction are applicable or in conflict with respect to the use of the Software, the Human Rights Laws that are most protective of the individuals or groups harmed shall apply.
24 |
25 | 3. [Surveillance Capitalism](https://en.wikipedia.org/wiki/Surveillance_capitalism). The Software shall not be used by any person or entity for any systems, activities, or other uses that actively and knowingly participate in data gathering for the purpose of advertising or surveillance capitalism.
26 |
27 | 4. Large commercial actors. For-profit entities earning revenues in excess of $1,000,000 USD per year must obtain approval from the copyright holder and purchase a paid licence in order to use the Software in commercial projects.
28 |
29 | 5. Indemnity. Licensee shall hold harmless and indemnify Licensor (and any other contributor) against all losses, damages, liabilities, deficiencies, claims, actions, judgments, settlements, interest, awards, penalties, fines, costs, or expenses of whatever kind, including Licensor's reasonable attorneys' fees, arising out of or relating to Licensee's use of the Software in violation of Human Rights Laws or Human Rights Principles.
30 |
31 | * Failure to Comply. Any failure of Licensee to act according to the terms and conditions of this License is both a breach of the License and an infringement of the intellectual property rights of the Licensor (subject to exceptions under Laws, e.g., fair use). In the event of a breach or infringement, the terms and conditions of this License may be enforced by Licensor under the Laws of any jurisdiction to which Licensee is subject. Licensee also agrees that the Licensor may enforce the terms and conditions of this License against Licensee through specific performance (or similar remedy under Laws) to the extent permitted by Laws. For clarity, except in the event of a breach of this License, infringement, or as otherwise stated in this License, Licensor may not terminate this License with Licensee.
32 |
33 | * Enforceability and Interpretation. If any term or provision of this License is determined to be invalid, illegal, or unenforceable by a court of competent jurisdiction, then such invalidity, illegality, or unenforceability shall not affect any other term or provision of this License or invalidate or render unenforceable such term or provision in any other jurisdiction; provided, however, subject to a court modification pursuant to the immediately following sentence, if any term or provision of this License pertaining to Human Rights Laws or Human Rights Principles is deemed invalid, illegal, or unenforceable against Licensee by a court of competent jurisdiction, all rights in the Software granted to Licensee shall be deemed null and void as between Licensor and Licensee. Upon a determination that any term or provision is invalid, illegal, or unenforceable, to the extent permitted by Laws, the court may modify this License to affect the original purpose that the Software be used in compliance with Human Rights Principles and Human Rights Laws as closely as possible. The language in this License shall be interpreted as to its fair meaning and not strictly for or against any party.
34 |
35 | * Disclaimer. TO THE FULL EXTENT ALLOWED BY LAW, THIS SOFTWARE COMES "AS IS," WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED, AND LICENSOR AND ANY OTHER CONTRIBUTOR SHALL NOT BE LIABLE TO ANYONE FOR ANY DAMAGES OR OTHER LIABILITY ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THIS LICENSE, UNDER ANY KIND OF LEGAL CLAIM.
36 |
37 | This Hippocratic License is an Ethical Source license (https://ethicalsource.dev) and is offered for use by licensors and licensees at their own risk, on an "AS IS" basis, and with no warranties express or implied, to the maximum extent permitted by Laws.
38 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # [Zero Data](https://0data.app) Wrap
4 |
5 | _Unified JavaScript API for [Fission](https://guide.fission.codes/developers/webnative) + [remoteStorage](https://github.com/remotestorage/remotestorage.js)._
6 |
7 | # Comparisons
8 |
9 | - [remotestorage.js](https://community.remotestorage.io/t/659)
10 | - [Webnative SDK](https://talk.fission.codes/t/1587)
11 |
12 | # Long names…
13 |
14 | Yes, it's long and verbose and how I do things generally, but ideally your final code looks like this:
15 |
16 | ```javascript
17 | // write `{"id":"batmobile","clean":true,"washed":"…"}` to /bravo/cars/batmobile.json
18 | await api.alfa.cars.wash({
19 | id: 'batmobile',
20 | });
21 | ```
22 |
23 | # API Guide
24 |
25 | ## Setup
26 |
27 | ```javascript
28 | const api = await zerodatawrap.ZDRWrap({
29 |
30 | // include then pass directly
31 | ZDRParamLibrary: RemoteStorage, // or webnative
32 |
33 | // read/write permissions
34 | ZDRParamScopes: [{
35 |
36 | // code-level identifier
37 | ZDRScopeKey: 'alfa',
38 |
39 | // top-level storage directory
40 | ZDRScopeDirectory: 'bravo',
41 |
42 | }],
43 |
44 | });
45 |
46 | // write `{"foo":"bar"}` to /bravo/charlie.json
47 | await api.alfa.ZDRStorageWriteObject('charlie.json', {
48 | foo: 'bar',
49 | });
50 | ```
51 |
52 | ### ZDRWrap
53 |
54 | | param | type | notes |
55 | |-------|---------|-------|
56 | | ZDRParamLibrary
**Required** | pass `RemoteStorage` or `webnative` or an object conforming to `ZDRClient` | |
57 | | ZDRParamScopes
**Required** | array of `ZDRScope` objects | |
58 | | ZDRParamDispatchError | function | called on network or sync errors |
59 | | ZDRParamDispatchConnected | function | called if linked to a cloud account |
60 | | ZDRParamDispatchOnline | function | called when network is online |
61 | | ZDRParamDispatchOffline | function | called when network is offline |
62 |
63 | ### ZDRScope
64 |
65 | | param | type | notes |
66 | |-------|---------|-------|
67 | | ZDRScopeKey
**Required** | string, non-empty, trimmed | convenience accessor for code only |
68 | | ZDRScopeDirectory
**Required** | string, non-empty, trimmed, no slashes | top-level directory for claiming read/write access |
69 | | ZDRScopeCreatorDirectory | string, non-empty, trimmed | if Fission, sets `permissions.app` instead of `permissions.fs` |
70 | | ZDRScopeSchemas | array of `ZDRSchema` objects | defines model helpers |
71 | | ZDRScopeIsPublic | boolean | use public directory on read/write |
72 |
73 | ## Storage
74 |
75 | ### ZDRStorageWriteObject(path, object)
76 |
77 | Call `JSON.stringify`; write to storage.
78 |
79 | Returns input object.
80 |
81 | ### ZDRStorageWriteFile(path, data, mimetype)
82 |
83 | *`mimetype` used by remoteStorage.*
84 |
85 | Write to storage.
86 |
87 | Returns input.
88 |
89 | ### ZDRStorageReadObject(path)
90 |
91 | Read from storage; call `JSON.parse`.
92 |
93 | Returns object.
94 |
95 | ### ZDRStorageReadFile(path)
96 |
97 | Read from storage.
98 |
99 | Returns data.
100 |
101 | ### ZDRStorageListingObjects(path)
102 |
103 | Read from storage in path directory (non-recursive); group by path.
104 |
105 | Returns key/value object.
106 |
107 | ### ZDRStoragePaths(path)
108 |
109 | Fetch paths (non-recursive).
110 |
111 | Returns array of paths.
112 |
113 | ### ZDRStoragePathsRecursive(path)
114 |
115 | Fetch paths recursively.
116 |
117 | Returns flat array of paths.
118 |
119 | ### ZDRStorageDeleteFile(path)
120 |
121 | Delete from storage.
122 |
123 | Returns null.
124 |
125 | ### ZDRStorageDeleteFolderRecursive(path)
126 |
127 | Delete folder and subcontents recursively from storage.
128 |
129 | Returns input.
130 |
131 | ## Cloud
132 |
133 | ### ZDRCloudConnect(address)
134 |
135 | Start authorization process corresponding to `ZDRParamLibrary`.
136 |
137 | Returns undefined.
138 |
139 | ### ZDRCloudReconnect()
140 |
141 | Retry authorization process in case of expiry or denied access.
142 |
143 | Returns undefined.
144 |
145 | ### ZDRCloudDisconnect()
146 |
147 | Log out.
148 |
149 | Returns undefined.
150 |
151 | ## Model (optional)
152 |
153 | ```javascript
154 | const api = zerodatawrap.ZDRWrap({
155 |
156 | // …
157 |
158 | ZDRParamScopes: [{
159 |
160 | // …
161 |
162 | // map schemas to paths
163 | ZDRScopeSchemas: [{
164 |
165 | // code-level identifier
166 | ZDRSchemaKey: 'cars',
167 |
168 | // path for a given object
169 | ZDRSchemaPath (object) {
170 | return `cars/${ object.id }.json`;
171 | },
172 |
173 | // object information for a given path
174 | ZDRSchemaStub (path) {
175 | return {
176 | id: path.split('/').pop().split('.json').shift(),
177 | };
178 | },
179 |
180 | }],
181 |
182 | // …
183 |
184 | }],
185 |
186 | // …
187 |
188 | });
189 |
190 | // write `{"id":"batmobile"}` to /bravo/cars/batmobile.json
191 | await api.alfa.cars.ZDRModelWriteObject({
192 | id: 'batmobile',
193 | });
194 | ```
195 |
196 | ### ZDRSchema
197 |
198 | | param | type | notes |
199 | |-------|---------|-------|
200 | | ZDRSchemaKey
**Required** | string, non-empty, trimmed | convenience accessor for code only |
201 | | ZDRSchemaPath
**Required** | function | constructs the path for a given object |
202 | | ZDRSchemaStub
**Required** | function | constructs object information for a given path, used for filtering paths in recursion and routing sync events |
203 | | ZDRSchemaMethods | object | defines methods to be accessed from the api interface (bound to `this`) |
204 | | ZDRSchemaDispatchValidate | function | called before `ZDRModelWriteObject` |
205 | | ZDRSchemaDispatchSyncCreate | function | called on remote create *remoteStorage only* |
206 | | ZDRSchemaDispatchSyncUpdate | function | called on remote update *remoteStorage only* |
207 | | ZDRSchemaDispatchSyncDelete | function | called on remote delete *remoteStorage only* |
208 | | ZDRSchemaDispatchSyncConflict | function | called on remote conflict *remoteStorage only*
**Note: this passes the remoteStorage change event directly** |
209 |
210 | ### Specify a validation function
211 |
212 | ```javascript
213 | const api = zerodatawrap.ZDRWrap({
214 |
215 | // …
216 |
217 | ZDRParamScopes: [{
218 |
219 | // …
220 |
221 | ZDRScopeSchemas: [{
222 |
223 | // …
224 |
225 | // truthy values cause a promise rejection
226 | ZDRSchemaDispatchValidate (object) {
227 | if (typeof object.id !== 'string') {
228 | return {
229 | not: 'so fast',
230 | };
231 | }
232 | },
233 |
234 | // …
235 |
236 | }],
237 |
238 | // …
239 |
240 | }],
241 |
242 | // …
243 |
244 | });
245 |
246 | // rejects
247 | try {
248 | await api.alfa.cars.ZDRModelWriteObject({
249 | id: 123,
250 | });
251 | } catch (truthy) {
252 | console.log(truthy.not); // so fast
253 | }
254 | ```
255 |
256 | ### Specify custom methods
257 |
258 | ```javascript
259 | const api = zerodatawrap.ZDRWrap({
260 |
261 | // …
262 |
263 | ZDRParamScopes: [{
264 |
265 | // …
266 |
267 | ZDRScopeSchemas: [{
268 |
269 | // …
270 |
271 | // logic to be done on save
272 | ZDRSchemaMethods: {
273 |
274 | clean (car) {
275 | return this.alfa.cars.ZDRModelWriteObject(Object.assign(car, {
276 | clean: true,
277 | washed: new Date(),
278 | }));
279 | },
280 |
281 | },
282 |
283 | // …
284 |
285 | }],
286 |
287 | // …
288 |
289 | }],
290 |
291 | // …
292 |
293 | });
294 |
295 | // write `{"id":"batmobile","clean":true,"washed":"…"}` to /bravo/cars/batmobile.json
296 | await api.alfa.cars.clean({
297 | id: 'batmobile',
298 | });
299 | ```
300 |
301 | ### Receive object sync notifications
302 |
303 | ```javascript
304 | const api = zerodatawrap.ZDRWrap({
305 |
306 | // …
307 |
308 | ZDRParamScopes: [{
309 |
310 | // …
311 |
312 | ZDRScopeSchemas: [{
313 |
314 | // …
315 |
316 | // update the interface for remote changes
317 | ZDRSchemaDispatchSyncCreate (object) {
318 | console.log('create', object);
319 | },
320 | ZDRSchemaDispatchSyncUpdate (object) {
321 | console.log('update', object);
322 | },
323 | ZDRSchemaDispatchSyncDelete (object) {
324 | console.log('delete', object);
325 | },
326 |
327 | // handle conflict
328 | ZDRSchemaDispatchSyncConflict (event) {
329 | console.log('conflict', event);
330 | },
331 |
332 | // …
333 |
334 | }],
335 |
336 | // …
337 |
338 | }],
339 |
340 | // …
341 |
342 | });
343 | ```
344 |
345 | ### ZDRModelPath(object)
346 |
347 | Returns object path via `ZDRSchemaPath`.
348 |
349 | ### ZDRModelWriteObject(object)
350 |
351 | Validate with `ZDRSchemaDispatchValidate`, reject if truthy; write object to path from `ZDRModelPath`.
352 |
353 | Returns input.
354 |
355 | ### ZDRModelListObjects()
356 |
357 | Read all objects recursively (where paths conform to logic in `ZDRSchema`).
358 |
359 | Returns array of objects.
360 |
361 | ### ZDRModelDeleteObject(object)
362 |
363 | Delete object from storage.
364 |
365 | Returns input.
366 |
367 | ## Multiple protocols
368 |
369 | When supporting multiple protocols, the library can help track which one was selected.
370 |
371 | ```javascript
372 | const api = await zerodatawrap.ZDRWrap({
373 |
374 | ZDRParamLibrary: (function() {
375 | // get the selected protocol, default to `ZDRProtocolCustom`
376 | const selected = zerodatawrap.ZDRPreferenceProtocol(zerodatawrap.ZDRProtocolCustom());
377 |
378 | if (selected === zerodatawrap.ZDRProtocolRemoteStorage()) {
379 | return RemoteStorage;
380 | }
381 |
382 | return {
383 | ZDRClientWriteFile (path, data) {
384 | console.log('custom protocol write', [...arguments]);
385 | },
386 | ZDRClientReadFile (path) {
387 | console.log('custom protocol read', [...arguments]);
388 | },
389 | ZDRClientListObjects (path) {
390 | console.log('custom protocol list objects', [...arguments]);
391 | },
392 | ZDRClientDelete (path) {
393 | console.log('custom protocol delete', [...arguments]);
394 | },
395 | };
396 | })(),
397 |
398 | // …
399 |
400 | });
401 | ```
402 |
403 | Move from one protocol to another by generating APIs from preferences:
404 |
405 | ```javascript
406 | if (zerodatawrap.ZDRPreferenceProtocolMigrate()) {
407 |
408 | // generate apis from protocol
409 | const wrap = function (protocol) {
410 | return zerodatawrap.ZDRWrap({
411 |
412 | // …
413 |
414 | });
415 | };
416 | const source = await wrap(zerodatawrap.ZDRPreferenceProtocolMigrate());
417 | const destination = await wrap(zerodatawrap.ZDRPreferenceProtocol());
418 |
419 | // get all objects (this is simplified, should be recursive)
420 | await Promise.all(Object.entries(await source.App.ZDRStorageListingObjects('')).map(async function ([key, value]) {
421 | // write to destination
422 | await destination.App.ZDRStorageWriteObject(key, value);
423 |
424 | // delete from source
425 | await source.App.ZDRStorageDeleteFile(key);
426 | }));
427 |
428 | // clear migrate preference to avoid repeating
429 | zerodatawrap.ZDRPreferenceProtocolMigrateClear();
430 |
431 | // call disconnect to do any other cleanup
432 | source.ZDRCloudDisconnect();
433 | };
434 | ```
435 |
436 | ### ZDRClient (for custom protocol only)
437 |
438 | | function | notes |
439 | |-------|---------|
440 | | ZDRClientWriteFile
**Required** | called by `ZDRStorageWriteFile` |
441 | | ZDRClientReadFile
**Required** | called by `ZDRStorageReadFile` |
442 | | ZDRClientListObjects
**Required** | called by `ZDRStorageListingObjects` |
443 | | ZDRClientDelete
**Required** | called by `ZDRStorageDeleteFile` |
444 | | ZDRClientPrepare | called before returning wrapper |
445 | | ZDRClientConnect | called by `ZDRCloudConnect` |
446 | | ZDRClientReconnect | called by `ZDRCloudReconnect` |
447 | | ZDRClientDisconnect | called by `ZDRCloudDisconnect` |
448 |
449 | ### ZDRProtocolRemoteStorage()
450 |
451 | Returns string.
452 |
453 | ### ZDRProtocolFission()
454 |
455 | Returns string.
456 |
457 | ### ZDRProtocolCustom()
458 |
459 | Returns string.
460 |
461 | ### ZDRPreferenceProtocol(protocol)
462 |
463 | Stores input as the protocol preference if none is set.
464 |
465 | Returns the protocol preference.
466 |
467 | ### ZDRPreferenceProtocolClear()
468 |
469 | Clears the protocol preference.
470 |
471 | Returns null.
472 |
473 | ### ZDRPreferenceProtocolConnect(protocol)
474 |
475 | Sets the protocol preference as 'to be migrated' if connecting to a different protocol.
476 |
477 | Returns input.
478 |
479 | ### ZDRPreferenceProtocolMigrate()
480 |
481 | Returns the 'to be migrated' protocol if set.
482 |
483 | ### ZDRPreferenceProtocolMigrateClear()
484 |
485 | Clears the 'to be migrated' protocol.
486 |
487 | Returns input object.
488 |
489 | ## ❤️
490 |
491 | Help me keep creating projects that are public, accessible for free, and open-source.
492 |
493 |
494 |
495 | ## License
496 |
497 | The code is released under a [Hippocratic License](https://firstdonoharm.dev), modified to exclude its use for surveillance capitalism and also to require large for-profit entities to purchase a paid license.
498 |
499 | ## Questions
500 |
501 | Feel free to reach out on [Mastodon](https://rosano.ca/mastodon) or [Bluesky](https://rosano.ca/bluesky).
502 |
--------------------------------------------------------------------------------
/main-integrate-remotestorage-tests.js:
--------------------------------------------------------------------------------
1 | const { rejects, deepEqual } = require('assert');
2 |
3 | const mod = require('./main.js');
4 |
5 | const RemoteStorage = require('remotestoragejs');
6 |
7 | describe('_ZDRModelSyncCallbackSignature', function test__ZDRModelSyncCallbackSignature() {
8 |
9 | it('returns undefined', function () {
10 | deepEqual(mod._ZDRModelSyncCallbackSignature(), undefined);
11 | });
12 |
13 | it('returns undefined if window', function () {
14 | deepEqual(mod._ZDRModelSyncCallbackSignature({
15 | origin: 'window',
16 | }), undefined);
17 | });
18 |
19 | it('returns undefined if local init', function () {
20 | deepEqual(mod._ZDRModelSyncCallbackSignature({
21 | origin: 'local',
22 | }), undefined);
23 | });
24 |
25 | it('returns string if remote create', function () {
26 | deepEqual(mod._ZDRModelSyncCallbackSignature({
27 | origin: 'remote',
28 | oldValue: undefined,
29 | newValue: Math.random().toString(),
30 | }), 'ZDRSchemaDispatchSyncCreate');
31 | });
32 |
33 | it('returns string if remote update', function () {
34 | deepEqual(mod._ZDRModelSyncCallbackSignature({
35 | origin: 'remote',
36 | oldValue: Math.random().toString(),
37 | newValue: Math.random().toString(),
38 | }), 'ZDRSchemaDispatchSyncUpdate');
39 | });
40 |
41 | it('returns string if remote delete', function () {
42 | deepEqual(mod._ZDRModelSyncCallbackSignature({
43 | origin: 'remote',
44 | oldValue: Math.random().toString(),
45 | newValue: undefined,
46 | }), 'ZDRSchemaDispatchSyncDelete');
47 | });
48 |
49 | it('returns string if conflict', function () {
50 | deepEqual(mod._ZDRModelSyncCallbackSignature({
51 | origin: 'conflict',
52 | }), 'ZDRSchemaDispatchSyncConflict');
53 | });
54 |
55 | });
56 |
57 | describe('_ZDRWrap_RemoteStorage', function test__ZDRWrap_RemoteStorage() {
58 |
59 | const ZDRScopeDirectory = Date.now().toString();
60 |
61 | const _ZDRStorageRemoteStorage = function (inputData = {}) {
62 | const ZDRScopeKey = inputData.ZDRScopeKey || Math.random().toString();
63 | const _ZDRScopeDirectory = inputData.ZDRScopeDirectory || ZDRScopeDirectory;
64 |
65 | return mod._ZDRWrap(Object.assign({
66 | ZDRParamLibrary: RemoteStorage,
67 | ZDRParamScopes: [uStubScope(Object.assign({
68 | ZDRScopeKey,
69 | ZDRScopeDirectory: _ZDRScopeDirectory,
70 | }, inputData))],
71 | ZDRParamDispatchReady: (function () {}),
72 | }, inputData))[ZDRScopeKey];
73 | };
74 |
75 | it('calls client.access.claim', function () {
76 | const ZDRScopeDirectory = Math.random().toString();
77 |
78 | deepEqual(uCapture(function (capture) {
79 | _ZDRStorageRemoteStorage({
80 | ZDRScopeDirectory,
81 | ZDRParamLibrary: uStubRemoteStorage({
82 | claim: (function () {
83 | capture(...arguments);
84 | }),
85 | }),
86 | });
87 | }), [ZDRScopeDirectory, 'rw']);
88 | });
89 |
90 | it('calls client.caching.enable', function () {
91 | const ZDRScopeDirectory = Math.random().toString();
92 |
93 | deepEqual(uCapture(function (capture) {
94 | _ZDRStorageRemoteStorage({
95 | ZDRScopeDirectory,
96 | ZDRParamLibrary: uStubRemoteStorage({
97 | enable: (function () {
98 | capture(...arguments);
99 | }),
100 | }),
101 | });
102 | }), [`/${ ZDRScopeDirectory }/`]);
103 | });
104 |
105 | context('error', function () {
106 |
107 | it('calls ZDRParamDispatchError', function () {
108 | const item = Math.random().toString();
109 |
110 | deepEqual(uCapture(function (capture) {
111 | _ZDRStorageRemoteStorage({
112 | ZDRParamLibrary: uStubRemoteStorage({
113 | on: (function (param1, param2) {
114 | if (param1 !== 'error') {
115 | return;
116 | }
117 |
118 | return param2(item);
119 | }),
120 | }),
121 | ZDRParamDispatchError: (function () {
122 | capture(...arguments);
123 | }),
124 | });
125 | }), [item]);
126 | });
127 |
128 | it('ignores if offline and sync failed', function () {
129 | deepEqual(uCapture(function (capture) {
130 | _ZDRStorageRemoteStorage({
131 | ZDRParamLibrary: uStubRemoteStorage({
132 | on: (function (param1, param2) {
133 | if (param1 !== 'error') {
134 | return;
135 | }
136 |
137 | return param2(new Error('Sync failed: Network request failed.'));
138 | }),
139 | remote: {
140 | online: false,
141 | },
142 | }),
143 | ZDRParamDispatchError: (function () {
144 | capture(...arguments);
145 | }),
146 | });
147 | }), []);
148 | });
149 |
150 | });
151 |
152 | context('ready', function () {
153 |
154 | it('calls ZDRParamDispatchReady', function () {
155 | const item = Math.random().toString();
156 | deepEqual(uCapture(function (capture) {
157 | _ZDRStorageRemoteStorage({
158 | ZDRParamLibrary: uStubRemoteStorage({
159 | on: (function (param1, param2) {
160 | if (param1 !== 'ready') {
161 | return;
162 | }
163 |
164 | return param2();
165 | }),
166 | }),
167 | ZDRParamDispatchReady: (function () {
168 | capture(item);
169 | }),
170 | });
171 | }), [item]);
172 | });
173 |
174 | });
175 |
176 | context('connected', function () {
177 |
178 | it('calls ZDRParamDispatchConnected', function () {
179 | const userAddress = Math.random().toString();
180 | const token = Math.random().toString();
181 |
182 | deepEqual(uCapture(function (capture) {
183 | mod._ZDRWrap({
184 | ZDRParamLibrary: uStubRemoteStorage({
185 | on: (function (param1, param2) {
186 | if (param1 !== 'connected') {
187 | return;
188 | }
189 |
190 | return param2();
191 | }),
192 | remote: {
193 | userAddress,
194 | token,
195 | },
196 | }),
197 | ZDRParamScopes: [uStubScope()],
198 | ZDRParamDispatchReady: (function () {}),
199 | ZDRParamDispatchConnected: (function () {
200 | capture(...arguments);
201 | }),
202 | });
203 | }), [userAddress, token]);
204 | });
205 |
206 | });
207 |
208 | context('network-online', function () {
209 |
210 | it('calls ZDRParamDispatchOnline', function () {
211 | const item = Math.random().toString();
212 | deepEqual(uCapture(function (capture) {
213 | mod._ZDRWrap({
214 | ZDRParamLibrary: uStubRemoteStorage({
215 | on: (function (param1, param2) {
216 | if (param1 !== 'network-online') {
217 | return;
218 | }
219 |
220 | return param2();
221 | }),
222 | }),
223 | ZDRParamScopes: [uStubScope()],
224 | ZDRParamDispatchOnline: (function () {
225 | capture(item);
226 | }),
227 | ZDRParamDispatchReady: (function () {}),
228 | });
229 | }), [item]);
230 | });
231 |
232 | });
233 |
234 | context('network-offline', function () {
235 |
236 | it('calls ZDRParamDispatchOffline', function () {
237 | const item = Math.random().toString();
238 | deepEqual(uCapture(function (capture) {
239 | mod._ZDRWrap({
240 | ZDRParamLibrary: uStubRemoteStorage({
241 | on: (function (param1, param2) {
242 | if (param1 !== 'network-offline') {
243 | return;
244 | }
245 |
246 | return param2();
247 | }),
248 | }),
249 | ZDRParamScopes: [uStubScope()],
250 | ZDRParamDispatchOffline: (function () {
251 | capture(item);
252 | }),
253 | ZDRParamDispatchReady: (function () {}),
254 | });
255 | }), [item]);
256 | });
257 |
258 | });
259 |
260 | context('sync-done', function () {
261 |
262 | it('calls ZDRParamDispatchSyncDidStop', function () {
263 | const item = Math.random().toString();
264 | deepEqual(uCapture(function (capture) {
265 | mod._ZDRWrap({
266 | ZDRParamLibrary: uStubRemoteStorage({
267 | on: (function (param1, param2) {
268 | if (param1 !== 'sync-done') {
269 | return;
270 | }
271 |
272 | return param2();
273 | }),
274 | }),
275 | ZDRParamScopes: [uStubScope()],
276 | ZDRParamDispatchSyncDidStop: (function () {
277 | capture(item);
278 | }),
279 | ZDRParamDispatchReady: (function () {}),
280 | });
281 | }), [item]);
282 | });
283 |
284 | });
285 |
286 | context('_ZDRStorageBasePath', function test__ZDRStorageBasePath() {
287 |
288 | it('returns inputData', function () {
289 | const item = Math.random().toString();
290 | deepEqual(_ZDRStorageRemoteStorage()._ZDRStorageBasePath(item), item);
291 | });
292 |
293 | it('removes leading slash', function () {
294 | const item = Math.random().toString();
295 | deepEqual(_ZDRStorageRemoteStorage()._ZDRStorageBasePath('/' + item), item);
296 | });
297 |
298 | });
299 |
300 | context('ZDRStorageClient', function test_ZDRStorageClient() {
301 |
302 | it('returns RemoteStorage', function () {
303 | const ZDRScopeDirectory = Math.random().toString();
304 | deepEqual(Object.keys(mod._ZDRWrap({
305 | ZDRParamLibrary: uStubRemoteStorage(),
306 | ZDRParamScopes: [uStubScope({
307 | ZDRScopeDirectory,
308 | })],
309 | ZDRParamDispatchReady: (function () {}),
310 | }).ZDRStorageClient()[ZDRScopeDirectory]), ['privateClient', 'publicClient']);
311 | });
312 |
313 | });
314 |
315 | context('ZDRStorageWriteFile', function test_ZDRStorageWriteFile() {
316 |
317 | it('calls scope.storeFile', async function () {
318 | const param1 = Math.random().toString();
319 | const param2 = Math.random().toString();
320 | const param3 = uStubFilePath();
321 |
322 | const ZDRScopeIsPublic = uRandomElement(true, false);
323 |
324 | await rejects(_ZDRStorageRemoteStorage({
325 | ZDRParamLibrary: uStubRemoteStorage({
326 | storeFile: (function () {
327 | return Promise.reject([...arguments]);
328 | }),
329 | FakePublicClient: ZDRScopeIsPublic,
330 | }),
331 | ZDRScopeIsPublic,
332 | }).ZDRStorageWriteFile(param1, param2, param3), [param3, param1, param2]);
333 | });
334 |
335 | });
336 |
337 | context('ZDRStorageWriteObject', function test_ZDRStorageWriteObject() {
338 |
339 | it('calls scope.storeFile', async function () {
340 | const param1 = Math.random().toString();
341 | const param2 = {
342 | [Math.random().toString()]: Math.random().toString(),
343 | };
344 |
345 | const ZDRScopeIsPublic = uRandomElement(true, false);
346 |
347 | await rejects(_ZDRStorageRemoteStorage({
348 | ZDRParamLibrary: uStubRemoteStorage({
349 | storeFile: (function () {
350 | return Promise.reject([...arguments]);
351 | }),
352 | FakePublicClient: ZDRScopeIsPublic,
353 | }),
354 | ZDRScopeIsPublic,
355 | }).ZDRStorageWriteObject(param1, param2), ['application/json', param1, JSON.stringify(param2)]);
356 | });
357 |
358 | });
359 |
360 | context('ZDRStorageReadFile', function test_ZDRStorageReadFile() {
361 |
362 | it('calls scope.getFile', function () {
363 | const item = Math.random().toString();
364 |
365 | const ZDRScopeIsPublic = uRandomElement(true, false);
366 |
367 | deepEqual(uCapture(function (capture) {
368 | _ZDRStorageRemoteStorage({
369 | ZDRParamLibrary: uStubRemoteStorage({
370 | getFile: capture,
371 | FakePublicClient: ZDRScopeIsPublic,
372 | }),
373 | ZDRScopeIsPublic,
374 | }).ZDRStorageReadFile(item)
375 | }), [item, false]);
376 | });
377 |
378 | });
379 |
380 | context('ZDRStorageReadObject', function test_ZDRStorageReadObject() {
381 |
382 | it('calls scope.getFile', function () {
383 | const item = Math.random().toString();
384 |
385 | const ZDRScopeIsPublic = uRandomElement(true, false);
386 |
387 | deepEqual(uCapture(function (capture) {
388 | _ZDRStorageRemoteStorage({
389 | ZDRParamLibrary: uStubRemoteStorage({
390 | getFile: capture,
391 | FakePublicClient: ZDRScopeIsPublic,
392 | }),
393 | ZDRScopeIsPublic,
394 | }).ZDRStorageReadObject(item)
395 | }), [item, false]);
396 | });
397 |
398 | });
399 |
400 | context('ZDRStorageListingObjects', function test_ZDRStorageListingObjects() {
401 |
402 | const ZDRScopeKey = Date.now().toString();
403 |
404 | it('calls scope.getAll', async function () {
405 | const item = Math.random().toString();
406 |
407 | const ZDRScopeIsPublic = uRandomElement(true, false);
408 |
409 | await rejects(_ZDRStorageRemoteStorage({
410 | ZDRParamLibrary: uStubRemoteStorage({
411 | getAll: (function () {
412 | return Promise.reject([...arguments]);
413 | }),
414 | FakePublicClient: ZDRScopeIsPublic,
415 | }),
416 | ZDRScopeIsPublic,
417 | }).ZDRStorageListingObjects(item), [mod._ZDRPathFormatDirectory(item), false]);
418 | });
419 |
420 | it('excludes folder', async function () {
421 | const client = _ZDRStorageRemoteStorage();
422 |
423 | await client.ZDRStorageWriteObject(Date.now().toString() + '/' + Math.random().toString(), {
424 | [Math.random().toString()]: Math.random().toString(),
425 | });
426 |
427 | deepEqual(await client.ZDRStorageListingObjects(uRandomElement('', '/')), {});
428 | });
429 |
430 | it('excludes file', async function () {
431 | const client = _ZDRStorageRemoteStorage();
432 |
433 | await client.ZDRStorageWriteFile(Math.random().toString(), Math.random().toString(), 'text/plain');
434 |
435 | deepEqual(await client.ZDRStorageListingObjects(uRandomElement('', '/')), {});
436 | });
437 |
438 | it('includes object', async function () {
439 | const path = Math.random().toString();
440 | const object = {
441 | [Math.random().toString()]: Math.random().toString(),
442 | };
443 |
444 | const client = _ZDRStorageRemoteStorage();
445 |
446 | await client.ZDRStorageWriteObject(path, object);
447 |
448 | deepEqual(await client.ZDRStorageListingObjects(uRandomElement('', '/')), {
449 | [path]: object,
450 | });
451 | });
452 |
453 | });
454 |
455 | context('ZDRStoragePaths', function test_ZDRStoragePaths() {
456 |
457 | const ZDRScopeKey = Date.now().toString();
458 |
459 | it('calls scope.getListing', async function () {
460 | const item = Math.random().toString();
461 |
462 | const ZDRScopeIsPublic = uRandomElement(true, false);
463 |
464 | await rejects(_ZDRStorageRemoteStorage({
465 | ZDRParamLibrary: uStubRemoteStorage({
466 | getListing: (function () {
467 | return Promise.reject([...arguments]);
468 | }),
469 | FakePublicClient: ZDRScopeIsPublic,
470 | }),
471 | ZDRScopeIsPublic,
472 | }).ZDRStoragePaths(item), [mod._ZDRPathFormatDirectory(item), false]);
473 | });
474 |
475 | it('converts folder', async function () {
476 | const path = Math.random().toString();
477 |
478 | const client = _ZDRStorageRemoteStorage();
479 |
480 | await client.ZDRStorageWriteObject(path + '/' + Math.random().toString(), {});
481 |
482 | deepEqual(await client.ZDRStoragePaths(uRandomElement('', '/')), [path + '/']);
483 | });
484 |
485 | it('converts file', async function () {
486 | const path = Math.random().toString();
487 |
488 | const client = _ZDRStorageRemoteStorage();
489 |
490 | await client.ZDRStorageWriteFile(path, Math.random().toString(), 'text/plain');
491 |
492 | deepEqual(await client.ZDRStoragePaths(uRandomElement('', '/')), [path]);
493 | });
494 |
495 | it('converts object', async function () {
496 | const path = Math.random().toString();
497 | const object = {
498 | [Math.random().toString()]: Math.random().toString(),
499 | };
500 |
501 | const client = _ZDRStorageRemoteStorage({
502 | ZDRScopeKey,
503 | });
504 |
505 | await client.ZDRStorageWriteObject(path, object);
506 |
507 | deepEqual(await client.ZDRStoragePaths(uRandomElement('', '/')), [path]);
508 | });
509 |
510 | });
511 |
512 | context('ZDRStoragePermalink', function test_ZDRStoragePermalink() {
513 |
514 | it('calls scope.getItemURL', async function () {
515 | const item = Math.random().toString();
516 |
517 | const ZDRScopeIsPublic = uRandomElement(true, false);
518 |
519 | deepEqual(await _ZDRStorageRemoteStorage({
520 | ZDRParamLibrary: uStubRemoteStorage({
521 | getItemURL: (function () {
522 | return [...arguments];
523 | }),
524 | FakePublicClient: ZDRScopeIsPublic,
525 | }),
526 | ZDRScopeIsPublic,
527 | }).ZDRStoragePermalink(item), [item]);
528 | });
529 |
530 | });
531 |
532 | context('ZDRStorageDeleteFile', function test_ZDRStorageDeleteFile() {
533 |
534 | it('calls scope.remove', async function () {
535 | const item = Math.random().toString();
536 |
537 | const ZDRScopeIsPublic = uRandomElement(true, false);
538 |
539 | await rejects(_ZDRStorageRemoteStorage({
540 | ZDRParamLibrary: uStubRemoteStorage({
541 | remove: (function () {
542 | return Promise.reject([...arguments]);
543 | }),
544 | FakePublicClient: ZDRScopeIsPublic,
545 | }),
546 | ZDRScopeIsPublic,
547 | }).ZDRStorageDeleteFile(item), [item]);
548 | });
549 |
550 | });
551 |
552 | context('ZDRCloudConnect', function test_ZDRCloudConnect() {
553 |
554 | it('calls connect', async function () {
555 | const item = Math.random().toString();
556 | await rejects(mod._ZDRWrap({
557 | ZDRParamLibrary: uStubRemoteStorage({
558 | connect: (function () {
559 | return Promise.reject([...arguments]);
560 | }),
561 | }),
562 | ZDRParamScopes: [uStubScope()],
563 | ZDRParamDispatchReady: (function () {}),
564 | }).ZDRCloudConnect(item), [item]);
565 | });
566 |
567 | });
568 |
569 | context('ZDRCloudReconnect', function test_ZDRCloudReconnect() {
570 |
571 | it('calls reconnect', async function () {
572 | const item = Math.random().toString();
573 | await rejects(mod._ZDRWrap({
574 | ZDRParamLibrary: uStubRemoteStorage({
575 | reconnect: (function () {
576 | return Promise.reject([item]);
577 | }),
578 | }),
579 | ZDRParamScopes: [uStubScope()],
580 | ZDRParamDispatchReady: (function () {}),
581 | }).ZDRCloudReconnect(), [item]);
582 | });
583 |
584 | });
585 |
586 | context('ZDRCloudDisconnect', function test_ZDRCloudDisconnect() {
587 |
588 | it('calls disconnect', async function () {
589 | const item = Math.random().toString();
590 |
591 | await rejects(mod._ZDRWrap({
592 | ZDRParamLibrary: uStubRemoteStorage({
593 | disconnect: (function () {
594 | return Promise.reject([item]);
595 | }),
596 | }),
597 | ZDRParamScopes: [uStubScope()],
598 | ZDRParamDispatchReady: (function () {}),
599 | }).ZDRCloudDisconnect(), [item]);
600 | });
601 |
602 | });
603 |
604 | context('change', function () {
605 |
606 | it('skips if no _ZDRModelSyncCallbackSignatures', function () {
607 | deepEqual(uCapture(function (capture) {
608 | _ZDRStorageRemoteStorage({
609 | ZDRParamLibrary: uStubRemoteStorage({
610 | on: (function (param1, param2) {
611 | if (param1 !== 'change') {
612 | return;
613 | }
614 |
615 | capture(...arguments);
616 | }),
617 | }),
618 | });
619 | }), []);
620 | });
621 |
622 | const uChange = function (params = {}) {
623 | return _ZDRStorageRemoteStorage(Object.assign({
624 | ZDRScopeSchemas: [uStubSchema(mod._ZDRModelSyncCallbackSignatures().reduce(function (coll, item) {
625 | return Object.assign(coll, {
626 | [item]: (function () {
627 | capture(...arguments);
628 | }),
629 | }, params);
630 | }, {
631 | ZDRSchemaStub: (function (inputData) {
632 | return Object.fromEntries([inputData.split('.')]);
633 | }),
634 | ZDRSchemaPath: (function (inputData) {
635 | return Object.entries(inputData).pop().join('.');
636 | }),
637 | }))],
638 | ZDRParamLibrary: uStubRemoteStorage({
639 | on: (function (param1, param2) {
640 | if (param1 !== 'change') {
641 | return;
642 | }
643 |
644 | return param2(Object.assign({
645 | origin: params.signature === 'ZDRSchemaDispatchSyncConflict' ? 'conflict' : 'remote',
646 | relativePath: Math.random().toString(),
647 | }, (function (inputData) {
648 | if (params.signature === 'ZDRSchemaDispatchSyncCreate') {
649 | return {
650 | newValue: Math.random().toString(),
651 | };
652 | }
653 |
654 | if (params.signature === 'ZDRSchemaDispatchSyncUpdate') {
655 | return {
656 | oldValue: Math.random().toString(),
657 | newValue: Math.random().toString(),
658 | };
659 | }
660 |
661 | if (params.signature === 'ZDRSchemaDispatchSyncDelete') {
662 | return {
663 | oldValue: Math.random().toString(),
664 | };
665 | }
666 | })()));
667 | }),
668 | }),
669 | }, params));
670 | };
671 |
672 | it('ignores if no match', function () {
673 | const signature = uRandomElement(mod._ZDRModelSyncCallbackSignatures());
674 | deepEqual(uCapture(function (capture) {
675 | uChange({
676 | signature,
677 | ZDRSchemaPath: (function (inputData) {
678 | return Math.random().toString();
679 | }),
680 | });
681 | }), []);
682 | });
683 |
684 | it('ignores if no signature', function () {
685 | deepEqual(uCapture(function (capture) {
686 | uChange({
687 | signature: Math.random().toString(),
688 | });
689 | }), []);
690 | });
691 |
692 | it('ignores if no callback', function () {
693 | const signature = uRandomElement(mod._ZDRModelSyncCallbackSignatures());
694 | deepEqual(uCapture(function (capture) {
695 | uChange({
696 | signature,
697 | [signature]: undefined,
698 | });
699 | }), []);
700 | });
701 |
702 | it('calls callback at signature', function () {
703 | const signature = uRandomElement(mod._ZDRModelSyncCallbackSignatures());
704 | deepEqual(uCapture(function (capture) {
705 | uChange({
706 | signature,
707 | [signature]: (function () {
708 | capture(signature);
709 | }),
710 | });
711 | }), [signature]);
712 | });
713 |
714 | it('calls _ZDRParamDispatchJSONPostParse', function () {
715 | const signature = uRandomElement(mod._ZDRModelSyncCallbackSignatures());
716 | const item = Math.random().toString();
717 | deepEqual(uCapture(function (capture) {
718 | uChange({
719 | _ZDRParamDispatchJSONPostParse: (function () {
720 | return {
721 | [item]: item,
722 | };
723 | }),
724 | signature,
725 | [signature]: capture,
726 | });
727 | }), [{
728 | [item]: item,
729 | }]);
730 | });
731 |
732 | });
733 |
734 | });
735 |
--------------------------------------------------------------------------------
/main.js:
--------------------------------------------------------------------------------
1 | const uFlatten = function (inputData) {
2 | return [].concat.apply([], inputData);
3 | };
4 |
5 | const mod = {
6 |
7 | _ZDRSchemaObjectValidate(inputData) {
8 | if (typeof inputData !== 'object' || inputData === null) {
9 | throw new Error('ZDRErrorInputNotValid');
10 | }
11 |
12 | if (typeof inputData.ZDRSchemaKey !== 'string') {
13 | throw new Error('ZDRErrorInputNotString');
14 | }
15 |
16 | if (!inputData.ZDRSchemaKey.trim()) {
17 | throw new Error('ZDRErrorInputNotFilled');
18 | }
19 |
20 | if (inputData.ZDRSchemaKey.trim() !== inputData.ZDRSchemaKey) {
21 | throw new Error('ZDRErrorInputNotTrimmed');
22 | }
23 |
24 | if (typeof inputData.ZDRSchemaStub !== 'function') {
25 | throw new Error('ZDRErrorInputNotFunction');
26 | }
27 |
28 | if (typeof inputData.ZDRSchemaPath !== 'function') {
29 | throw new Error('ZDRErrorInputNotFunction');
30 | }
31 |
32 | if (inputData.ZDRSchemaMethods !== undefined) {
33 | if (typeof inputData.ZDRSchemaMethods !== 'object' || inputData.ZDRSchemaMethods === null) {
34 | throw new Error('ZDRErrorInputNotObject');
35 | }
36 | }
37 |
38 | if (inputData.ZDRSchemaDispatchValidate !== undefined) {
39 | if (typeof inputData.ZDRSchemaDispatchValidate !== 'function') {
40 | throw new Error('ZDRErrorInputNotFunction');
41 | }
42 | }
43 |
44 | if (inputData.ZDRSchemaDispatchSyncCreate !== undefined) {
45 | if (typeof inputData.ZDRSchemaDispatchSyncCreate !== 'function') {
46 | throw new Error('ZDRErrorInputNotFunction');
47 | }
48 | }
49 |
50 | if (inputData.ZDRSchemaDispatchSyncUpdate !== undefined) {
51 | if (typeof inputData.ZDRSchemaDispatchSyncUpdate !== 'function') {
52 | throw new Error('ZDRErrorInputNotFunction');
53 | }
54 | }
55 |
56 | if (inputData.ZDRSchemaDispatchSyncDelete !== undefined) {
57 | if (typeof inputData.ZDRSchemaDispatchSyncDelete !== 'function') {
58 | throw new Error('ZDRErrorInputNotFunction');
59 | }
60 | }
61 |
62 | if (inputData.ZDRSchemaDispatchSyncConflict !== undefined) {
63 | if (typeof inputData.ZDRSchemaDispatchSyncConflict !== 'function') {
64 | throw new Error('ZDRErrorInputNotFunction');
65 | }
66 | }
67 |
68 | return true;
69 | },
70 |
71 | _ZDRScopeObjectValidate(inputData) {
72 | if (typeof inputData !== 'object' || inputData === null) {
73 | throw new Error('ZDRErrorInputNotValid');
74 | }
75 |
76 | if (typeof inputData.ZDRScopeKey !== 'string') {
77 | throw new Error('ZDRErrorInputNotString');
78 | }
79 |
80 | if (!inputData.ZDRScopeKey.trim()) {
81 | throw new Error('ZDRErrorInputNotFilled');
82 | }
83 |
84 | if (inputData.ZDRScopeKey.trim() !== inputData.ZDRScopeKey) {
85 | throw new Error('ZDRErrorInputNotTrimmed');
86 | }
87 |
88 | if (typeof inputData.ZDRScopeDirectory !== 'string') {
89 | throw new Error('ZDRErrorInputNotString');
90 | }
91 |
92 | if (!inputData.ZDRScopeDirectory.trim()) {
93 | throw new Error('ZDRErrorInputNotFilled');
94 | }
95 |
96 | if (inputData.ZDRScopeDirectory.trim() !== inputData.ZDRScopeDirectory) {
97 | throw new Error('ZDRErrorInputNotTrimmed');
98 | }
99 |
100 | if (inputData.ZDRScopeDirectory.match('/')) {
101 | throw new Error('ZDRErrorInputNotValid');
102 | }
103 |
104 | if (inputData.ZDRScopeSchemas !== undefined) {
105 | if (!Array.isArray(inputData.ZDRScopeSchemas)) {
106 | throw new Error('ZDRErrorInputNotValid');
107 | }
108 | }
109 |
110 | if (inputData.ZDRScopeCreatorDirectory !== undefined) {
111 | if (typeof inputData.ZDRScopeCreatorDirectory !== 'string') {
112 | throw new Error('ZDRErrorInputNotString');
113 | }
114 |
115 | if (!inputData.ZDRScopeCreatorDirectory.trim()) {
116 | throw new Error('ZDRErrorInputNotFilled');
117 | }
118 |
119 | if (inputData.ZDRScopeCreatorDirectory.trim() !== inputData.ZDRScopeCreatorDirectory) {
120 | throw new Error('ZDRErrorInputNotTrimmed');
121 | }
122 | }
123 |
124 | if (inputData.ZDRScopeIsPublic !== undefined) {
125 | if (typeof inputData.ZDRScopeIsPublic !== 'boolean') {
126 | throw new Error('ZDRErrorInputNotBoolean');
127 | }
128 | }
129 |
130 | return true;
131 | },
132 |
133 | _ZDRClientObjectValidate(inputData) {
134 | if (typeof inputData !== 'object' || inputData === null) {
135 | throw new Error('ZDRErrorInputNotValid');
136 | }
137 |
138 | if (typeof inputData.ZDRClientWriteFile !== 'function') {
139 | throw new Error('ZDRErrorInputNotFunction');
140 | }
141 |
142 | if (typeof inputData.ZDRClientReadFile !== 'function') {
143 | throw new Error('ZDRErrorInputNotFunction');
144 | }
145 |
146 | if (typeof inputData.ZDRClientListObjects !== 'function') {
147 | throw new Error('ZDRErrorInputNotFunction');
148 | }
149 |
150 | if (typeof inputData.ZDRClientDelete !== 'function') {
151 | throw new Error('ZDRErrorInputNotFunction');
152 | }
153 |
154 | if (inputData.ZDRClientPrepare !== undefined) {
155 | if (typeof inputData.ZDRClientPrepare !== 'function') {
156 | throw new Error('ZDRErrorInputNotFunction');
157 | }
158 | }
159 |
160 | if (inputData.ZDRClientConnect !== undefined) {
161 | if (typeof inputData.ZDRClientConnect !== 'function') {
162 | throw new Error('ZDRErrorInputNotFunction');
163 | }
164 | }
165 |
166 | if (inputData.ZDRClientReconnect !== undefined) {
167 | if (typeof inputData.ZDRClientReconnect !== 'function') {
168 | throw new Error('ZDRErrorInputNotFunction');
169 | }
170 | }
171 |
172 | if (inputData.ZDRClientDisconnect !== undefined) {
173 | if (typeof inputData.ZDRClientDisconnect !== 'function') {
174 | throw new Error('ZDRErrorInputNotFunction');
175 | }
176 | }
177 |
178 | return true;
179 | },
180 |
181 | _ZDRPathIsDirectory(inputData) {
182 | if (typeof inputData !== 'string') {
183 | throw new Error('ZDRErrorInputNotValid');
184 | }
185 |
186 | return inputData.slice(-1) === '/';
187 | },
188 |
189 | _ZDRPathFormatDirectory(inputData) {
190 | if (typeof inputData !== 'string') {
191 | throw new Error('ZDRErrorInputNotValid');
192 | }
193 |
194 | return mod._ZDRPathIsDirectory(inputData) ? inputData : inputData.concat('/')
195 | },
196 |
197 | _ZDRPathFormatPath(inputData) {
198 | if (typeof inputData !== 'string') {
199 | throw new Error('ZDRErrorInputNotValid');
200 | }
201 |
202 | return inputData[0] === '/' ? inputData : '/'.concat(inputData);
203 | },
204 |
205 | _ZDRModelSyncCallbackSignatures() {
206 | return [
207 | 'ZDRSchemaDispatchSyncCreate',
208 | 'ZDRSchemaDispatchSyncUpdate',
209 | 'ZDRSchemaDispatchSyncDelete',
210 | 'ZDRSchemaDispatchSyncConflict',
211 | ];
212 | },
213 |
214 | _ZDRModelSyncCallbackInput(param1, param2) {
215 | if (!mod._ZDRModelSyncCallbackSignatures().includes(param1)) {
216 | throw new Error('ZDRErrorInputNotValid');
217 | }
218 |
219 | if (!param2.origin) {
220 | throw new Error('ZDRErrorInputNotValid');
221 | }
222 |
223 | if (param1 === 'ZDRSchemaDispatchSyncConflict') {
224 | return param2;
225 | }
226 |
227 | return param2[param1 === 'ZDRSchemaDispatchSyncDelete' ? 'oldValue' : 'newValue'];
228 | },
229 |
230 | _ZDRModelSyncCallbackSignature(inputData) {
231 | if (typeof inputData !== 'object' || inputData === null) {
232 | return;
233 | }
234 |
235 | if (inputData.origin === 'remote' && typeof inputData.oldValue === 'undefined' && typeof inputData.newValue !== 'undefined') {
236 | return 'ZDRSchemaDispatchSyncCreate';
237 | }
238 |
239 | if (inputData.origin === 'remote' && typeof inputData.oldValue !== 'undefined' && typeof inputData.newValue !== 'undefined') {
240 | return 'ZDRSchemaDispatchSyncUpdate';
241 | }
242 |
243 | if (inputData.origin === 'remote' && typeof inputData.oldValue !== 'undefined' && typeof inputData.newValue === 'undefined') {
244 | return 'ZDRSchemaDispatchSyncDelete';
245 | }
246 |
247 | if (inputData.origin === 'conflict') {
248 | return 'ZDRSchemaDispatchSyncConflict';
249 | }
250 |
251 | return;
252 | },
253 |
254 | ZDRProtocolRemoteStorage() {
255 | return 'ZDR_PROTOCOL_REMOTE_STORAGE';
256 | },
257 |
258 | ZDRProtocolCustom() {
259 | return 'ZDR_PROTOCOL_CUSTOM';
260 | },
261 |
262 | _ZDRProtocols() {
263 | return [
264 | mod.ZDRProtocolRemoteStorage(),
265 | mod.ZDRProtocolCustom(),
266 | ];
267 | },
268 |
269 | ZDRProtocolForIdentity(inputData) {
270 | if (typeof inputData !== 'string') {
271 | throw new Error('ZDRErrorInputNotValid');
272 | }
273 |
274 | return mod.ZDRProtocolRemoteStorage();
275 | },
276 |
277 | _ZDRProtocol(inputData) {
278 | if (typeof inputData === 'function' && Object.keys(inputData).includes('Unauthorized')) {
279 | return mod.ZDRProtocolRemoteStorage();
280 | }
281 |
282 | if (!!inputData && typeof inputData === 'object' && inputData.ZDRClientWriteFile && mod._ZDRClientObjectValidate(inputData)) {
283 | return mod.ZDRProtocolCustom();
284 | }
285 |
286 | throw new Error('ZDRErrorInputNotValid');
287 | },
288 |
289 | _ZDRClientInterface(_client, protocol, options) {
290 | return {
291 |
292 | async ClientWriteFile(param1, param2, param3) {
293 | try {
294 | await ({
295 | [mod.ZDRProtocolRemoteStorage()]: (async function () {
296 | return _client.storeFile(param3, param1, typeof Blob !== 'undefined' && param2.constructor === Blob ? await new Promise(function (res, rej) {
297 | const reader = new FileReader();
298 |
299 | reader.onload = function () {
300 | res(reader.result);
301 | };
302 |
303 | reader.readAsArrayBuffer(param2);
304 | }) : param2);
305 | }),
306 | [mod.ZDRProtocolCustom()]: (function () {
307 | return _client.ZDRClientWriteFile(param1, param2, param3);
308 | }),
309 | })[protocol]();
310 | } catch (e) {
311 | if (options.ZDRParamDispatchWriteError) {
312 | return options.ZDRParamDispatchWriteError(e);
313 | }
314 |
315 | throw e;
316 | }
317 |
318 | return param2;
319 | },
320 |
321 | async ClientWriteObject(param1, param2) {
322 | const _this = this;
323 | const writeData = JSON.stringify(options._ZDRParamDispatchJSONPreStringify ? options._ZDRParamDispatchJSONPreStringify(param2) : param2);
324 |
325 | await _this.ClientWriteFile(param1, writeData, 'application/json');
326 |
327 | return param2;
328 | },
329 |
330 | ClientReadFile(inputData) {
331 | return ({
332 | [mod.ZDRProtocolRemoteStorage()]: (async function () {
333 | return ((await _client.getFile(inputData, false)) || {}).data;
334 | }),
335 | [mod.ZDRProtocolCustom()]: (function () {
336 | return _client.ZDRClientReadFile(inputData);
337 | }),
338 | })[protocol]();
339 | },
340 |
341 | async ClientReadObject(inputData) {
342 | const result = await this.ClientReadFile(inputData);
343 |
344 | if (!result) {
345 | return null;
346 | }
347 |
348 | const parsed = JSON.parse(result);
349 | return options._ZDRParamDispatchJSONPostParse ? options._ZDRParamDispatchJSONPostParse(parsed) : parsed;
350 | },
351 |
352 | async ClientListObjects(inputData) {
353 | return Object.fromEntries((await ({
354 | [mod.ZDRProtocolRemoteStorage()]: (async function () {
355 | return Object.entries(await _client.getAll(inputData === '/' ? '' : inputData, false)).filter(function ([key, value]) {
356 | if (mod._ZDRPathIsDirectory(key)) {
357 | return false;
358 | }
359 |
360 | return value !== true;
361 | });
362 | }),
363 | [mod.ZDRProtocolCustom()]: (async function () {
364 | return Object.entries(await _client.ZDRClientListObjects(inputData));
365 | }),
366 | })[protocol]()).map(function ([key, value]) {
367 | return [key, options._ZDRParamDispatchJSONPostParse ? options._ZDRParamDispatchJSONPostParse(value) : value];
368 | }));
369 | },
370 |
371 | async ClientPaths(inputData) {
372 | return await ({
373 | [mod.ZDRProtocolRemoteStorage()]: (async function () {
374 | return Object.keys(await _client.getListing(inputData, false));
375 | }),
376 | [mod.ZDRProtocolCustom()]: (async function () {
377 | return Object.keys(await _client.ZDRClientListObjects(inputData));
378 | }),
379 | })[protocol]();
380 | },
381 |
382 | ClientPermalink(inputData) {
383 | return ({
384 | [mod.ZDRProtocolRemoteStorage()]: (function () {
385 | return _client.getItemURL(inputData);
386 | }),
387 | [mod.ZDRProtocolCustom()]: (function () {
388 | throw new Error('ZDRErrorMethodNotDefined');
389 | }),
390 | })[protocol]();
391 | },
392 |
393 | ClientDelete(inputData) {
394 | return ({
395 | [mod.ZDRProtocolRemoteStorage()]: (function () {
396 | if (mod._ZDRPathIsDirectory(inputData)) {
397 | return null;
398 | }
399 |
400 | return _client.remove(inputData.replace(/^\/+/, ''));
401 | }),
402 | [mod.ZDRProtocolCustom()]: (function () {
403 | return _client.ZDRClientDelete(inputData);
404 | }),
405 | })[protocol]();
406 | },
407 |
408 | };
409 | },
410 |
411 | _ZDRWrap(inputData) {
412 | if (typeof inputData !== 'object' || inputData === null) {
413 | throw new Error('ZDRErrorInputNotValid');
414 | }
415 |
416 | const ZDRStorageProtocol = mod._ZDRProtocol(inputData.ZDRParamLibrary);
417 |
418 | if (!Array.isArray(inputData.ZDRParamScopes) || !inputData.ZDRParamScopes.length) {
419 | throw new Error('ZDRErrorInputNotValid');
420 | }
421 |
422 | const scopes = inputData.ZDRParamScopes.filter(mod._ZDRScopeObjectValidate);
423 |
424 | if (!scopes.length) {
425 | throw new Error('ZDRErrorInputNotValid');
426 | }
427 |
428 | if (typeof inputData.ZDRParamDispatchReady !== 'function') {
429 | throw new Error('ZDRErrorInputNotValid');
430 | }
431 |
432 | if (typeof inputData.ZDRParamDispatchError !== 'undefined') {
433 | if (typeof inputData.ZDRParamDispatchError !== 'function') {
434 | throw new Error('ZDRErrorInputNotValid');
435 | }
436 | }
437 |
438 | if (typeof inputData.ZDRParamDispatchConnected !== 'undefined') {
439 | if (typeof inputData.ZDRParamDispatchConnected !== 'function') {
440 | throw new Error('ZDRErrorInputNotValid');
441 | }
442 | }
443 |
444 | if (typeof inputData.ZDRParamDispatchOnline !== 'undefined') {
445 | if (typeof inputData.ZDRParamDispatchOnline !== 'function') {
446 | throw new Error('ZDRErrorInputNotValid');
447 | }
448 | }
449 |
450 | if (typeof inputData.ZDRParamDispatchOffline !== 'undefined') {
451 | if (typeof inputData.ZDRParamDispatchOffline !== 'function') {
452 | throw new Error('ZDRErrorInputNotValid');
453 | }
454 | }
455 |
456 | if (typeof inputData.ZDRParamDispatchSyncDidStart !== 'undefined') {
457 | if (typeof inputData.ZDRParamDispatchSyncDidStart !== 'function') {
458 | throw new Error('ZDRErrorInputNotValid');
459 | }
460 | }
461 |
462 | if (typeof inputData.ZDRParamDispatchSyncDidStop !== 'undefined') {
463 | if (typeof inputData.ZDRParamDispatchSyncDidStop !== 'function') {
464 | throw new Error('ZDRErrorInputNotValid');
465 | }
466 | }
467 |
468 | if (typeof inputData.ZDRParamDispatchWriteError !== 'undefined') {
469 | if (typeof inputData.ZDRParamDispatchWriteError !== 'function') {
470 | throw new Error('ZDRErrorInputNotValid');
471 | }
472 | }
473 |
474 | if (typeof inputData._ZDRParamDispatchJSONPreStringify !== 'undefined') {
475 | if (typeof inputData._ZDRParamDispatchJSONPreStringify !== 'function') {
476 | throw new Error('ZDRErrorInputNotValid');
477 | }
478 | }
479 |
480 | if (typeof inputData._ZDRParamDispatchJSONPostParse !== 'undefined') {
481 | if (typeof inputData._ZDRParamDispatchJSONPostParse !== 'function') {
482 | throw new Error('ZDRErrorInputNotValid');
483 | }
484 | }
485 |
486 | const library = (function () {
487 | if (ZDRStorageProtocol !== mod.ZDRProtocolRemoteStorage()) {
488 | return inputData.ZDRParamLibrary;
489 | }
490 |
491 | return new(inputData.ZDRParamLibrary)({
492 | modules: scopes.reduce(function (coll, item) {
493 | return coll.concat({
494 | name: item.ZDRScopeDirectory,
495 | builder: (function (privateClient, publicClient) {
496 | return {
497 | exports: {
498 | privateClient,
499 | publicClient,
500 | },
501 | };
502 | }),
503 | });
504 | }, [])
505 | });
506 | })();
507 |
508 | if (ZDRStorageProtocol === mod.ZDRProtocolRemoteStorage()) {
509 | library.on('error', function (error) {
510 | if (!library.remote.online && error.message === 'Sync failed: Network request failed.') {
511 | return;
512 | }
513 |
514 | inputData.ZDRParamDispatchError && inputData.ZDRParamDispatchError(error);
515 | });
516 |
517 | library.on('connected', function () {
518 | inputData.ZDRParamDispatchConnected && inputData.ZDRParamDispatchConnected(library.remote.userAddress, library.remote.token);
519 | });
520 |
521 | library.on('network-online', function () {
522 | inputData.ZDRParamDispatchOnline && inputData.ZDRParamDispatchOnline();
523 | });
524 |
525 | library.on('network-offline', function () {
526 | inputData.ZDRParamDispatchOffline && inputData.ZDRParamDispatchOffline();
527 | });
528 |
529 | library.on('sync-done', function () {
530 | inputData.ZDRParamDispatchSyncDidStop && inputData.ZDRParamDispatchSyncDidStop();
531 | });
532 |
533 | library.on('ready', function () {
534 | inputData.ZDRParamDispatchReady();
535 | });
536 | }
537 |
538 | if (ZDRStorageProtocol === mod.ZDRProtocolCustom()) {
539 | Promise.resolve((library.ZDRClientPrepare || function () {})()).then(inputData.ZDRParamDispatchReady);
540 | }
541 |
542 | const outputData = {
543 |
544 | ZDRStorageProtocol,
545 |
546 | ZDRStorageClient() {
547 | return ({
548 | [mod.ZDRProtocolRemoteStorage()]: (function () {
549 | return library;
550 | }),
551 | [mod.ZDRProtocolCustom()]: (function () {
552 | return inputData.ZDRParamLibrary;
553 | }),
554 | })[ZDRStorageProtocol]();
555 | },
556 |
557 | ZDRCloudConnect(inputData) {
558 | if (typeof inputData !== 'string') {
559 | throw new Error('ZDRErrorInputNotValid');
560 | }
561 |
562 | return ({
563 | [mod.ZDRProtocolRemoteStorage()]: (function () {
564 | return library.connect(inputData);
565 | }),
566 | [mod.ZDRProtocolCustom()]: (function () {
567 | return library.ZDRClientConnect(inputData);
568 | }),
569 | })[ZDRStorageProtocol]();
570 | },
571 |
572 | ZDRCloudReconnect() {
573 | return ({
574 | [mod.ZDRProtocolRemoteStorage()]: (function () {
575 | return library.reconnect(inputData);
576 | }),
577 | [mod.ZDRProtocolCustom()]: (function () {
578 | return !library.ZDRClientReconnect ? library.ZDRClientConnect() : library.ZDRClientReconnect();
579 | }),
580 | })[ZDRStorageProtocol]();
581 | },
582 |
583 | ZDRCloudDisconnect() {
584 | return ({
585 | [mod.ZDRProtocolRemoteStorage()]: (function () {
586 | return library.disconnect(inputData);
587 | }),
588 | [mod.ZDRProtocolCustom()]: (function () {
589 | return library.ZDRClientDisconnect(inputData);
590 | }),
591 | })[ZDRStorageProtocol]();
592 | },
593 |
594 | };
595 |
596 | return scopes.reduce(function (coll, item) {
597 | if (ZDRStorageProtocol === mod.ZDRProtocolRemoteStorage()) {
598 | library.access.claim(item.ZDRScopeDirectory, 'rw');
599 |
600 | library.caching.enable(`/${ item.ZDRScopeDirectory }/`);
601 | }
602 |
603 | const schemas = (item.ZDRScopeSchemas || []).filter(mod._ZDRSchemaObjectValidate);
604 |
605 | const _client = {
606 | [mod.ZDRProtocolRemoteStorage()]: (function () {
607 | return library[item.ZDRScopeDirectory][item.ZDRScopeIsPublic ? 'publicClient' : 'privateClient'];
608 | }),
609 | [mod.ZDRProtocolCustom()]: (function () {
610 | return library;
611 | }),
612 | }[ZDRStorageProtocol]();
613 | const client = mod._ZDRClientInterface(_client, ZDRStorageProtocol, inputData);
614 |
615 | if (ZDRStorageProtocol === mod.ZDRProtocolRemoteStorage() && schemas.filter(function (e) {
616 | return Object.keys(e).filter(function (e) {
617 | return mod._ZDRModelSyncCallbackSignatures().includes(e);
618 | }).length;
619 | }).length) {
620 | _client.on('change', function (event) {
621 | const signature = mod._ZDRModelSyncCallbackSignature(event);
622 |
623 | if (!signature) {
624 | return;
625 | }
626 |
627 | schemas.forEach(function (e) {
628 | if (e.ZDRSchemaPath(e.ZDRSchemaStub(event.relativePath)) !== event.relativePath) {
629 | return;
630 | }
631 |
632 | if (!e[signature]) {
633 | return;
634 | }
635 |
636 | const outputData = mod._ZDRModelSyncCallbackInput(signature, event);
637 | return e[signature](inputData._ZDRParamDispatchJSONPostParse ? inputData._ZDRParamDispatchJSONPostParse(outputData) : outputData);
638 | });
639 | });
640 | }
641 |
642 | const _ZDRStorageBasePath = function (inputData, pretty = false) {
643 | if (typeof inputData !== 'string') {
644 | throw new Error('ZDRErrorInputNotValid');
645 | }
646 |
647 | return ((ZDRStorageProtocol === 'mod.ZDRProtocolFission()' ? `/${ pretty ? 'p' : (item.ZDRScopeIsPublic ? 'public' : 'private') }/${ item.ZDRScopeCreatorDirectory ? `Apps/${ item.ZDRScopeCreatorDirectory }/${ item.ZDRScopeDirectory }` : item.ZDRScopeDirectory }/` : '') + inputData).slice(ZDRStorageProtocol === mod.ZDRProtocolRemoteStorage() && inputData[0] === '/' ? 1 : 0);
648 | };
649 |
650 | return Object.assign(coll, {
651 | [item.ZDRScopeKey]: Object.assign({
652 |
653 | _ZDRStorageBasePath,
654 |
655 | ZDRStorageWriteFile(param1, param2, param3) {
656 | if (typeof param1 !== 'string') {
657 | throw new Error('ZDRErrorInputNotValid');
658 | }
659 |
660 | if (typeof param3 !== 'string') {
661 | throw new Error('ZDRErrorInputNotValid');
662 | }
663 |
664 | return client.ClientWriteFile(_ZDRStorageBasePath(param1), param2, param3);
665 | },
666 |
667 | ZDRStorageWriteObject(param1, param2) {
668 | if (typeof param1 !== 'string') {
669 | throw new Error('ZDRErrorInputNotValid');
670 | }
671 |
672 | if (typeof param2 !== 'object' || param2 === null) {
673 | throw new Error('ZDRErrorInputNotValid');
674 | }
675 |
676 | return client.ClientWriteObject(_ZDRStorageBasePath(param1), param2);
677 | },
678 |
679 | ZDRStorageReadFile(inputData) {
680 | if (typeof inputData !== 'string') {
681 | throw new Error('ZDRErrorInputNotValid');
682 | }
683 |
684 | return client.ClientReadFile(_ZDRStorageBasePath(inputData));
685 | },
686 |
687 | ZDRStorageReadObject(inputData) {
688 | if (typeof inputData !== 'string') {
689 | throw new Error('ZDRErrorInputNotValid');
690 | }
691 |
692 | return client.ClientReadObject(_ZDRStorageBasePath(inputData));
693 | },
694 |
695 | ZDRStorageListingObjects(inputData) {
696 | if (typeof inputData !== 'string') {
697 | throw new Error('ZDRErrorInputNotValid');
698 | }
699 |
700 | return client.ClientListObjects(mod._ZDRPathFormatDirectory(_ZDRStorageBasePath(inputData)));
701 | },
702 |
703 | _ZDRStoragePaths(inputData) {
704 | return client.ClientPaths(_ZDRStorageBasePath(inputData));
705 | },
706 |
707 | ZDRStoragePaths(inputData) {
708 | if (typeof inputData !== 'string') {
709 | throw new Error('ZDRErrorInputNotValid');
710 | }
711 |
712 | return this._ZDRStoragePaths(mod._ZDRPathFormatDirectory(inputData));
713 | },
714 |
715 | async _ZDRStoragePathsRecursive(inputData, includeFolders = false) {
716 | const _this = this;
717 | return uFlatten(await Promise.all((await _this.ZDRStoragePaths(inputData)).map(function (e) {
718 | return mod._ZDRPathIsDirectory(e) ? _this._ZDRStoragePathsRecursive(inputData + e, includeFolders) : inputData + e;
719 | }))).concat(includeFolders ? inputData : []);
720 | },
721 |
722 | ZDRStoragePathsRecursive(inputData, includeFolders = false) {
723 | if (typeof inputData !== 'string') {
724 | throw new Error('ZDRErrorInputNotValid');
725 | }
726 |
727 | if (typeof includeFolders !== 'undefined') {
728 | if (typeof includeFolders !== 'boolean') {
729 | throw new Error('ZDRErrorInputNotValid');
730 | }
731 | }
732 |
733 | return this._ZDRStoragePathsRecursive(mod._ZDRPathFormatDirectory(inputData), includeFolders);
734 | },
735 |
736 | ZDRStoragePermalink(inputData) {
737 | if (typeof inputData !== 'string') {
738 | throw new Error('ZDRErrorInputNotValid');
739 | }
740 |
741 | return client.ClientPermalink(_ZDRStorageBasePath(inputData, true));
742 | },
743 |
744 | _ZDRStorageDeleteFile(inputData) {
745 | return client.ClientDelete(inputData);
746 | },
747 |
748 | ZDRStorageDeleteFile(inputData) {
749 | if (typeof inputData !== 'string') {
750 | throw new Error('ZDRErrorInputNotValid');
751 | }
752 |
753 | return client.ClientDelete(_ZDRStorageBasePath(inputData));
754 | },
755 |
756 | async ZDRStorageDeleteFolderRecursive(inputData) {
757 | if (typeof inputData !== 'string') {
758 | throw new Error('ZDRErrorInputNotValid');
759 | }
760 |
761 | const _this = this._ZDRStoragePathsRecursive ? this : coll[item.ZDRScopeKey];
762 |
763 | await Promise.all((await _this._ZDRStoragePathsRecursive(mod._ZDRPathFormatDirectory(inputData))).map(_ZDRStorageBasePath).map(_this._ZDRStorageDeleteFile));
764 |
765 | return inputData;
766 | },
767 |
768 | }, schemas.reduce(function (map, model) {
769 | return Object.assign(map, {
770 | [model.ZDRSchemaKey]: Object.assign({
771 |
772 | ZDRModelPath(inputData) {
773 | if (typeof inputData !== 'object' || inputData === null) {
774 | throw new Error('ZDRErrorInputNotValid');
775 | }
776 |
777 | return model.ZDRSchemaPath(...arguments);
778 | },
779 |
780 | ZDRModelWriteObject(inputData) {
781 | if (model.ZDRSchemaDispatchValidate) {
782 | const outputData = model.ZDRSchemaDispatchValidate(...arguments);
783 |
784 | if (outputData) {
785 | return Promise.reject(outputData);
786 | }
787 | }
788 |
789 | return coll[item.ZDRScopeKey].ZDRStorageWriteObject(mod._ZDRPathFormatPath(map[model.ZDRSchemaKey].ZDRModelPath(...arguments)), inputData);
790 | },
791 |
792 | async _ZDRModelListObjects() {
793 | const _this = this;
794 |
795 | return (await coll[item.ZDRScopeKey].ZDRStoragePathsRecursive('/')).filter(function (e) {
796 | return mod._ZDRPathFormatPath(e) === mod._ZDRPathFormatPath(_this.ZDRModelPath(model.ZDRSchemaStub(e)));
797 | });
798 | },
799 |
800 | async ZDRModelListObjects() {
801 | return Promise.all((await this._ZDRModelListObjects()).map(coll[item.ZDRScopeKey].ZDRStorageReadObject));
802 | },
803 |
804 | async ZDRModelDeleteObject(inputData) {
805 | await coll[item.ZDRScopeKey].ZDRStorageDeleteFile(mod._ZDRPathFormatPath(map[model.ZDRSchemaKey].ZDRModelPath(inputData)));
806 |
807 | return inputData;
808 | },
809 |
810 | }, Object.entries(model.ZDRSchemaMethods || {}).reduce(function (coll, [key, value]) {
811 | if (typeof value !== 'function') {
812 | throw new Error('ZDRErrorInputNotFunction');
813 | }
814 |
815 | return Object.assign(coll, {
816 | [key]: value.bind(outputData),
817 | });
818 | }, {})),
819 | });
820 | }, {})),
821 | });
822 | }, outputData);
823 | },
824 |
825 | ZDRWrap(inputData = {}) {
826 | const _this = this;
827 | return new Promise(async function (res, rej) {
828 | try {
829 | const outputData = _this._ZDRWrap(Object.assign(inputData, {
830 | ZDRParamDispatchReady: (function () {
831 | setTimeout(function () {
832 | return res(outputData);
833 | });
834 | }),
835 | }));
836 | } catch (error) {
837 | rej(error);
838 | }
839 | });
840 | },
841 |
842 | ZDRPreferenceProtocol(inputData, _localStorage) {
843 | if (!mod._ZDRProtocols().includes(inputData)) {
844 | throw new Error('ZDRErrorInputNotValid');
845 | }
846 |
847 | const api = typeof localStorage === 'object' ? localStorage : _localStorage;
848 | if (!api.getItem('ZDR_PREFERENCE_PROTOCOL')) {
849 | api.setItem('ZDR_PREFERENCE_PROTOCOL', inputData);
850 | }
851 |
852 | return api.getItem('ZDR_PREFERENCE_PROTOCOL');
853 | },
854 |
855 | ZDRPreferenceProtocolClear(_localStorage) {
856 | return (typeof localStorage === 'object' ? localStorage : _localStorage).removeItem('ZDR_PREFERENCE_PROTOCOL');
857 | },
858 |
859 | ZDRPreferenceProtocolMigrate(_localStorage) {
860 | return (typeof localStorage === 'object' ? localStorage : _localStorage).getItem('ZDR_PREFERENCE_PROTOCOL_MIGRATE');
861 | },
862 |
863 | ZDRPreferenceProtocolMigrateClear(_localStorage) {
864 | return (typeof localStorage === 'object' ? localStorage : _localStorage).removeItem('ZDR_PREFERENCE_PROTOCOL_MIGRATE');
865 | },
866 |
867 | ZDRPreferenceProtocolConnect(inputData, _localStorage) {
868 | const protocol = this.ZDRProtocolForIdentity(inputData);
869 |
870 | const api = typeof localStorage === 'object' ? localStorage : _localStorage;
871 |
872 | if (api.getItem('ZDR_PREFERENCE_PROTOCOL') && (api.getItem('ZDR_PREFERENCE_PROTOCOL') !== protocol)) {
873 | api.setItem('ZDR_PREFERENCE_PROTOCOL_MIGRATE', api.getItem('ZDR_PREFERENCE_PROTOCOL'));
874 | }
875 |
876 | api.setItem('ZDR_PREFERENCE_PROTOCOL', protocol);
877 |
878 | return protocol;
879 | },
880 |
881 | ZDRLauncherFakeItemProxy() {
882 | return {
883 | LCHRecipeName: 'ZDRLauncherFakeItemProxy',
884 | LCHRecipeCallback() {},
885 | };
886 | },
887 |
888 | ZDRLauncherItemFakeDispatchError(inputData) {
889 | if (typeof inputData !== 'object' || inputData === null) {
890 | throw new Error('OLSKErrorInputNotValid');
891 | }
892 |
893 | return {
894 | LCHRecipeName: 'ZDRLauncherItemFakeDispatchError',
895 | LCHRecipeCallback() {
896 | return inputData.ZDRParamDispatchError(new Error('ZDR_FAKE_CLOUD_ERROR'));
897 | },
898 | };
899 | },
900 |
901 | ZDRLauncherItemFakeDispatchWriteError(inputData) {
902 | if (typeof inputData !== 'object' || inputData === null) {
903 | throw new Error('OLSKErrorInputNotValid');
904 | }
905 |
906 | return {
907 | LCHRecipeName: 'ZDRLauncherItemFakeDispatchWriteError',
908 | LCHRecipeCallback() {
909 | return inputData.ZDRParamDispatchWriteError(new Error('ZDR_FAKE_WRITE_ERROR'));
910 | },
911 | };
912 | },
913 |
914 | ZDRLauncherItemFakeDispatchConnected(inputData) {
915 | if (typeof inputData !== 'object' || inputData === null) {
916 | throw new Error('OLSKErrorInputNotValid');
917 | }
918 |
919 | return {
920 | LCHRecipeName: 'ZDRLauncherItemFakeDispatchConnected',
921 | LCHRecipeCallback() {
922 | return inputData.ZDRParamDispatchConnected('ZDR_FAKE_CLOUD_IDENTITY', 'ZDR_FAKE_CLOUD_TOKEN');
923 | },
924 | };
925 | },
926 |
927 | ZDRLauncherItemFakeDispatchOnline(inputData) {
928 | if (typeof inputData !== 'object' || inputData === null) {
929 | throw new Error('OLSKErrorInputNotValid');
930 | }
931 |
932 | return {
933 | LCHRecipeName: 'ZDRLauncherItemFakeDispatchOnline',
934 | LCHRecipeCallback() {
935 | return inputData.ZDRParamDispatchOnline();
936 | },
937 | };
938 | },
939 |
940 | ZDRLauncherItemFakeDispatchOffline(inputData) {
941 | if (typeof inputData !== 'object' || inputData === null) {
942 | throw new Error('OLSKErrorInputNotValid');
943 | }
944 |
945 | return {
946 | LCHRecipeName: 'ZDRLauncherItemFakeDispatchOffline',
947 | LCHRecipeCallback() {
948 | return inputData.ZDRParamDispatchOffline();
949 | },
950 | };
951 | },
952 |
953 | ZDRLauncherItemFakeDispatchSyncDidStart(inputData) {
954 | if (typeof inputData !== 'object' || inputData === null) {
955 | throw new Error('OLSKErrorInputNotValid');
956 | }
957 |
958 | return {
959 | LCHRecipeName: 'ZDRLauncherItemFakeDispatchSyncDidStart',
960 | LCHRecipeCallback() {
961 | return inputData.ZDRParamDispatchSyncDidStart();
962 | },
963 | };
964 | },
965 |
966 | ZDRLauncherItemFakeDispatchSyncDidStop(inputData) {
967 | if (typeof inputData !== 'object' || inputData === null) {
968 | throw new Error('OLSKErrorInputNotValid');
969 | }
970 |
971 | return {
972 | LCHRecipeName: 'ZDRLauncherItemFakeDispatchSyncDidStop',
973 | LCHRecipeCallback() {
974 | return inputData.ZDRParamDispatchSyncDidStop();
975 | },
976 | };
977 | },
978 |
979 | ZDRLauncherItemFakeDispatchDisconnected(inputData) {
980 | if (typeof inputData !== 'object' || inputData === null) {
981 | throw new Error('OLSKErrorInputNotValid');
982 | }
983 |
984 | return {
985 | LCHRecipeName: 'ZDRLauncherItemFakeDispatchDisconnected',
986 | LCHRecipeCallback() {
987 | return inputData.ZDRParamDispatchConnected(null);
988 | },
989 | };
990 | },
991 |
992 | ZDRRecipes(params) {
993 | if (typeof params !== 'object' || params === null) {
994 | throw new Error('OLSKErrorInputNotValid');
995 | }
996 |
997 | if (typeof params.ParamMod !== 'object' || params.ParamMod === null) {
998 | throw new Error('OLSKErrorInputNotValid');
999 | }
1000 |
1001 | if (typeof params.ParamSpecUI !== 'boolean') {
1002 | throw new Error('OLSKErrorInputNotValid');
1003 | }
1004 |
1005 | return [
1006 | mod.ZDRLauncherFakeItemProxy(),
1007 | mod.ZDRLauncherItemFakeDispatchError(params.ParamMod),
1008 | mod.ZDRLauncherItemFakeDispatchWriteError(params.ParamMod),
1009 | mod.ZDRLauncherItemFakeDispatchConnected(params.ParamMod),
1010 | mod.ZDRLauncherItemFakeDispatchOnline(params.ParamMod),
1011 | mod.ZDRLauncherItemFakeDispatchOffline(params.ParamMod),
1012 | mod.ZDRLauncherItemFakeDispatchSyncDidStart(params.ParamMod),
1013 | mod.ZDRLauncherItemFakeDispatchSyncDidStop(params.ParamMod),
1014 | mod.ZDRLauncherItemFakeDispatchDisconnected(params.ParamMod),
1015 | ].filter(function (e) {
1016 | if (params.ParamSpecUI) {
1017 | return true;
1018 | }
1019 |
1020 | return !(e.LCHRecipeSignature || e.LCHRecipeName).match(/Fake/);
1021 | });
1022 | },
1023 |
1024 | };
1025 |
1026 | Object.assign(exports, mod);
1027 |
--------------------------------------------------------------------------------
/main-tests.js:
--------------------------------------------------------------------------------
1 | const { throws, rejects, deepEqual } = require('assert');
2 |
3 | const mod = require('./main.js');
4 |
5 | describe('_ZDRSchemaObjectValidate', function test__ZDRSchemaObjectValidate() {
6 |
7 | const __ZDRSchemaObjectValidate = function (inputData = {}) {
8 | return mod._ZDRSchemaObjectValidate(uStubSchema(inputData));
9 | };
10 |
11 | it('throws if not object', function () {
12 | throws(function () {
13 | mod._ZDRSchemaObjectValidate(null);
14 | }, /ZDRErrorInputNotValid/);
15 | });
16 |
17 | it('throws if ZDRSchemaKey not string', function () {
18 | throws(function () {
19 | __ZDRSchemaObjectValidate({
20 | ZDRSchemaKey: null,
21 | });
22 | }, /ZDRErrorInputNotString/);
23 | });
24 |
25 | it('throws if ZDRSchemaKey not filled', function () {
26 | throws(function () {
27 | __ZDRSchemaObjectValidate({
28 | ZDRSchemaKey: ' ',
29 | });
30 | }, /ZDRErrorInputNotFilled/);
31 | });
32 |
33 | it('throws if ZDRSchemaKey not trimmed', function () {
34 | throws(function () {
35 | __ZDRSchemaObjectValidate({
36 | ZDRSchemaKey: ' ' + Math.random().toString() + ' ',
37 | });
38 | }, /ZDRErrorInputNotTrimmed/);
39 | });
40 |
41 | it('throws if ZDRSchemaStub not function', function () {
42 | throws(function () {
43 | __ZDRSchemaObjectValidate({
44 | ZDRSchemaStub: null,
45 | });
46 | }, /ZDRErrorInputNotFunction/);
47 | });
48 |
49 | it('throws if ZDRSchemaPath not function', function () {
50 | throws(function () {
51 | __ZDRSchemaObjectValidate({
52 | ZDRSchemaPath: null,
53 | });
54 | }, /ZDRErrorInputNotFunction/);
55 | });
56 |
57 | it('returns true', function () {
58 | deepEqual(__ZDRSchemaObjectValidate(), true);
59 | });
60 |
61 | it('throws if ZDRSchemaMethods not object', function () {
62 | throws(function () {
63 | __ZDRSchemaObjectValidate({
64 | ZDRSchemaMethods: null,
65 | });
66 | }, /ZDRErrorInputNotObject/);
67 | });
68 |
69 | it('throws if ZDRSchemaDispatchValidate not function', function () {
70 | throws(function () {
71 | __ZDRSchemaObjectValidate({
72 | ZDRSchemaDispatchValidate: null,
73 | });
74 | }, /ZDRErrorInputNotFunction/);
75 | });
76 |
77 | it('throws if ZDRSchemaDispatchSyncCreate not function', function () {
78 | throws(function () {
79 | __ZDRSchemaObjectValidate({
80 | ZDRSchemaDispatchSyncCreate: null,
81 | });
82 | }, /ZDRErrorInputNotFunction/);
83 | });
84 |
85 | it('throws if ZDRSchemaDispatchSyncUpdate not function', function () {
86 | throws(function () {
87 | __ZDRSchemaObjectValidate({
88 | ZDRSchemaDispatchSyncUpdate: null,
89 | });
90 | }, /ZDRErrorInputNotFunction/);
91 | });
92 |
93 | it('throws if ZDRSchemaDispatchSyncDelete not function', function () {
94 | throws(function () {
95 | __ZDRSchemaObjectValidate({
96 | ZDRSchemaDispatchSyncDelete: null,
97 | });
98 | }, /ZDRErrorInputNotFunction/);
99 | });
100 |
101 | it('throws if ZDRSchemaDispatchSyncConflict not function', function () {
102 | throws(function () {
103 | __ZDRSchemaObjectValidate({
104 | ZDRSchemaDispatchSyncConflict: null,
105 | });
106 | }, /ZDRErrorInputNotFunction/);
107 | });
108 |
109 | });
110 |
111 | describe('_ZDRScopeObjectValidate', function test__ZDRScopeObjectValidate() {
112 |
113 | it('throws if not object', function () {
114 | throws(function () {
115 | mod._ZDRScopeObjectValidate(null);
116 | }, /ZDRErrorInputNotValid/);
117 | });
118 |
119 | it('throws if ZDRScopeKey not string', function () {
120 | throws(function () {
121 | mod._ZDRScopeObjectValidate(uStubScope({
122 | ZDRScopeKey: null,
123 | }));
124 | }, /ZDRErrorInputNotString/);
125 | });
126 |
127 | it('throws if ZDRScopeKey not filled', function () {
128 | throws(function () {
129 | mod._ZDRScopeObjectValidate(uStubScope({
130 | ZDRScopeKey: ' ',
131 | }));
132 | }, /ZDRErrorInputNotFilled/);
133 | });
134 |
135 | it('throws if ZDRScopeKey not trimmed', function () {
136 | throws(function () {
137 | mod._ZDRScopeObjectValidate(uStubScope({
138 | ZDRScopeKey: ' ' + Math.random().toString() + ' ',
139 | }));
140 | }, /ZDRErrorInputNotTrimmed/);
141 | });
142 |
143 | it('throws if ZDRScopeDirectory not string', function () {
144 | throws(function () {
145 | mod._ZDRScopeObjectValidate(uStubScope({
146 | ZDRScopeDirectory: null,
147 | }));
148 | }, /ZDRErrorInputNotString/);
149 | });
150 |
151 | it('throws if ZDRScopeDirectory not filled', function () {
152 | throws(function () {
153 | mod._ZDRScopeObjectValidate(uStubScope({
154 | ZDRScopeDirectory: ' ',
155 | }));
156 | }, /ZDRErrorInputNotFilled/);
157 | });
158 |
159 | it('throws if ZDRScopeDirectory not trimmed', function () {
160 | throws(function () {
161 | mod._ZDRScopeObjectValidate(uStubScope({
162 | ZDRScopeDirectory: ' ' + Math.random().toString() + ' ',
163 | }));
164 | }, /ZDRErrorInputNotTrimmed/);
165 | });
166 |
167 | it('throws if ZDRScopeDirectory contains slash', function () {
168 | throws(function () {
169 | mod._ZDRScopeObjectValidate(uStubScope({
170 | ZDRScopeDirectory: Math.random().toString() + '/' + Math.random().toString(),
171 | }));
172 | }, /ZDRErrorInputNotValid/);
173 | });
174 |
175 | it('returns true', function () {
176 | deepEqual(mod._ZDRScopeObjectValidate(uStubScope()), true);
177 | });
178 |
179 | it('throws if ZDRScopeSchemas not array', function () {
180 | throws(function () {
181 | mod._ZDRScopeObjectValidate(uStubScope({
182 | ZDRScopeSchemas: null,
183 | }));
184 | }, /ZDRErrorInputNotValid/);
185 | });
186 |
187 | it('throws if ZDRScopeCreatorDirectory not string', function () {
188 | throws(function () {
189 | mod._ZDRScopeObjectValidate(uStubScope({
190 | ZDRScopeCreatorDirectory: null,
191 | }));
192 | }, /ZDRErrorInputNotString/);
193 | });
194 |
195 | it('throws if ZDRScopeCreatorDirectory not filled', function () {
196 | throws(function () {
197 | mod._ZDRScopeObjectValidate(uStubScope({
198 | ZDRScopeCreatorDirectory: ' ',
199 | }));
200 | }, /ZDRErrorInputNotFilled/);
201 | });
202 |
203 | it('throws if ZDRScopeCreatorDirectory not trimmed', function () {
204 | throws(function () {
205 | mod._ZDRScopeObjectValidate(uStubScope({
206 | ZDRScopeCreatorDirectory: ' ' + Math.random().toString() + ' ',
207 | }));
208 | }, /ZDRErrorInputNotTrimmed/);
209 | });
210 |
211 | it('throws if ZDRScopeIsPublic not boolean', function () {
212 | throws(function () {
213 | mod._ZDRScopeObjectValidate(uStubScope({
214 | ZDRScopeIsPublic: null,
215 | }));
216 | }, /ZDRErrorInputNotBoolean/);
217 | });
218 |
219 | });
220 |
221 | describe('_ZDRClientObjectValidate', function test__ZDRClientObjectValidate() {
222 |
223 | it('throws if not object', function () {
224 | throws(function () {
225 | mod._ZDRClientObjectValidate(null);
226 | }, /ZDRErrorInputNotValid/);
227 | });
228 |
229 | it('throws if ZDRClientWriteFile not function', function () {
230 | throws(function () {
231 | mod._ZDRClientObjectValidate(uStubCustomClient({
232 | ZDRClientWriteFile: null,
233 | }));
234 | }, /ZDRErrorInputNotFunction/);
235 | });
236 |
237 | it('throws if ZDRClientReadFile not function', function () {
238 | throws(function () {
239 | mod._ZDRClientObjectValidate(uStubCustomClient({
240 | ZDRClientReadFile: null,
241 | }));
242 | }, /ZDRErrorInputNotFunction/);
243 | });
244 |
245 | it('throws if ZDRClientListObjects not function', function () {
246 | throws(function () {
247 | mod._ZDRClientObjectValidate(uStubCustomClient({
248 | ZDRClientListObjects: null,
249 | }));
250 | }, /ZDRErrorInputNotFunction/);
251 | });
252 |
253 | it('throws if ZDRClientDelete not function', function () {
254 | throws(function () {
255 | mod._ZDRClientObjectValidate(uStubCustomClient({
256 | ZDRClientDelete: null,
257 | }));
258 | }, /ZDRErrorInputNotFunction/);
259 | });
260 |
261 | it('returns true', function () {
262 | deepEqual(mod._ZDRClientObjectValidate(uStubCustomClient()), true);
263 | });
264 |
265 | it('throws if ZDRClientPrepare not function', function () {
266 | throws(function () {
267 | mod._ZDRClientObjectValidate(uStubCustomClient({
268 | ZDRClientPrepare: null,
269 | }));
270 | }, /ZDRErrorInputNotFunction/);
271 | });
272 |
273 | it('throws if ZDRClientConnect not function', function () {
274 | throws(function () {
275 | mod._ZDRClientObjectValidate(uStubCustomClient({
276 | ZDRClientConnect: null,
277 | }));
278 | }, /ZDRErrorInputNotFunction/);
279 | });
280 |
281 | it('throws if ZDRClientReconnect not function', function () {
282 | throws(function () {
283 | mod._ZDRClientObjectValidate(uStubCustomClient({
284 | ZDRClientReconnect: null,
285 | }));
286 | }, /ZDRErrorInputNotFunction/);
287 | });
288 |
289 | it('throws if ZDRClientDisconnect not function', function () {
290 | throws(function () {
291 | mod._ZDRClientObjectValidate(uStubCustomClient({
292 | ZDRClientDisconnect: null,
293 | }));
294 | }, /ZDRErrorInputNotFunction/);
295 | });
296 |
297 | });
298 |
299 | describe('_ZDRPathIsDirectory', function test__ZDRPathIsDirectory() {
300 |
301 | it('throws if not string', function () {
302 | throws(function () {
303 | mod._ZDRPathIsDirectory(null);
304 | }, /ZDRErrorInputNotValid/);
305 | });
306 |
307 | it('returns true if trailing slash', function () {
308 | deepEqual(mod._ZDRPathIsDirectory(Math.random().toString() + '/'), true);
309 | });
310 |
311 | it('returns false', function () {
312 | deepEqual(mod._ZDRPathIsDirectory(Math.random().toString()), false);
313 | });
314 |
315 | });
316 |
317 | describe('_ZDRPathFormatDirectory', function test__ZDRPathFormatDirectory() {
318 |
319 | it('throws if not string', function () {
320 | throws(function () {
321 | mod._ZDRPathFormatDirectory(null);
322 | }, /ZDRErrorInputNotValid/);
323 | });
324 |
325 | it('returns inputData', function () {
326 | const item = Math.random().toString();
327 | deepEqual(mod._ZDRPathFormatDirectory(item + uRandomElement('/', '')), item + '/');
328 | });
329 |
330 | });
331 |
332 | describe('_ZDRPathFormatPath', function test__ZDRPathFormatPath() {
333 |
334 | it('throws if not string', function () {
335 | throws(function () {
336 | mod._ZDRPathFormatPath(null);
337 | }, /ZDRErrorInputNotValid/);
338 | });
339 |
340 | it('returns inputData', function () {
341 | const item = Math.random().toString();
342 | deepEqual(mod._ZDRPathFormatPath(uRandomElement('/', '') + item), '/' + item);
343 | });
344 |
345 | });
346 |
347 | describe('_ZDRModelSyncCallbackSignatures', function test__ZDRModelSyncCallbackSignatures() {
348 |
349 | it('returns array', function () {
350 | deepEqual(mod._ZDRModelSyncCallbackSignatures(), [
351 | 'ZDRSchemaDispatchSyncCreate',
352 | 'ZDRSchemaDispatchSyncUpdate',
353 | 'ZDRSchemaDispatchSyncDelete',
354 | 'ZDRSchemaDispatchSyncConflict',
355 | ]);
356 | });
357 |
358 | });
359 |
360 | describe('_ZDRModelSyncCallbackInput', function test__ZDRModelSyncCallbackInput() {
361 |
362 | const __ZDRModelSyncCallbackInput = function (param1, param2 = {}) {
363 | return mod._ZDRModelSyncCallbackInput(param1, Object.assign({
364 | origin: Math.random().toString(),
365 | }, param2));
366 | };
367 |
368 | it('throws if param1 not valid', function () {
369 | throws(function () {
370 | __ZDRModelSyncCallbackInput(Math.random().toString());
371 | }, /ZDRErrorInputNotValid/);
372 | });
373 |
374 | it('throws if param2 not valid', function () {
375 | throws(function () {
376 | mod._ZDRModelSyncCallbackInput(uRandomElement(mod._ZDRModelSyncCallbackSignatures()), {
377 | origin: null,
378 | });
379 | }, /ZDRErrorInputNotValid/);
380 | });
381 |
382 | it('returns newValue if ZDRSchemaDispatchSyncCreate', function () {
383 | const newValue = Math.random().toString();
384 | deepEqual(__ZDRModelSyncCallbackInput('ZDRSchemaDispatchSyncCreate', {
385 | newValue,
386 | }), newValue);
387 | });
388 |
389 | it('returns newValue if ZDRSchemaDispatchSyncUpdate', function () {
390 | const newValue = Math.random().toString();
391 | deepEqual(__ZDRModelSyncCallbackInput('ZDRSchemaDispatchSyncUpdate', {
392 | newValue,
393 | }), newValue);
394 | });
395 |
396 | it('returns oldValue if ZDRSchemaDispatchSyncDelete', function () {
397 | const oldValue = Math.random().toString();
398 | deepEqual(__ZDRModelSyncCallbackInput('ZDRSchemaDispatchSyncDelete', {
399 | oldValue,
400 | }), oldValue);
401 | });
402 |
403 | it('returns param2 if conflict', function () {
404 | const item = {
405 | origin: Math.random().toString(),
406 | };
407 | deepEqual(__ZDRModelSyncCallbackInput('ZDRSchemaDispatchSyncConflict', item), item);
408 | });
409 |
410 | });
411 |
412 | describe('ZDRProtocolRemoteStorage', function test_ZDRProtocolRemoteStorage() {
413 |
414 | it('returns string', function () {
415 | deepEqual(mod.ZDRProtocolRemoteStorage(), 'ZDR_PROTOCOL_REMOTE_STORAGE');
416 | });
417 |
418 | });
419 |
420 | describe('ZDRProtocolCustom', function test_ZDRProtocolCustom() {
421 |
422 | it('returns string', function () {
423 | deepEqual(mod.ZDRProtocolCustom(), 'ZDR_PROTOCOL_CUSTOM');
424 | });
425 |
426 | });
427 |
428 | describe('_ZDRProtocols', function test__ZDRProtocols() {
429 |
430 | it('returns array', function () {
431 | deepEqual(mod._ZDRProtocols(), [
432 | mod.ZDRProtocolRemoteStorage(),
433 | mod.ZDRProtocolCustom(),
434 | ]);
435 | });
436 |
437 | });
438 |
439 | describe('ZDRProtocolForIdentity', function test_ZDRProtocolForIdentity() {
440 |
441 | it('throws if not string', function () {
442 | throws(function () {
443 | mod.ZDRProtocolForIdentity(null);
444 | }, /ZDRErrorInputNotValid/);
445 | });
446 |
447 | it('returns ZDRProtocolRemoteStorage', function () {
448 | deepEqual(mod.ZDRProtocolForIdentity(Math.random().toString()), mod.ZDRProtocolRemoteStorage());
449 | });
450 |
451 | });
452 |
453 | describe('_ZDRProtocol', function test__ZDRProtocol() {
454 |
455 | it('returns type if remoteStorage', function () {
456 | deepEqual(mod._ZDRProtocol(uStubRemoteStorage()), mod.ZDRProtocolRemoteStorage());
457 | });
458 |
459 | it('returns type if custom', function () {
460 | deepEqual(mod._ZDRProtocol(uStubCustomClient()), mod.ZDRProtocolCustom());
461 | });
462 |
463 | it('throws', function () {
464 | throws(function () {
465 | mod._ZDRProtocol({});
466 | }, /ZDRErrorInputNotValid/);
467 | });
468 |
469 | });
470 |
471 | describe('_ZDRWrap', function test__ZDRWrap() {
472 |
473 | const __ZDRWrap = function (inputData = {}) {
474 | return mod._ZDRWrap(Object.assign({
475 | ZDRParamLibrary: uRandomElement(uStubRemoteStorage(), uStubCustomClient({
476 | ZDRClientConnect: (function () {}),
477 | ZDRClientDisconnect: (function () {}),
478 | })),
479 | ZDRParamScopes: [uStubScope(Object.assign({
480 | ZDRScopeSchemas: [uStubSchema(inputData)],
481 | }, inputData))],
482 | ZDRParamDispatchReady: (function () {}),
483 | }, inputData));
484 | };
485 |
486 | it('throws if not object', function () {
487 | throws(function () {
488 | mod._ZDRWrap(null);
489 | }, /ZDRErrorInputNotValid/);
490 | });
491 |
492 | it('throws if ZDRParamLibrary not valid', function () {
493 | throws(function () {
494 | __ZDRWrap({
495 | ZDRParamLibrary: null,
496 | });
497 | }, /ZDRErrorInputNotValid/);
498 | });
499 |
500 | it('throws if ZDRParamScopes not array', function () {
501 | throws(function () {
502 | __ZDRWrap({
503 | ZDRParamScopes: null,
504 | });
505 | }, /ZDRErrorInputNotValid/);
506 | });
507 |
508 | it('throws if ZDRParamScopes not filled', function () {
509 | throws(function () {
510 | __ZDRWrap({
511 | ZDRParamScopes: [],
512 | });
513 | }, /ZDRErrorInputNotValid/);
514 | });
515 |
516 | it('throws if ZDRParamScopes element not valid', function () {
517 | throws(function () {
518 | __ZDRWrap({
519 | ZDRParamScopes: [{
520 | ZDRScopeKey: null,
521 | }],
522 | });
523 | }, /ZDRErrorInputNotString/);
524 | });
525 |
526 | it('throws if ZDRScopeSchemas element not valid', function () {
527 | throws(function () {
528 | __ZDRWrap({
529 | ZDRParamScopes: [{
530 | ZDRScopeKey: Math.random().toString(),
531 | ZDRScopeDirectory: Math.random().toString(),
532 | ZDRScopeSchemas: [{
533 | ZDRSchemaKey: null
534 | }]
535 | }],
536 | });
537 | }, /ZDRErrorInputNotString/);
538 | });
539 |
540 | it('throws if ZDRParamDispatchReady not function', function () {
541 | throws(function () {
542 | __ZDRWrap({
543 | ZDRParamDispatchReady: null,
544 | });
545 | }, /ZDRErrorInputNotValid/);
546 | });
547 |
548 | it('returns object', function () {
549 | deepEqual(typeof __ZDRWrap(), 'object');
550 | });
551 |
552 | it('throws if ZDRParamDispatchError not function', function () {
553 | throws(function () {
554 | __ZDRWrap({
555 | ZDRParamDispatchError: null,
556 | });
557 | }, /ZDRErrorInputNotValid/);
558 | });
559 |
560 | it('throws if ZDRParamDispatchConnected not function', function () {
561 | throws(function () {
562 | __ZDRWrap({
563 | ZDRParamDispatchConnected: null,
564 | });
565 | }, /ZDRErrorInputNotValid/);
566 | });
567 |
568 | it('throws if ZDRParamDispatchOnline not function', function () {
569 | throws(function () {
570 | __ZDRWrap({
571 | ZDRParamDispatchOnline: null,
572 | });
573 | }, /ZDRErrorInputNotValid/);
574 | });
575 |
576 | it('throws if ZDRParamDispatchOffline not function', function () {
577 | throws(function () {
578 | __ZDRWrap({
579 | ZDRParamDispatchOffline: null,
580 | });
581 | }, /ZDRErrorInputNotValid/);
582 | });
583 |
584 | it('throws if ZDRParamDispatchSyncDidStart not function', function () {
585 | throws(function () {
586 | __ZDRWrap({
587 | ZDRParamDispatchSyncDidStart: null,
588 | });
589 | }, /ZDRErrorInputNotValid/);
590 | });
591 |
592 | it('throws if ZDRParamDispatchSyncDidStop not function', function () {
593 | throws(function () {
594 | __ZDRWrap({
595 | ZDRParamDispatchSyncDidStop: null,
596 | });
597 | }, /ZDRErrorInputNotValid/);
598 | });
599 |
600 | it('throws if ZDRParamDispatchWriteError not function', function () {
601 | throws(function () {
602 | __ZDRWrap({
603 | ZDRParamDispatchWriteError: null,
604 | });
605 | }, /ZDRErrorInputNotValid/);
606 | });
607 |
608 | it('throws if _ZDRParamDispatchJSONPreStringify not function', function () {
609 | throws(function () {
610 | __ZDRWrap({
611 | _ZDRParamDispatchJSONPreStringify: null,
612 | });
613 | }, /ZDRErrorInputNotValid/);
614 | });
615 |
616 | it('throws if _ZDRParamDispatchJSONPostParse not function', function () {
617 | throws(function () {
618 | __ZDRWrap({
619 | _ZDRParamDispatchJSONPostParse: null,
620 | });
621 | }, /ZDRErrorInputNotValid/);
622 | });
623 |
624 | const __ZDRStorage = function (inputData = {}) {
625 | const ZDRScopeKey = Math.random().toString();
626 |
627 | return __ZDRWrap(Object.assign({
628 | ZDRScopeKey,
629 | }, inputData))[ZDRScopeKey];
630 | };
631 |
632 | context('_ZDRStorageBasePath', function test__ZDRStorageBasePath() {
633 |
634 | it('throws if not string', function () {
635 | throws(function () {
636 | __ZDRStorage()._ZDRStorageBasePath(null);
637 | }, /ZDRErrorInputNotValid/);
638 | });
639 |
640 | it('returns string', function () {
641 | deepEqual(typeof __ZDRStorage()._ZDRStorageBasePath(Math.random().toString()), 'string');
642 | });
643 |
644 | });
645 |
646 | context('ZDRStorageWriteFile', function test_ZDRStorageWriteFile() {
647 |
648 | it('throws if param1 not string', function () {
649 | throws(function () {
650 | __ZDRStorage().ZDRStorageWriteFile(null, {}, uStubFilePath());
651 | }, /ZDRErrorInputNotValid/);
652 | });
653 |
654 | it('throws if param3 not string', function () {
655 | throws(function () {
656 | __ZDRStorage().ZDRStorageWriteFile(Math.random().toString(), {}, null);
657 | }, /ZDRErrorInputNotValid/);
658 | });
659 |
660 | it('returns param2', async function () {
661 | const item = Math.random().toString();
662 | deepEqual(await __ZDRStorage().ZDRStorageWriteFile(Math.random().toString(), item, uStubFilePath()), item);
663 | });
664 |
665 | });
666 |
667 | context('ZDRStorageWriteObject', function test_ZDRStorageWriteObject() {
668 |
669 | it('throws if param1 not string', function () {
670 | throws(function () {
671 | __ZDRStorage().ZDRStorageWriteObject(null, {});
672 | }, /ZDRErrorInputNotValid/);
673 | });
674 |
675 | it('throws if param2 not object', function () {
676 | throws(function () {
677 | __ZDRStorage().ZDRStorageWriteObject(Math.random().toString(), null);
678 | }, /ZDRErrorInputNotValid/);
679 | });
680 |
681 | it('returns param2', async function () {
682 | const item = {
683 | [Math.random().toString()]: Math.random().toString(),
684 | };
685 | deepEqual(await __ZDRStorage().ZDRStorageWriteObject(Math.random().toString(), item), item);
686 | });
687 |
688 | it('calls _ZDRParamDispatchJSONPreStringify', async function () {
689 | const item = Math.random().toString();
690 | deepEqual(await __ZDRStorage({
691 | _ZDRParamDispatchJSONPreStringify: (function (inputData) {
692 | return Object.assign(inputData, {
693 | [item]: item,
694 | });
695 | })
696 | }).ZDRStorageWriteObject(Math.random().toString(), {}), {
697 | [item]: item,
698 | })
699 | });
700 |
701 | it('calls ZDRParamDispatchWriteError if write fails', async function () {
702 | const err = new Error(Math.random().toString());
703 | const item = function() {
704 | throw err;
705 | };
706 |
707 | deepEqual(await uCaptureAsync(function (ZDRParamDispatchWriteError) {
708 | return __ZDRStorage({
709 | ZDRParamLibrary: uRandomElement(uStubRemoteStorage({
710 | storeFile: item,
711 | }), uStubCustomClient({
712 | ZDRClientConnect: (function () {}),
713 | ZDRClientDisconnect: (function () {}),
714 | ZDRClientWriteFile: item,
715 | })),
716 | ZDRParamDispatchWriteError,
717 | }).ZDRStorageWriteFile(Math.random().toString(), Math.random().toString(), uStubFilePath());
718 | }), [err]);
719 | });
720 |
721 | });
722 |
723 | context('ZDRStorageReadFile', function test_ZDRStorageReadFile() {
724 |
725 | it('throws if not string', function () {
726 | throws(function () {
727 | __ZDRStorage().ZDRStorageReadFile(null);
728 | }, /ZDRErrorInputNotValid/);
729 | });
730 |
731 | it('returns null', async function () {
732 | deepEqual(await __ZDRStorage().ZDRStorageReadFile(Math.random().toString()), null);
733 | });
734 |
735 | });
736 |
737 | context('ZDRStorageReadObject', function test_ZDRStorageReadObject() {
738 |
739 | it('throws if not string', function () {
740 | throws(function () {
741 | __ZDRStorage().ZDRStorageReadObject(null);
742 | }, /ZDRErrorInputNotValid/);
743 | });
744 |
745 | it('returns null', async function () {
746 | deepEqual(await __ZDRStorage().ZDRStorageReadObject(Math.random().toString()), null);
747 | });
748 |
749 | it('calls _ZDRParamDispatchJSONPostParse', async function () {
750 | const item = Math.random().toString();
751 | const api = __ZDRStorage({
752 | _ZDRParamDispatchJSONPostParse: (function () {
753 | return {
754 | [item]: item,
755 | };
756 | }),
757 | });
758 |
759 | const path = Math.random().toString();
760 |
761 | await api.ZDRStorageWriteObject(path, {});
762 |
763 | deepEqual(await api.ZDRStorageReadObject(path), {
764 | [item]: item,
765 | })
766 | });
767 |
768 | });
769 |
770 | context('ZDRStorageListingObjects', function test_ZDRStorageListingObjects() {
771 |
772 | it('throws if not string', function () {
773 | throws(function () {
774 | __ZDRStorage().ZDRStorageListingObjects(null);
775 | }, /ZDRErrorInputNotValid/);
776 | });
777 |
778 | it('returns object', async function () {
779 | deepEqual(await __ZDRStorage().ZDRStorageListingObjects(Math.random().toString()), {});
780 | });
781 |
782 | it('calls _ZDRParamDispatchJSONPostParse', async function () {
783 | const item = Math.random().toString();
784 | const api = __ZDRStorage({
785 | _ZDRParamDispatchJSONPostParse: (function () {
786 | return {
787 | [item]: item,
788 | };
789 | }),
790 | });
791 |
792 | await api.ZDRStorageWriteObject(Math.random().toString(), {});
793 |
794 | deepEqual(Object.values(await api.ZDRStorageListingObjects(Math.random().toString())), [{
795 | [item]: item,
796 | }]);
797 | });
798 |
799 | });
800 |
801 | context('ZDRStoragePaths', function test_ZDRStoragePaths() {
802 |
803 | it('throws if not string', function () {
804 | throws(function () {
805 | __ZDRStorage().ZDRStoragePaths(null);
806 | }, /ZDRErrorInputNotValid/);
807 | });
808 |
809 | it('calls _ZDRStoragePaths', function () {
810 | const item = Math.random().toString();
811 | deepEqual(Object.assign(__ZDRStorage(), {
812 | _ZDRStoragePaths: (function () {
813 | return [...arguments];
814 | }),
815 | }).ZDRStoragePaths(item + uRandomElement('/', '')), [mod._ZDRPathFormatDirectory(item)])
816 | });
817 |
818 | it('returns array', async function () {
819 | deepEqual(await __ZDRStorage().ZDRStoragePaths(Math.random().toString()), []);
820 | });
821 |
822 | });
823 |
824 | context('_ZDRStoragePathsRecursive', function test__ZDRStoragePathsRecursive() {
825 |
826 | it('calls ZDRStoragePaths', async function () {
827 | const item = mod._ZDRPathFormatDirectory(Math.random().toString());
828 | const file = Math.random().toString();
829 | deepEqual(await Object.assign(__ZDRStorage(), {
830 | ZDRStoragePaths: (function () {
831 | return [file];
832 | }),
833 | })._ZDRStoragePathsRecursive(item), [mod._ZDRPathFormatDirectory(item) + file]);
834 | });
835 |
836 | it('calls ZDRStoragePaths recursively', async function () {
837 | const item = mod._ZDRPathFormatDirectory(Math.random().toString());
838 | const folder = mod._ZDRPathFormatDirectory(Math.random().toString());
839 | const file = Math.random().toString();
840 | deepEqual(await Object.assign(__ZDRStorage(), {
841 | ZDRStoragePaths: (function (inputData) {
842 | return [inputData === item ? folder : file];
843 | }),
844 | })._ZDRStoragePathsRecursive(item), [mod._ZDRPathFormatDirectory(item) + folder + file]);
845 | });
846 |
847 | it('includes folders if param2 true', async function () {
848 | const item = mod._ZDRPathFormatDirectory(Math.random().toString());
849 | const folder = mod._ZDRPathFormatDirectory(Math.random().toString());
850 | const file = Math.random().toString();
851 | deepEqual(await Object.assign(__ZDRStorage(), {
852 | ZDRStoragePaths: (function (inputData) {
853 | return [inputData === item ? folder : file];
854 | }),
855 | })._ZDRStoragePathsRecursive(item, true), [
856 | mod._ZDRPathFormatDirectory(item) + folder + file,
857 | mod._ZDRPathFormatDirectory(item) + folder,
858 | mod._ZDRPathFormatDirectory(item)
859 | ]);
860 | });
861 |
862 | });
863 |
864 | context('ZDRStoragePathsRecursive', function test_ZDRStoragePathsRecursive() {
865 |
866 | it('throws if not string', function () {
867 | throws(function () {
868 | __ZDRStorage().ZDRStoragePathsRecursive(null);
869 | }, /ZDRErrorInputNotValid/);
870 | });
871 |
872 | it('calls _ZDRStoragePathsRecursive', function () {
873 | const item = Math.random().toString();
874 | deepEqual(Object.assign(__ZDRStorage(), {
875 | _ZDRStoragePathsRecursive: (function () {
876 | return [...arguments];
877 | }),
878 | }).ZDRStoragePathsRecursive(item), [mod._ZDRPathFormatDirectory(item), false])
879 | });
880 |
881 | it('returns array', async function () {
882 | deepEqual(await __ZDRStorage().ZDRStoragePathsRecursive(Math.random().toString()), []);
883 | });
884 |
885 | it('throws if param2 not boolean', function () {
886 | throws(function () {
887 | __ZDRStorage().ZDRStoragePathsRecursive(Math.random().toString(), null);
888 | }, /ZDRErrorInputNotValid/);
889 | });
890 |
891 | });
892 |
893 | context('ZDRStoragePermalink', function test_ZDRStoragePermalink() {
894 |
895 | it('throws if not string', function () {
896 | throws(function () {
897 | __ZDRStorage().ZDRStoragePermalink(null);
898 | }, /ZDRErrorInputNotValid/);
899 | });
900 |
901 | });
902 |
903 | context('ZDRStorageDeleteFile', function test_ZDRStorageDeleteFile() {
904 |
905 | it('throws if not string', function () {
906 | throws(function () {
907 | __ZDRStorage().ZDRStorageDeleteFile(null);
908 | }, /ZDRErrorInputNotValid/);
909 | });
910 |
911 | it('returns null', async function () {
912 | deepEqual(await __ZDRStorage().ZDRStorageDeleteFile(Math.random().toString()), null);
913 | });
914 |
915 | });
916 |
917 | context('ZDRStorageDeleteFolderRecursive', function test_ZDRStorageDeleteFolderRecursive() {
918 |
919 | it('rejects if not string', async function () {
920 | await rejects(__ZDRStorage().ZDRStorageDeleteFolderRecursive(null), /ZDRErrorInputNotValid/);
921 | });
922 |
923 | it('calls _ZDRStoragePathsRecursive', async function () {
924 | const item = Math.random().toString();
925 | deepEqual(uCapture(function (_ZDRStoragePathsRecursive) {
926 | Object.assign(__ZDRStorage(), {
927 | _ZDRStoragePathsRecursive,
928 | }).ZDRStorageDeleteFolderRecursive(item)
929 | }), [mod._ZDRPathFormatDirectory(item)]);
930 | });
931 |
932 | it('calls _ZDRStorageDeleteFile', async function () {
933 | const item = Math.random().toString();
934 | const api = __ZDRStorage();
935 | deepEqual(await new Promise(function (res, rej) {
936 | Object.assign(api, {
937 | _ZDRStoragePathsRecursive: (function () {
938 | return [
939 | item,
940 | ];
941 | }),
942 | _ZDRStorageDeleteFile: res,
943 | }).ZDRStorageDeleteFolderRecursive(Math.random().toString())
944 | }), api._ZDRStorageBasePath(item));
945 | });
946 |
947 | it('returns inputData', async function () {
948 | const item = Math.random().toString();
949 | deepEqual(await Object.assign(__ZDRStorage(), {
950 | _ZDRStoragePathsRecursive: (function () {
951 | return [];
952 | }),
953 | }).ZDRStorageDeleteFolderRecursive(item), item);
954 | });
955 |
956 | });
957 |
958 | context('ZDRStorageProtocol', function test_ZDRStorageProtocol() {
959 |
960 | it('returns ZDRProtocol', function () {
961 | const ZDRParamLibrary = uRandomElement(uStubRemoteStorage());
962 | deepEqual(__ZDRWrap({
963 | ZDRParamLibrary,
964 | }).ZDRStorageProtocol, mod._ZDRProtocol(ZDRParamLibrary));
965 | });
966 |
967 | });
968 |
969 | context('ZDRModel', function () {
970 |
971 | const _ZDRModel = function (inputData = {}) {
972 | const ZDRSchemaKey = Math.random().toString();
973 |
974 | return Object.assign(Object.assign(__ZDRStorage(Object.assign({
975 | ZDRSchemaKey,
976 | }, inputData)), inputData)[ZDRSchemaKey], inputData);
977 | };
978 |
979 | context('ZDRModelPath', function test_ZDRModelPath() {
980 |
981 | it('throws if not object', function () {
982 | throws(function () {
983 | _ZDRModel().ZDRModelPath(null);
984 | }, /ZDRErrorInputNotValid/);
985 | });
986 |
987 | it('calls ZDRSchemaPath', async function () {
988 | const inputData = {
989 | [Math.random().toString()]: Math.random().toString(),
990 | };
991 |
992 | deepEqual(_ZDRModel({
993 | ZDRSchemaPath: (function () {
994 | return JSON.stringify([...arguments]);
995 | }),
996 | }).ZDRModelPath(inputData), JSON.stringify([inputData]));
997 | });
998 |
999 | it('returns result', async function () {
1000 | const item = Math.random().toString();
1001 | deepEqual(_ZDRModel({
1002 | ZDRSchemaPath: (function () {
1003 | return item;
1004 | }),
1005 | }).ZDRModelPath({}), item);
1006 | });
1007 |
1008 | });
1009 |
1010 | context('ZDRModelWriteObject', function test_ZDRModelWriteObject() {
1011 |
1012 | it('throws if not object', function () {
1013 | throws(function () {
1014 | _ZDRModel().ZDRModelWriteObject(null);
1015 | }, /ZDRErrorInputNotValid/);
1016 | });
1017 |
1018 | it('passes all arguments to ZDRSchemaDispatchValidate', async function () {
1019 | const item1 = Math.random().toString();
1020 | const item2 = Math.random().toString();
1021 | await rejects(_ZDRModel({
1022 | ZDRSchemaDispatchValidate: (function () {
1023 | return [...arguments];
1024 | }),
1025 | }).ZDRModelWriteObject(item1, item2), [item1, item2]);
1026 | });
1027 |
1028 | it('rejects if ZDRSchemaDispatchValidate truthy', async function () {
1029 | const item = Math.random().toString();
1030 | await rejects(_ZDRModel({
1031 | ZDRSchemaDispatchValidate: (function () {
1032 | return [item];
1033 | }),
1034 | }).ZDRModelWriteObject({}), [item]);
1035 | });
1036 |
1037 | it('passes all arguments to ZDRSchemaPath', function () {
1038 | const item1 = {
1039 | [Math.random().toString()]: Math.random().toString(),
1040 | };
1041 | const item2 = {
1042 | [Math.random().toString()]: Math.random().toString(),
1043 | };
1044 | deepEqual(uCapture(function (capture) {
1045 | _ZDRModel({
1046 | ZDRSchemaPath: (function () {
1047 | capture(...arguments);
1048 |
1049 | return Math.random().toString();
1050 | }),
1051 | }).ZDRModelWriteObject(item1, item2)
1052 | }), [item1, item2]);
1053 | });
1054 |
1055 | it('calls ZDRStorageWriteObject', async function () {
1056 | const inputData = {
1057 | [Math.random().toString()]: Math.random().toString(),
1058 | };
1059 | const path = Math.random().toString();
1060 |
1061 | const model = _ZDRModel({
1062 | ZDRStorageWriteObject: (function () {
1063 | return [...arguments];
1064 | }),
1065 | ZDRSchemaPath: (function () {
1066 | return path;
1067 | }),
1068 | });
1069 |
1070 | deepEqual(model.ZDRModelWriteObject(inputData), [mod._ZDRPathFormatPath(path), inputData]);
1071 | });
1072 |
1073 | it('returns inputData', async function () {
1074 | const item = {
1075 | [Math.random().toString()]: Math.random().toString(),
1076 | };
1077 | deepEqual(await _ZDRModel().ZDRModelWriteObject(item), item);
1078 | });
1079 |
1080 | });
1081 |
1082 | context('_ZDRModelListObjects', function test__ZDRModelListObjects() {
1083 |
1084 | it('calls ZDRStoragePathsRecursive', function () {
1085 | const item = [];
1086 |
1087 | const model = _ZDRModel({
1088 | ZDRStoragePathsRecursive: (function () {
1089 | item.push(...arguments);
1090 |
1091 | return [];
1092 | }),
1093 | })._ZDRModelListObjects();
1094 |
1095 | deepEqual(item, ['/']);
1096 | });
1097 |
1098 | it('excludes if no match', async function () {
1099 | const item = Math.random().toString();
1100 | deepEqual(await _ZDRModel({
1101 | ZDRStoragePathsRecursive: (function () {
1102 | return [item];
1103 | }),
1104 | ZDRSchemaStub: (function () {
1105 | return Object.fromEntries([item.split('.')]);
1106 | }),
1107 | ZDRSchemaPath: (function () {
1108 | return Math.random().toString();
1109 | }),
1110 | })._ZDRModelListObjects(), []);
1111 | });
1112 |
1113 | it('include if match', async function () {
1114 | const item = Math.random().toString();
1115 | deepEqual(await _ZDRModel({
1116 | ZDRStoragePathsRecursive: (function () {
1117 | return [item];
1118 | }),
1119 | ZDRSchemaStub: (function () {
1120 | return Object.fromEntries([item.split('.')]);
1121 | }),
1122 | ZDRSchemaPath: (function (inputData) {
1123 | return Object.entries(inputData).shift().join('.');
1124 | }),
1125 | })._ZDRModelListObjects(), [item]);
1126 | });
1127 |
1128 | it('include if match leading slash insensitive', async function () {
1129 | const slash = uRandomElement(true, false);
1130 | const item = Math.random().toString();
1131 | deepEqual(await _ZDRModel({
1132 | ZDRStoragePathsRecursive: (function () {
1133 | return [slash ? mod._ZDRPathFormatPath(item) : item];
1134 | }),
1135 | ZDRSchemaStub: (function () {
1136 | return Object.fromEntries([item.split('.')]);
1137 | }),
1138 | ZDRSchemaPath: (function (inputData) {
1139 | const item = Object.entries(inputData).shift().join('.');
1140 | return !slash ? mod._ZDRPathFormatPath(item) : item;
1141 | }),
1142 | })._ZDRModelListObjects(), [slash ? mod._ZDRPathFormatPath(item) : item]);
1143 | });
1144 |
1145 | });
1146 |
1147 | context('ZDRModelListObjects', function test_ZDRModelListObjects() {
1148 |
1149 | it('calls _ZDRModelListObjects', function () {
1150 | const item = [];
1151 |
1152 | const model = _ZDRModel({
1153 | _ZDRModelListObjects: (function () {
1154 | item.push([...arguments]);
1155 |
1156 | return [];
1157 | }),
1158 | }).ZDRModelListObjects();
1159 |
1160 | deepEqual(item, [
1161 | []
1162 | ]);
1163 | });
1164 |
1165 | it('maps ZDRStorageReadObject', async function () {
1166 | const item = Math.random().toString();
1167 | deepEqual(await _ZDRModel({
1168 | _ZDRModelListObjects: (function () {
1169 | return [item];
1170 | }),
1171 | ZDRStorageReadObject: (function (inputData) {
1172 | return inputData.split('.');
1173 | }),
1174 | }).ZDRModelListObjects(), [item.split('.')]);
1175 | });
1176 |
1177 | });
1178 |
1179 | context('ZDRModelDeleteObject', function test_ZDRModelDeleteObject() {
1180 |
1181 | it('rejects if not object', async function () {
1182 | await rejects(_ZDRModel().ZDRModelDeleteObject(null), /ZDRErrorInputNotValid/);
1183 | });
1184 |
1185 | it('calls ZDRStorageDeleteFile', async function () {
1186 | const path = Math.random().toString();
1187 |
1188 | deepEqual(uCapture(function (ZDRStorageDeleteFile) {
1189 | const model = _ZDRModel({
1190 | ZDRStorageDeleteFile,
1191 | ZDRSchemaPath: (function () {
1192 | return path;
1193 | }),
1194 | }).ZDRModelDeleteObject({
1195 | [Math.random().toString()]: Math.random().toString(),
1196 | });
1197 | }), [mod._ZDRPathFormatPath(path)]);
1198 | });
1199 |
1200 | it('returns inputData', async function () {
1201 | const item = {
1202 | [Math.random().toString()]: Math.random().toString(),
1203 | };
1204 | deepEqual(await _ZDRModel().ZDRModelDeleteObject(item), item);
1205 | });
1206 |
1207 | });
1208 |
1209 | context('ZDRSchemaMethods', function test_ZDRSchemaMethods() {
1210 |
1211 | it('throws if not function', function () {
1212 | throws(function () {
1213 | __ZDRWrap(Object.assign({
1214 | ZDRSchemaMethods: {
1215 | [Math.random().toString()]: Math.random().toString(),
1216 | },
1217 | }));
1218 | }, /ZDRErrorInputNotFunction/);
1219 | });
1220 |
1221 | it('binds wrap to this', function () {
1222 | const ZDRScopeKey = Math.random().toString();
1223 | const ZDRSchemaKey = Math.random().toString();
1224 | const item = Math.random().toString();
1225 |
1226 | const wrap = __ZDRWrap(Object.assign({
1227 | ZDRScopeKey,
1228 | ZDRSchemaKey,
1229 | ZDRSchemaMethods: {
1230 | [item]: (function () {
1231 | return [this].concat(...arguments);
1232 | }),
1233 | },
1234 | }));
1235 |
1236 | deepEqual(wrap[ZDRScopeKey][ZDRSchemaKey][item](item), [wrap, item]);
1237 | });
1238 |
1239 | });
1240 |
1241 | });
1242 |
1243 | context('ZDRCloudConnect', function test_ZDRCloudConnect() {
1244 |
1245 | it('throws if not string', function () {
1246 | throws(function () {
1247 | __ZDRWrap().ZDRCloudConnect(null);
1248 | }, /ZDRErrorInputNotValid/);
1249 | });
1250 |
1251 | it('returns undefined', function () {
1252 | deepEqual(__ZDRWrap().ZDRCloudConnect(Math.random().toString()), undefined);
1253 | });
1254 |
1255 | });
1256 |
1257 | context('ZDRCloudReconnect', function test_ZDRCloudReconnect() {
1258 |
1259 | it('returns undefined', function () {
1260 | deepEqual(__ZDRWrap().ZDRCloudReconnect(), undefined);
1261 | });
1262 |
1263 | });
1264 |
1265 | context('ZDRCloudDisconnect', function test_ZDRCloudDisconnect() {
1266 |
1267 | it('returns undefined', function () {
1268 | deepEqual(__ZDRWrap().ZDRCloudDisconnect(), undefined);
1269 | });
1270 |
1271 | });
1272 |
1273 | });
1274 |
1275 | describe('ZDRWrap', function test_ZDRWrap() {
1276 |
1277 | it('calls _ZDRWrap', function () {
1278 | const item = {
1279 | [Math.random().toString()]: Math.random().toString(),
1280 | };
1281 | deepEqual(uCapture(function (capture) {
1282 | Object.assign(Object.assign({}, mod), {
1283 | _ZDRWrap: (function () {
1284 | capture(...arguments);
1285 | }),
1286 | }).ZDRWrap(item);
1287 | }), [item]);
1288 | });
1289 |
1290 | it('sets ZDRParamDispatchReady', async function () {
1291 | const ZDRScopeKey = Math.random().toString();
1292 | const ZDRParamLibrary = uRandomElement(uStubRemoteStorage(), uStubCustomClient());
1293 |
1294 | deepEqual((await mod.ZDRWrap({
1295 | ZDRParamLibrary,
1296 | ZDRParamScopes: [uStubScope({
1297 | ZDRScopeKey
1298 | })],
1299 | })).hasOwnProperty(ZDRScopeKey), true);
1300 | });
1301 |
1302 | });
1303 |
1304 | describe('ZDRPreferenceProtocol', function test_ZDRPreferenceProtocol() {
1305 |
1306 | it('throws if not valid', function () {
1307 | throws(function () {
1308 | mod.ZDRPreferenceProtocol(Math.random().toString());
1309 | }, /ZDRErrorInputNotValid/);
1310 | });
1311 |
1312 | it('calls localStorage.getItem', function () {
1313 | deepEqual(uCapture(function (capture) {
1314 | mod.ZDRPreferenceProtocol(uRandomElement(mod._ZDRProtocols()), uStubLocalStorage({
1315 | getItem: (function () {
1316 | capture(...arguments);
1317 | }),
1318 | }));
1319 | }), [
1320 | 'ZDR_PREFERENCE_PROTOCOL',
1321 | 'ZDR_PREFERENCE_PROTOCOL',
1322 | ]);
1323 | });
1324 |
1325 | it('calls localStorage.setItem if localStorage.getItem falsey', function () {
1326 | const item = uRandomElement(Math.random().toString(), false);
1327 | deepEqual(uCapture(function (capture) {
1328 | mod.ZDRPreferenceProtocol(uRandomElement(mod._ZDRProtocols()), uStubLocalStorage({
1329 | getItem: (function () {
1330 | return item;
1331 | }),
1332 | setItem: (function () {
1333 | capture(item);
1334 | }),
1335 | }));
1336 | }), item ? [] : [item]);
1337 | });
1338 |
1339 | it('returns localStorage.getItem', function () {
1340 | const item = Math.random().toString();
1341 | deepEqual(mod.ZDRPreferenceProtocol(uRandomElement(mod._ZDRProtocols()), uStubLocalStorage({
1342 | getItem: (function () {
1343 | return item;
1344 | }),
1345 | })), item);
1346 | });
1347 |
1348 | });
1349 |
1350 | describe('ZDRPreferenceProtocolClear', function test_ZDRPreferenceProtocolClear() {
1351 |
1352 | it('calls localStorage.removeItem', function () {
1353 | deepEqual(uCapture(function (capture) {
1354 | mod.ZDRPreferenceProtocolClear(uStubLocalStorage({
1355 | removeItem: (function () {
1356 | capture(...arguments);
1357 | }),
1358 | }));
1359 | }), [
1360 | 'ZDR_PREFERENCE_PROTOCOL',
1361 | ]);
1362 | });
1363 |
1364 | it('returns localStorage.removeItem', function () {
1365 | const item = Math.random().toString();
1366 | deepEqual(mod.ZDRPreferenceProtocolClear(uStubLocalStorage({
1367 | removeItem: (function () {
1368 | return item;
1369 | }),
1370 | })), item);
1371 | });
1372 |
1373 | });
1374 |
1375 | describe('ZDRPreferenceProtocolMigrate', function test_ZDRPreferenceProtocolMigrate() {
1376 |
1377 | it('calls localStorage.getItem', function () {
1378 | deepEqual(uCapture(function (capture) {
1379 | mod.ZDRPreferenceProtocolMigrate(uStubLocalStorage({
1380 | getItem: (function () {
1381 | capture(...arguments);
1382 | }),
1383 | }));
1384 | }), [
1385 | 'ZDR_PREFERENCE_PROTOCOL_MIGRATE',
1386 | ]);
1387 | });
1388 |
1389 | it('returns localStorage.getItem', function () {
1390 | const item = Math.random().toString();
1391 | deepEqual(mod.ZDRPreferenceProtocolMigrate(uStubLocalStorage({
1392 | getItem: (function () {
1393 | return item;
1394 | }),
1395 | })), item);
1396 | });
1397 |
1398 | });
1399 |
1400 | describe('ZDRPreferenceProtocolMigrateClear', function test_ZDRPreferenceProtocolMigrateClear() {
1401 |
1402 | it('calls localStorage.removeItem', function () {
1403 | deepEqual(uCapture(function (capture) {
1404 | mod.ZDRPreferenceProtocolMigrateClear(uStubLocalStorage({
1405 | removeItem: (function () {
1406 | capture(...arguments);
1407 | }),
1408 | }));
1409 | }), [
1410 | 'ZDR_PREFERENCE_PROTOCOL_MIGRATE',
1411 | ]);
1412 | });
1413 |
1414 | it('returns localStorage.removeItem', function () {
1415 | const item = Math.random().toString();
1416 | deepEqual(mod.ZDRPreferenceProtocolMigrateClear(uStubLocalStorage({
1417 | removeItem: (function () {
1418 | return item;
1419 | }),
1420 | })), item);
1421 | });
1422 |
1423 | });
1424 |
1425 | describe('ZDRPreferenceProtocolConnect', function test_ZDRPreferenceProtocolConnect() {
1426 |
1427 | it('throws if not string', function () {
1428 | throws(function () {
1429 | mod.ZDRPreferenceProtocolConnect(null);
1430 | }, /ZDRErrorInputNotValid/);
1431 | });
1432 |
1433 | it('calls ZDRProtocolForIdentity', function () {
1434 | const item = Math.random().toString();
1435 | deepEqual(uCapture(function (capture) {
1436 | Object.assign(Object.assign({}, mod), {
1437 | ZDRProtocolForIdentity: (function () {
1438 | capture(...arguments);
1439 |
1440 | return uRandomElement(mod._ZDRProtocols());
1441 | }),
1442 | }).ZDRPreferenceProtocolConnect(item, uStubLocalStorage());
1443 | }), [item]);
1444 | });
1445 |
1446 | it('sets ZDR_PREFERENCE_PROTOCOL_MIGRATE if different', function () {
1447 | deepEqual(uCapture(function (capture) {
1448 | mod.ZDRPreferenceProtocolConnect(Math.random().toString(), uStubLocalStorage({
1449 | getItem: (function () {
1450 | return mod.ZDRProtocolRemoteStorage();
1451 | }),
1452 | setItem: (function () {
1453 | capture(...arguments);
1454 | }),
1455 | }));
1456 | }), [
1457 | 'ZDR_PREFERENCE_PROTOCOL',
1458 | mod.ZDRProtocolRemoteStorage(),
1459 | ]);
1460 | });
1461 |
1462 | it('returns ZDRProtocol', function () {
1463 | const item = uRandomElement(true, false);
1464 | deepEqual(mod.ZDRPreferenceProtocolConnect(Math.random().toString(), uStubLocalStorage()), mod.ZDRProtocolRemoteStorage());
1465 | });
1466 |
1467 | });
1468 |
1469 | describe('ZDRLauncherFakeItemProxy', function test_ZDRLauncherFakeItemProxy() {
1470 |
1471 | it('returns object', function () {
1472 | const item = mod.ZDRLauncherFakeItemProxy();
1473 | deepEqual(item, {
1474 | LCHRecipeName: 'ZDRLauncherFakeItemProxy',
1475 | LCHRecipeCallback: item.LCHRecipeCallback,
1476 | });
1477 | });
1478 |
1479 | context('LCHRecipeCallback', function () {
1480 |
1481 | it('returns undefined', function () {
1482 | deepEqual(mod.ZDRLauncherFakeItemProxy().LCHRecipeCallback(), undefined);
1483 | });
1484 |
1485 | });
1486 |
1487 | });
1488 |
1489 | describe('ZDRLauncherItemFakeDispatchError', function test_ZDRLauncherItemFakeDispatchError() {
1490 |
1491 | it('throws if not object', function () {
1492 | throws(function () {
1493 | mod.ZDRLauncherItemFakeDispatchError(null);
1494 | }, /OLSKErrorInputNotValid/);
1495 | });
1496 |
1497 | it('returns object', function () {
1498 | const item = mod.ZDRLauncherItemFakeDispatchError({});
1499 | deepEqual(item, {
1500 | LCHRecipeName: 'ZDRLauncherItemFakeDispatchError',
1501 | LCHRecipeCallback: item.LCHRecipeCallback,
1502 | });
1503 | });
1504 |
1505 | context('LCHRecipeCallback', function () {
1506 |
1507 | it('calls ZDRParamDispatchError', function () {
1508 | deepEqual(mod.ZDRLauncherItemFakeDispatchError({
1509 | ZDRParamDispatchError: (function () {
1510 | return [...arguments];
1511 | }),
1512 | }).LCHRecipeCallback(), [new Error('ZDR_FAKE_CLOUD_ERROR')]);
1513 | });
1514 |
1515 | });
1516 |
1517 | });
1518 |
1519 | describe('ZDRLauncherItemFakeDispatchWriteError', function test_ZDRLauncherItemFakeDispatchWriteError() {
1520 |
1521 | it('throws if not object', function () {
1522 | throws(function () {
1523 | mod.ZDRLauncherItemFakeDispatchWriteError(null);
1524 | }, /OLSKErrorInputNotValid/);
1525 | });
1526 |
1527 | it('returns object', function () {
1528 | const item = mod.ZDRLauncherItemFakeDispatchWriteError({});
1529 | deepEqual(item, {
1530 | LCHRecipeName: 'ZDRLauncherItemFakeDispatchWriteError',
1531 | LCHRecipeCallback: item.LCHRecipeCallback,
1532 | });
1533 | });
1534 |
1535 | context('LCHRecipeCallback', function () {
1536 |
1537 | it('calls ZDRParamDispatchWriteError', function () {
1538 | deepEqual(mod.ZDRLauncherItemFakeDispatchWriteError({
1539 | ZDRParamDispatchWriteError: (function () {
1540 | return [...arguments];
1541 | }),
1542 | }).LCHRecipeCallback(), [new Error('ZDR_FAKE_WRITE_ERROR')]);
1543 | });
1544 |
1545 | });
1546 |
1547 | });
1548 |
1549 | describe('ZDRLauncherItemFakeDispatchConnected', function test_ZDRLauncherItemFakeDispatchConnected() {
1550 |
1551 | it('throws if not object', function () {
1552 | throws(function () {
1553 | mod.ZDRLauncherItemFakeDispatchConnected(null);
1554 | }, /OLSKErrorInputNotValid/);
1555 | });
1556 |
1557 | it('returns object', function () {
1558 | const item = mod.ZDRLauncherItemFakeDispatchConnected({});
1559 | deepEqual(item, {
1560 | LCHRecipeName: 'ZDRLauncherItemFakeDispatchConnected',
1561 | LCHRecipeCallback: item.LCHRecipeCallback,
1562 | });
1563 | });
1564 |
1565 | context('LCHRecipeCallback', function () {
1566 |
1567 | it('calls ZDRParamDispatchConnected', function () {
1568 | deepEqual(mod.ZDRLauncherItemFakeDispatchConnected({
1569 | ZDRParamDispatchConnected: (function () {
1570 | return [...arguments];
1571 | }),
1572 | }).LCHRecipeCallback(), ['ZDR_FAKE_CLOUD_IDENTITY', 'ZDR_FAKE_CLOUD_TOKEN']);
1573 | });
1574 |
1575 | });
1576 |
1577 | });
1578 |
1579 | describe('ZDRLauncherItemFakeDispatchOnline', function test_ZDRLauncherItemFakeDispatchOnline() {
1580 |
1581 | it('throws if not object', function () {
1582 | throws(function () {
1583 | mod.ZDRLauncherItemFakeDispatchOnline(null);
1584 | }, /OLSKErrorInputNotValid/);
1585 | });
1586 |
1587 | it('returns object', function () {
1588 | const item = mod.ZDRLauncherItemFakeDispatchOnline({});
1589 | deepEqual(item, {
1590 | LCHRecipeName: 'ZDRLauncherItemFakeDispatchOnline',
1591 | LCHRecipeCallback: item.LCHRecipeCallback,
1592 | });
1593 | });
1594 |
1595 | context('LCHRecipeCallback', function () {
1596 |
1597 | it('calls ZDRParamDispatchOnline', function () {
1598 | const item = Math.random().toString();
1599 | deepEqual(mod.ZDRLauncherItemFakeDispatchOnline({
1600 | ZDRParamDispatchOnline: (function () {
1601 | return item;
1602 | }),
1603 | }).LCHRecipeCallback(), item);
1604 | });
1605 |
1606 | });
1607 |
1608 | });
1609 |
1610 | describe('ZDRLauncherItemFakeDispatchOffline', function test_ZDRLauncherItemFakeDispatchOffline() {
1611 |
1612 | it('throws if not object', function () {
1613 | throws(function () {
1614 | mod.ZDRLauncherItemFakeDispatchOffline(null);
1615 | }, /OLSKErrorInputNotValid/);
1616 | });
1617 |
1618 | it('returns object', function () {
1619 | const item = mod.ZDRLauncherItemFakeDispatchOffline({});
1620 | deepEqual(item, {
1621 | LCHRecipeName: 'ZDRLauncherItemFakeDispatchOffline',
1622 | LCHRecipeCallback: item.LCHRecipeCallback,
1623 | });
1624 | });
1625 |
1626 | context('LCHRecipeCallback', function () {
1627 |
1628 | it('calls ZDRParamDispatchOffline', function () {
1629 | const item = Math.random().toString();
1630 | deepEqual(mod.ZDRLauncherItemFakeDispatchOffline({
1631 | ZDRParamDispatchOffline: (function () {
1632 | return item;
1633 | }),
1634 | }).LCHRecipeCallback(), item);
1635 | });
1636 |
1637 | });
1638 |
1639 | });
1640 |
1641 | describe('ZDRLauncherItemFakeDispatchSyncDidStart', function test_ZDRLauncherItemFakeDispatchSyncDidStart() {
1642 |
1643 | it('throws if not object', function () {
1644 | throws(function () {
1645 | mod.ZDRLauncherItemFakeDispatchSyncDidStart(null);
1646 | }, /OLSKErrorInputNotValid/);
1647 | });
1648 |
1649 | it('returns object', function () {
1650 | const item = mod.ZDRLauncherItemFakeDispatchSyncDidStart({});
1651 | deepEqual(item, {
1652 | LCHRecipeName: 'ZDRLauncherItemFakeDispatchSyncDidStart',
1653 | LCHRecipeCallback: item.LCHRecipeCallback,
1654 | });
1655 | });
1656 |
1657 | context('LCHRecipeCallback', function () {
1658 |
1659 | it('calls ZDRParamDispatchSyncDidStart', function () {
1660 | const item = Math.random().toString();
1661 | deepEqual(mod.ZDRLauncherItemFakeDispatchSyncDidStart({
1662 | ZDRParamDispatchSyncDidStart: (function () {
1663 | return item;
1664 | }),
1665 | }).LCHRecipeCallback(), item);
1666 | });
1667 |
1668 | });
1669 |
1670 | });
1671 |
1672 | describe('ZDRLauncherItemFakeDispatchSyncDidStop', function test_ZDRLauncherItemFakeDispatchSyncDidStop() {
1673 |
1674 | it('throws if not object', function () {
1675 | throws(function () {
1676 | mod.ZDRLauncherItemFakeDispatchSyncDidStop(null);
1677 | }, /OLSKErrorInputNotValid/);
1678 | });
1679 |
1680 | it('returns object', function () {
1681 | const item = mod.ZDRLauncherItemFakeDispatchSyncDidStop({});
1682 | deepEqual(item, {
1683 | LCHRecipeName: 'ZDRLauncherItemFakeDispatchSyncDidStop',
1684 | LCHRecipeCallback: item.LCHRecipeCallback,
1685 | });
1686 | });
1687 |
1688 | context('LCHRecipeCallback', function () {
1689 |
1690 | it('calls ZDRParamDispatchSyncDidStop', function () {
1691 | const item = Math.random().toString();
1692 | deepEqual(mod.ZDRLauncherItemFakeDispatchSyncDidStop({
1693 | ZDRParamDispatchSyncDidStop: (function () {
1694 | return item;
1695 | }),
1696 | }).LCHRecipeCallback(), item);
1697 | });
1698 |
1699 | });
1700 |
1701 | });
1702 |
1703 | describe('ZDRLauncherItemFakeDispatchDisconnected', function test_ZDRLauncherItemFakeDispatchDisconnected() {
1704 |
1705 | it('throws if not object', function () {
1706 | throws(function () {
1707 | mod.ZDRLauncherItemFakeDispatchDisconnected(null);
1708 | }, /OLSKErrorInputNotValid/);
1709 | });
1710 |
1711 | it('returns object', function () {
1712 | const item = mod.ZDRLauncherItemFakeDispatchDisconnected({});
1713 | deepEqual(item, {
1714 | LCHRecipeName: 'ZDRLauncherItemFakeDispatchDisconnected',
1715 | LCHRecipeCallback: item.LCHRecipeCallback,
1716 | });
1717 | });
1718 |
1719 | context('LCHRecipeCallback', function () {
1720 |
1721 | it('calls ZDRParamDispatchConnected', function () {
1722 | deepEqual(mod.ZDRLauncherItemFakeDispatchDisconnected({
1723 | ZDRParamDispatchConnected: (function () {
1724 | return [...arguments];
1725 | }),
1726 | }).LCHRecipeCallback().pop(), null);
1727 | });
1728 |
1729 | });
1730 |
1731 | });
1732 |
1733 | describe('ZDRRecipes', function test_ZDRRecipes() {
1734 |
1735 | const _ZDRRecipes = function (inputData = {}) {
1736 | return mod.ZDRRecipes(Object.assign({
1737 | ParamMod: {},
1738 | ParamSpecUI: false,
1739 | }, inputData));
1740 | };
1741 |
1742 | it('throws if not object', function () {
1743 | throws(function () {
1744 | mod.ZDRRecipes(null);
1745 | }, /OLSKErrorInputNotValid/);
1746 | });
1747 |
1748 | it('throws if ParamMod not object', function () {
1749 | throws(function () {
1750 | _ZDRRecipes({
1751 | ParamMod: null,
1752 | });
1753 | }, /OLSKErrorInputNotValid/);
1754 | });
1755 |
1756 | it('throws if ParamSpecUI not boolean', function () {
1757 | throws(function () {
1758 | _ZDRRecipes({
1759 | ParamSpecUI: null,
1760 | });
1761 | }, /OLSKErrorInputNotValid/);
1762 | });
1763 |
1764 | it('includes production recipes', function () {
1765 | deepEqual(_ZDRRecipes().map(function (e) {
1766 | return e.LCHRecipeSignature || e.LCHRecipeName;
1767 | }), Object.keys(mod).filter(function (e) {
1768 | return e.match(/Launcher/) && !e.match(/Fake/);
1769 | }));
1770 | });
1771 |
1772 | context('ParamSpecUI', function () {
1773 |
1774 | it('includes all recipes', function () {
1775 | deepEqual(_ZDRRecipes({
1776 | ParamSpecUI: true,
1777 | }).map(function (e) {
1778 | return e.LCHRecipeSignature || e.LCHRecipeName;
1779 | }), Object.keys(mod).filter(function (e) {
1780 | return e.match(/Launcher/);
1781 | }));
1782 | });
1783 |
1784 | });
1785 |
1786 | });
1787 |
--------------------------------------------------------------------------------