@mocktomata/io-remote 7.0.0-beta.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +24 -0
  3. package/esm/buildUrl.d.ts +2 -0
  4. package/esm/buildUrl.d.ts.map +1 -0
  5. package/esm/buildUrl.js +4 -0
  6. package/esm/buildUrl.js.map +1 -0
  7. package/esm/createIO.d.ts +4 -0
  8. package/esm/createIO.d.ts.map +1 -0
  9. package/esm/createIO.internal.d.ts +5 -0
  10. package/esm/createIO.internal.d.ts.map +1 -0
  11. package/esm/createIO.internal.js +34 -0
  12. package/esm/createIO.internal.js.map +1 -0
  13. package/esm/createIO.js +8 -0
  14. package/esm/createIO.js.map +1 -0
  15. package/esm/createIO.spec.d.ts +2 -0
  16. package/esm/createIO.spec.d.ts.map +1 -0
  17. package/esm/createIO.spec.js +54 -0
  18. package/esm/createIO.spec.js.map +1 -0
  19. package/esm/errors.d.ts +11 -0
  20. package/esm/errors.d.ts.map +1 -0
  21. package/esm/errors.js +15 -0
  22. package/esm/errors.js.map +1 -0
  23. package/esm/getServerInfo.d.ts +16 -0
  24. package/esm/getServerInfo.d.ts.map +1 -0
  25. package/esm/getServerInfo.js +37 -0
  26. package/esm/getServerInfo.js.map +1 -0
  27. package/esm/getServerInfo.spec.d.ts +2 -0
  28. package/esm/getServerInfo.spec.d.ts.map +1 -0
  29. package/esm/getServerInfo.spec.js +69 -0
  30. package/esm/getServerInfo.spec.js.map +1 -0
  31. package/esm/index.d.ts +4 -0
  32. package/esm/index.d.ts.map +1 -0
  33. package/esm/index.js +4 -0
  34. package/esm/index.js.map +1 -0
  35. package/esm/index.spec.d.ts +2 -0
  36. package/esm/index.spec.d.ts.map +1 -0
  37. package/esm/index.spec.js +5 -0
  38. package/esm/index.spec.js.map +1 -0
  39. package/esm/platform.d.ts +2 -0
  40. package/esm/platform.d.ts.map +1 -0
  41. package/esm/platform.js +4 -0
  42. package/esm/platform.js.map +1 -0
  43. package/esm/test-util/createFakeServerFetch.d.ts +5 -0
  44. package/esm/test-util/createFakeServerFetch.d.ts.map +1 -0
  45. package/esm/test-util/createFakeServerFetch.js +53 -0
  46. package/esm/test-util/createFakeServerFetch.js.map +1 -0
  47. package/esm/test-util/index.d.ts +2 -0
  48. package/esm/test-util/index.d.ts.map +1 -0
  49. package/esm/test-util/index.js +2 -0
  50. package/esm/test-util/index.js.map +1 -0
  51. package/esm/types.d.ts +8 -0
  52. package/esm/types.d.ts.map +1 -0
  53. package/esm/types.internal.d.ts +9 -0
  54. package/esm/types.internal.d.ts.map +1 -0
  55. package/esm/types.internal.js +2 -0
  56. package/esm/types.internal.js.map +1 -0
  57. package/esm/types.js +2 -0
  58. package/esm/types.js.map +1 -0
  59. package/package.json +62 -0
  60. package/ts/buildUrl.ts +3 -0
  61. package/ts/createIO.internal.ts +36 -0
  62. package/ts/createIO.spec.ts +70 -0
  63. package/ts/createIO.ts +10 -0
  64. package/ts/errors.ts +14 -0
  65. package/ts/getServerInfo.spec.ts +73 -0
  66. package/ts/getServerInfo.ts +59 -0
  67. package/ts/index.spec.ts +5 -0
  68. package/ts/index.ts +3 -0
  69. package/ts/platform.ts +3 -0
  70. package/ts/test-util/createFakeServerFetch.ts +58 -0
  71. package/ts/test-util/index.ts +1 -0
  72. package/ts/types.internal.ts +9 -0
  73. package/ts/types.ts +7 -0
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Fair Source License, version 0.9
2
+ Copyright © 2022 unional, Homa Wong (homawong@gmail.com)
3
+
4
+ Licensor: Homa Wong
5
+
6
+ Software: mocktomata, v7.0 and above
7
+
8
+ Use Limitation: 25 users
9
+
10
+ License Grant. Licensor hereby grants to each recipient of the Software (“you”) a non-exclusive, non-transferable, royalty-free and fully-paid-up license, under all of the Licensor’s copyright and patent rights, to use, copy, distribute, prepare derivative works of, publicly perform and display the Software, subject to the Use Limitation and the conditions set forth below.
11
+
12
+ Use Limitation. The license granted above allows use by up to the number of users per entity set forth above (the “Use Limitation”). For determining the number of users, “you” includes all affiliates, meaning legal entities controlling, controlled by, or under common control with you. If you exceed the Use Limitation, your use is subject to payment of Licensor’s then-current list price for licenses.
13
+
14
+ Conditions. Redistribution in source code or other forms must include a copy of this license document to be provided in a reasonable manner. Any redistribution of the Software is only allowed subject to this license.
15
+
16
+ Trademarks. This license does not grant you any right in the trademarks, service marks, brand names or logos of Licensor.
17
+
18
+ DISCLAIMER. THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OR CONDITION, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. LICENSORS HEREBY DISCLAIM ALL LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE.
19
+
20
+ Termination. If you violate the terms of this license, your rights will terminate automatically and will not be reinstated without the prior written consent of Licensor. Any such termination will not affect the right of others who may have received copies of the Software from you.
package/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # `@mocktomata/io-remote`
2
+
3
+ `@mocktomata/io-remote` provides IO access for [`mocktomata`] through some remote services.
4
+
5
+ The remote service is an instance of `@mocktomata/server` which uses various backend (e.g. `@mocktomata/nodejs`).
6
+
7
+ It implements the `Mocktomata.IO` type defined in `@mocktomata/framework`.
8
+
9
+ `mocktomata` depends on `@mocktomata/io-remote` for browser usage.
10
+ `@mocktomata/framework` does not depend on `@mocktomata/io-remote` directly.
11
+
12
+ This is a core package of [`mocktomata`] and do not need to be installed separately.
13
+
14
+ ## TO DO
15
+
16
+ Currently, validation of the data is handled on the server side.
17
+ It is needed to avoid bad/extra information send across the wire.
18
+
19
+ However, client side should perform similar check to prevent getting bad information from rouge server.
20
+
21
+ This mean similar validation/sanitation logic needs to be used by both server and client.
22
+
23
+ Currently, the logic is implemented in `@mocktomata/nodejs`.
24
+ They should be moved out of it to become platform independent and used on both sides.
@@ -0,0 +1,2 @@
1
+ export declare function buildUrl(urlBase: string, path: string): string;
2
+ //# sourceMappingURL=buildUrl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildUrl.d.ts","sourceRoot":"","sources":["../ts/buildUrl.ts"],"names":[],"mappings":"AAAA,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,UAErD"}
@@ -0,0 +1,4 @@
1
+ export function buildUrl(urlBase, path) {
2
+ return `${urlBase}/mocktomata/${path}`;
3
+ }
4
+ //# sourceMappingURL=buildUrl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildUrl.js","sourceRoot":"","sources":["../ts/buildUrl.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,QAAQ,CAAC,OAAe,EAAE,IAAY;IACpD,OAAO,GAAG,OAAO,eAAe,IAAI,EAAE,CAAA;AACxC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Mocktomata } from '@mocktomata/framework';
2
+ import type { CreateIOOptions } from './types.js';
3
+ export declare function createIO(options?: CreateIOOptions): Promise<Mocktomata.IO>;
4
+ //# sourceMappingURL=createIO.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createIO.d.ts","sourceRoot":"","sources":["../ts/createIO.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAA;AAIvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD,wBAAsB,QAAQ,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,CAGhF"}
@@ -0,0 +1,5 @@
1
+ import { Mocktomata } from '@mocktomata/framework';
2
+ import type { Context } from './types.internal.js';
3
+ import type { CreateIOOptions } from './types.js';
4
+ export declare function createIOInternal(ctx: Context, options?: CreateIOOptions): Promise<Mocktomata.IO>;
5
+ //# sourceMappingURL=createIO.internal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createIO.internal.d.ts","sourceRoot":"","sources":["../ts/createIO.internal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAwC,MAAM,uBAAuB,CAAA;AAGxF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,CA6BtG"}
@@ -0,0 +1,34 @@
1
+ import { SpecNotFound } from '@mocktomata/framework';
2
+ import { buildUrl } from './buildUrl.js';
3
+ import { getServerInfo } from './getServerInfo.js';
4
+ export async function createIOInternal(ctx, options) {
5
+ const info = await getServerInfo(ctx, options);
6
+ return {
7
+ async loadConfig() {
8
+ // @TODO add browser config?
9
+ const url = buildUrl(info.url, `config`);
10
+ const response = await ctx.fetch(url);
11
+ return response.json();
12
+ },
13
+ async loadPlugin(name) {
14
+ return ctx.importModule(name);
15
+ },
16
+ async readSpec(specName, specRelativePath) {
17
+ const id = btoa(JSON.stringify({ specName, specRelativePath }));
18
+ const response = await ctx.fetch(buildUrl(info.url, `specs/${id}`));
19
+ if (response.status === 404) {
20
+ throw new SpecNotFound(id, specRelativePath);
21
+ }
22
+ return response.json();
23
+ },
24
+ async writeSpec(specName, specRelativePath, record) {
25
+ const id = btoa(JSON.stringify({ specName, specRelativePath }));
26
+ const response = await ctx.fetch(buildUrl(info.url, `specs/${id}`), { method: 'POST', body: JSON.stringify(record) });
27
+ // istanbul ignore next
28
+ if (!response.ok) {
29
+ throw new Error(`failed to write spec: ${response.statusText}`);
30
+ }
31
+ },
32
+ };
33
+ }
34
+ //# sourceMappingURL=createIO.internal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createIO.internal.js","sourceRoot":"","sources":["../ts/createIO.internal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,YAAY,EAA0B,MAAM,uBAAuB,CAAA;AACxF,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAIlD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,GAAY,EAAE,OAAyB;IAC5E,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;IAC9C,OAAO;QACL,KAAK,CAAC,UAAU;YACd,4BAA4B;YAC5B,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;YACxC,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YACrC,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAA;QACxB,CAAC;QACD,KAAK,CAAC,UAAU,CAAC,IAAY;YAC3B,OAAO,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAA;QAC/B,CAAC;QACD,KAAK,CAAC,QAAQ,CAAC,QAAgB,EAAE,gBAAwB;YACvD,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAA;YAC/D,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,CAAA;YACnE,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE;gBAC3B,MAAM,IAAI,YAAY,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAA;aAC7C;YACD,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAA;QACxB,CAAC;QACD,KAAK,CAAC,SAAS,CAAC,QAAQ,EAAE,gBAAgB,EAAE,MAAM;YAChD,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAA;YAC/D,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;YACrH,uBAAuB;YACvB,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE;gBAChB,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAA;aAChE;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ import fetch from 'cross-fetch';
2
+ import { createIOInternal } from './createIO.internal.js';
3
+ import { importModule } from './platform.js';
4
+ export async function createIO(options) {
5
+ // istanbul ignore next
6
+ return createIOInternal({ fetch, location, importModule }, options);
7
+ }
8
+ //# sourceMappingURL=createIO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createIO.js","sourceRoot":"","sources":["../ts/createIO.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,aAAa,CAAA;AAC/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAG5C,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,OAAyB;IACtD,uBAAuB;IACvB,OAAO,gBAAgB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,OAAO,CAAC,CAAA;AACrE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=createIO.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createIO.spec.d.ts","sourceRoot":"","sources":["../ts/createIO.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,54 @@
1
+ import { SpecNotFound } from '@mocktomata/framework';
2
+ import { a } from 'assertron';
3
+ import { createIOInternal } from './createIO.internal.js';
4
+ import { createFakeServerFetch } from './test-util/index.js';
5
+ const location = {
6
+ hostname: 'localhost',
7
+ protocol: 'http:'
8
+ };
9
+ test('read not exist spec throws SpecNotFound', async () => {
10
+ const fetch = createFakeServerFetch();
11
+ const io = await createIOInternal({ fetch, location, importModule: () => Promise.resolve({}) });
12
+ await a.throws(io.readSpec('not exist', 'some-path/file'), SpecNotFound);
13
+ });
14
+ test('read existing spec', async () => {
15
+ const fetch = createFakeServerFetch();
16
+ const io = await createIOInternal({ fetch, location, importModule: () => Promise.resolve({}) });
17
+ const actual = await io.readSpec('exist', 'some-path/file');
18
+ expect(actual).toEqual({ actions: [] });
19
+ });
20
+ test('write spec', async () => {
21
+ const fetch = createFakeServerFetch();
22
+ const io = await createIOInternal({ fetch, location, importModule: () => Promise.resolve({}) });
23
+ const record = { refs: [], actions: [{ type: 'invoke', refId: '1', performer: 'user', thisArg: '0', payload: [], tick: 0 }] };
24
+ await io.writeSpec('new spec', 'some-path/file', record);
25
+ const spec = fetch.specs['new spec'];
26
+ expect(spec).toEqual(record);
27
+ });
28
+ describe('loadConfig()', () => {
29
+ test('returns installed plugin', async () => {
30
+ const fetch = createFakeServerFetch();
31
+ const io = await createIOInternal({ fetch, location, importModule: () => Promise.resolve({}) });
32
+ const list = await (await io.loadConfig()).plugins;
33
+ expect(list).toEqual(['@mocktomata/plugin-fixture-dummy']);
34
+ });
35
+ });
36
+ describe('loadPlugin()', () => {
37
+ test('load existing plugin', async () => {
38
+ const fetch = createFakeServerFetch();
39
+ const dummy = { activate() { } };
40
+ const io = await createIOInternal({
41
+ fetch, location, importModule: (moduleSpecifier) => Promise.resolve(moduleSpecifier
42
+ ? dummy : undefined)
43
+ });
44
+ const p = await io.loadPlugin(`@mocktomata/plugin-fixture-dummy`);
45
+ expect(p).toBe(dummy);
46
+ });
47
+ });
48
+ // describe('loadConfig()', () => {
49
+ // test('load...', async () => {
50
+ // const io = await createClientIO()
51
+ // await io.loadConfig()
52
+ // })
53
+ // })
54
+ //# sourceMappingURL=createIO.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createIO.spec.js","sourceRoot":"","sources":["../ts/createIO.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAc,MAAM,uBAAuB,CAAA;AAChE,OAAO,EAAE,CAAC,EAAE,MAAM,WAAW,CAAA;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAE5D,MAAM,QAAQ,GAAG;IACf,QAAQ,EAAE,WAAW;IACrB,QAAQ,EAAE,OAAO;CAClB,CAAA;AAED,IAAI,CAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;IACzD,MAAM,KAAK,GAAG,qBAAqB,EAAE,CAAA;IACrC,MAAM,EAAE,GAAG,MAAM,gBAAgB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IAE/F,MAAM,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC,EAAE,YAAY,CAAC,CAAA;AAC1E,CAAC,CAAC,CAAA;AAEF,IAAI,CAAC,oBAAoB,EAAE,KAAK,IAAI,EAAE;IACpC,MAAM,KAAK,GAAG,qBAAqB,EAAE,CAAA;IACrC,MAAM,EAAE,GAAG,MAAM,gBAAgB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IAE/F,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAA;IAE3D,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAA;AACzC,CAAC,CAAC,CAAA;AAEF,IAAI,CAAC,YAAY,EAAE,KAAK,IAAI,EAAE;IAC5B,MAAM,KAAK,GAAG,qBAAqB,EAAE,CAAA;IACrC,MAAM,EAAE,GAAG,MAAM,gBAAgB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IAE/F,MAAM,MAAM,GAAe,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAA;IACzI,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,gBAAgB,EAAE,MAAM,CAAC,CAAA;IAExD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;IACpC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;AAC9B,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,IAAI,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,KAAK,GAAG,qBAAqB,EAAE,CAAA;QACrC,MAAM,EAAE,GAAG,MAAM,gBAAgB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;QAE/F,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,UAAU,EAAE,CAAC,CAAC,OAAO,CAAA;QAClD,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,kCAAkC,CAAC,CAAC,CAAA;IAC5D,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,IAAI,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;QACtC,MAAM,KAAK,GAAG,qBAAqB,EAAE,CAAA;QACrC,MAAM,KAAK,GAAG,EAAE,QAAQ,KAAK,CAAC,EAAE,CAAA;QAChC,MAAM,EAAE,GAAG,MAAM,gBAAgB,CAAC;YAChC,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,CAC7B,eAAe,EACf,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe;gBAClC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;SACvB,CAAC,CAAA;QAEF,MAAM,CAAC,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,kCAAkC,CAAC,CAAA;QAEjE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACvB,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA;AAEF,mCAAmC;AACnC,kCAAkC;AAClC,wCAAwC;AACxC,4BAA4B;AAC5B,OAAO;AACP,KAAK"}
@@ -0,0 +1,11 @@
1
+ import { MocktomataError } from '@mocktomata/framework';
2
+ import { ModuleError } from 'iso-error';
3
+ export declare class ServerNotAvailable extends MocktomataError {
4
+ url: string;
5
+ constructor(url: string, options?: ModuleError.Options);
6
+ }
7
+ export declare class ServerNotAvailableAtPortRange extends MocktomataError {
8
+ url: string;
9
+ constructor(url: string, start: number, end: number, options?: ModuleError.Options);
10
+ }
11
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../ts/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AACvC,qBAAa,kBAAmB,SAAQ,eAAe;IAClC,GAAG,EAAE,MAAM;gBAAX,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,CAAC,OAAO;CAG9D;AAGD,qBAAa,6BAA8B,SAAQ,eAAe;IAC7C,GAAG,EAAE,MAAM;gBAAX,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,CAAC,OAAO;CAG1F"}
package/esm/errors.js ADDED
@@ -0,0 +1,15 @@
1
+ import { MocktomataError } from '@mocktomata/framework';
2
+ export class ServerNotAvailable extends MocktomataError {
3
+ constructor(url, options) {
4
+ super(`Unable to connect to server at ${url}`, options);
5
+ this.url = url;
6
+ }
7
+ }
8
+ // istanbul ignore next
9
+ export class ServerNotAvailableAtPortRange extends MocktomataError {
10
+ constructor(url, start, end, options) {
11
+ super(`Unable to find mocktomata server at ${url} between port ${start} and ${end}`, options);
12
+ this.url = url;
13
+ }
14
+ }
15
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../ts/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAEvD,MAAM,OAAO,kBAAmB,SAAQ,eAAe;IACrD,YAAmB,GAAW,EAAE,OAA6B;QAC3D,KAAK,CAAC,kCAAkC,GAAG,EAAE,EAAE,OAAO,CAAC,CAAA;QADtC,QAAG,GAAH,GAAG,CAAQ;IAE9B,CAAC;CACF;AAED,uBAAuB;AACvB,MAAM,OAAO,6BAA8B,SAAQ,eAAe;IAChE,YAAmB,GAAW,EAAE,KAAa,EAAE,GAAW,EAAE,OAA6B;QACvF,KAAK,CAAC,uCAAuC,GAAG,iBAAiB,KAAK,QAAQ,GAAG,EAAE,EAAE,OAAO,CAAC,CAAA;QAD5E,QAAG,GAAH,GAAG,CAAQ;IAE9B,CAAC;CACF"}
@@ -0,0 +1,16 @@
1
+ import type { CreateIOOptions } from './types.js';
2
+ export declare type ServerInfo = {
3
+ name: string;
4
+ version: string;
5
+ url: string;
6
+ plugins?: string[];
7
+ };
8
+ export declare type Context = {
9
+ fetch: (url: RequestInfo, init?: RequestInit) => Promise<Response>;
10
+ location: {
11
+ protocol: string;
12
+ hostname: string;
13
+ };
14
+ };
15
+ export declare function getServerInfo(context: Context, options?: CreateIOOptions): Promise<ServerInfo>;
16
+ //# sourceMappingURL=getServerInfo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getServerInfo.d.ts","sourceRoot":"","sources":["../ts/getServerInfo.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAEjD,oBAAY,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IAEZ,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CACnB,CAAA;AAED,oBAAY,OAAO,GAAG;IACpB,KAAK,EAAE,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnE,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAA;CACF,CAAA;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,CAEpG"}
@@ -0,0 +1,37 @@
1
+ import { buildUrl } from './buildUrl.js';
2
+ import { ServerNotAvailable, ServerNotAvailableAtPortRange } from './errors.js';
3
+ export async function getServerInfo(context, options) {
4
+ return options ? tryGetServerInfo(context, options.url) : lookupServerInfo(context);
5
+ }
6
+ async function lookupServerInfo(context) {
7
+ const { location } = context;
8
+ const url = `${location.protocol}//${location.hostname}`;
9
+ if (location.hostname === 'localhost') {
10
+ return tryGetServerInfoAtPort(context, url, 3698, 3698, 3708);
11
+ }
12
+ else {
13
+ return tryGetServerInfo(context, url);
14
+ }
15
+ }
16
+ async function tryGetServerInfoAtPort(context, urlBase, port, start, end) {
17
+ if (port >= end) {
18
+ throw new ServerNotAvailableAtPortRange(urlBase, start, end);
19
+ }
20
+ const url = `${urlBase}:${port}`;
21
+ try {
22
+ return await tryGetServerInfo(context, url);
23
+ }
24
+ catch (e) {
25
+ return tryGetServerInfoAtPort(context, urlBase, port + 1, start, end);
26
+ }
27
+ }
28
+ async function tryGetServerInfo({ fetch }, url) {
29
+ try {
30
+ const response = await fetch(buildUrl(url, 'info'));
31
+ return response.json();
32
+ }
33
+ catch (e) {
34
+ throw e.code === 'ECONNREFUSED' ? new ServerNotAvailable(url) : e;
35
+ }
36
+ }
37
+ //# sourceMappingURL=getServerInfo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getServerInfo.js","sourceRoot":"","sources":["../ts/getServerInfo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,kBAAkB,EAAE,6BAA6B,EAAE,MAAM,aAAa,CAAA;AAmB/E,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAgB,EAAE,OAAyB;IAC7E,OAAO,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;AACrF,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,OAAgB;IAC9C,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAA;IAC5B,MAAM,GAAG,GAAG,GAAG,QAAQ,CAAC,QAAQ,KAAK,QAAQ,CAAC,QAAQ,EAAE,CAAA;IACxD,IAAI,QAAQ,CAAC,QAAQ,KAAK,WAAW,EAAE;QACrC,OAAO,sBAAsB,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;KAC9D;SACI;QACH,OAAO,gBAAgB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;KACtC;AACH,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAC,OAAgB,EAAE,OAAe,EAAE,IAAY,EAAE,KAAa,EAAE,GAAW;IAC/G,IAAI,IAAI,IAAI,GAAG,EAAE;QACf,MAAM,IAAI,6BAA6B,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,CAAA;KAC7D;IAED,MAAM,GAAG,GAAG,GAAG,OAAO,IAAI,IAAI,EAAE,CAAA;IAEhC,IAAI;QACF,OAAO,MAAM,gBAAgB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;KAC5C;IACD,OAAO,CAAM,EAAE;QACb,OAAO,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,CAAA;KACtE;AACH,CAAC;AAED,KAAK,UAAU,gBAAgB,CAAC,EAAE,KAAK,EAAW,EAAE,GAAW;IAC7D,IAAI;QACF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAA;QACnD,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAA;KACvB;IACD,OAAO,CAAM,EAAE;QACb,MAAM,CAAC,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC,CAAC,IAAI,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;KAClE;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=getServerInfo.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getServerInfo.spec.d.ts","sourceRoot":"","sources":["../ts/getServerInfo.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,69 @@
1
+ import { a } from 'assertron';
2
+ import { ServerNotAvailable, ServerNotAvailableAtPortRange } from './errors.js';
3
+ import { getServerInfo } from './getServerInfo.js';
4
+ test('will try to search for server', async () => {
5
+ const fetch = (() => {
6
+ let count = 0;
7
+ return () => {
8
+ if (count < 3) {
9
+ count++;
10
+ return Promise.reject({ code: 'some error' });
11
+ }
12
+ return Promise.resolve({
13
+ json() {
14
+ return Promise.resolve({
15
+ name: 'mocktomata',
16
+ url: 'http://localhost:3712',
17
+ plugins: ['@mocktomata/plugin-fixture-dummy']
18
+ });
19
+ }
20
+ });
21
+ };
22
+ })();
23
+ const info = await getServerInfo({
24
+ fetch, location: {
25
+ hostname: 'localhost',
26
+ protocol: 'http:'
27
+ }
28
+ });
29
+ a.satisfies(info, {
30
+ name: 'mocktomata',
31
+ url: 'http://localhost:3712',
32
+ plugins: ['@mocktomata/plugin-fixture-dummy']
33
+ });
34
+ });
35
+ test('throws when specific server is not available', async () => {
36
+ const fetch = () => Promise.reject({ code: 'ECONNREFUSED' });
37
+ await a.throws(getServerInfo({ fetch, location }, { url: 'http://localhost:4321' }), ServerNotAvailable);
38
+ });
39
+ test('throws when server is not up', async () => {
40
+ const fetch = () => Promise.reject({});
41
+ await a.throws(getServerInfo({
42
+ fetch, location: {
43
+ hostname: 'localhost',
44
+ protocol: 'http:'
45
+ }
46
+ }), ServerNotAvailableAtPortRange);
47
+ });
48
+ test('remote', async () => {
49
+ let actual;
50
+ const fetch = (url) => {
51
+ actual = url;
52
+ return Promise.resolve({
53
+ json() {
54
+ return Promise.resolve({
55
+ name: 'mocktomata',
56
+ url: 'http://mocktomata.com',
57
+ plugins: ['@mocktomata/plugin-fixture-dummy']
58
+ });
59
+ }
60
+ });
61
+ };
62
+ const location = {
63
+ protocol: 'https:',
64
+ hostname: 'mocktomata.com'
65
+ };
66
+ await getServerInfo({ fetch, location });
67
+ expect(actual).toBe('https://mocktomata.com/mocktomata/info');
68
+ });
69
+ //# sourceMappingURL=getServerInfo.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getServerInfo.spec.js","sourceRoot":"","sources":["../ts/getServerInfo.spec.ts"],"names":[],"mappings":"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"}
package/esm/index.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export * from './createIO.js';
2
+ export * from './errors.js';
3
+ export * from './types.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../ts/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA"}
package/esm/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export * from './createIO.js';
2
+ export * from './errors.js';
3
+ export * from './types.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../ts/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,YAAY,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.spec.d.ts","sourceRoot":"","sources":["../ts/index.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ import { createIO } from './index.js';
2
+ test('exporting createIO', () => {
3
+ expect(createIO).toBeDefined();
4
+ });
5
+ //# sourceMappingURL=index.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.spec.js","sourceRoot":"","sources":["../ts/index.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,IAAI,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAC9B,MAAM,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAA;AAChC,CAAC,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare function importModule(moduleSpecifier: string): Promise<any>;
2
+ //# sourceMappingURL=platform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../ts/platform.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,eAAe,EAAE,MAAM,gBAEnD"}
@@ -0,0 +1,4 @@
1
+ export function importModule(moduleSpecifier) {
2
+ return import(moduleSpecifier);
3
+ }
4
+ //# sourceMappingURL=platform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.js","sourceRoot":"","sources":["../ts/platform.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,YAAY,CAAC,eAAuB;IAClD,OAAO,MAAM,CAAC,eAAe,CAAC,CAAA;AAChC,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare function createFakeServerFetch(): ((url: RequestInfo, init?: RequestInit) => Promise<Response>) & {
2
+ specs: Record<string, any>;
3
+ scenarios: Record<string, any>;
4
+ };
5
+ //# sourceMappingURL=createFakeServerFetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createFakeServerFetch.d.ts","sourceRoot":"","sources":["../../ts/test-util/createFakeServerFetch.ts"],"names":[],"mappings":"AAEA,wBAAgB,qBAAqB,WAUrB,WAAW,SAAS,WAAW;;;EAsC9C"}
@@ -0,0 +1,53 @@
1
+ import * as f from 'cross-fetch';
2
+ export function createFakeServerFetch() {
3
+ const specs = {
4
+ 'exist': { 'actions': [] }
5
+ };
6
+ const scenarios = {
7
+ 'exist': { 'scenario': 'exist' }
8
+ };
9
+ return Object.assign(async (url, init) => {
10
+ const uri = extractUri(url);
11
+ if (uri === 'mocktomata/info') {
12
+ return new f.Response(JSON.stringify({
13
+ url: 'http://localhost:3999',
14
+ version: '1.0',
15
+ }));
16
+ }
17
+ else if (uri === 'mocktomata/config') {
18
+ return new f.Response(JSON.stringify({
19
+ plugins: ['@mocktomata/plugin-fixture-dummy']
20
+ }));
21
+ }
22
+ // istanbul ignore next
23
+ else if (uri.startsWith('mocktomata/specs/')) {
24
+ const id = /mocktomata\/specs\/(.*)/.exec(uri)[1];
25
+ const { specName } = JSON.parse(atob(id));
26
+ if (init && init.method === 'POST') {
27
+ specs[specName] = JSON.parse(init.body);
28
+ return new f.Response(undefined);
29
+ }
30
+ else {
31
+ if (specs[specName])
32
+ return new f.Response(JSON.stringify(specs[specName]));
33
+ else
34
+ return new f.Response(undefined, { status: 404 });
35
+ }
36
+ }
37
+ // istanbul ignore next
38
+ console.error(url);
39
+ // istanbul ignore next
40
+ return new f.Response(undefined, { status: 404 });
41
+ }, {
42
+ specs,
43
+ scenarios
44
+ });
45
+ }
46
+ function extractUri(url) {
47
+ const match = /https?:\/\/\w*:\d+\/(.*)/.exec(url);
48
+ // istanbul ignore next
49
+ if (!match)
50
+ throw match;
51
+ return match[1];
52
+ }
53
+ //# sourceMappingURL=createFakeServerFetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createFakeServerFetch.js","sourceRoot":"","sources":["../../ts/test-util/createFakeServerFetch.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,aAAa,CAAA;AAEhC,MAAM,UAAU,qBAAqB;IACnC,MAAM,KAAK,GAAwB;QACjC,OAAO,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;KAC3B,CAAA;IAED,MAAM,SAAS,GAAwB;QACrC,OAAO,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE;KACjC,CAAA;IAED,OAAO,MAAM,CAAC,MAAM,CAClB,KAAK,EAAE,GAAgB,EAAE,IAAkB,EAAE,EAAE;QAC7C,MAAM,GAAG,GAAG,UAAU,CAAC,GAAa,CAAC,CAAA;QACrC,IAAI,GAAG,KAAK,iBAAiB,EAAE;YAC7B,OAAO,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC;gBACnC,GAAG,EAAE,uBAAuB;gBAC5B,OAAO,EAAE,KAAK;aACf,CAAC,CAAC,CAAA;SACJ;aACI,IAAI,GAAG,KAAK,mBAAmB,EAAE;YACpC,OAAO,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC;gBACnC,OAAO,EAAE,CAAC,kCAAkC,CAAC;aAC9C,CAAC,CAAC,CAAA;SACJ;QACD,uBAAuB;aAClB,IAAI,GAAG,CAAC,UAAU,CAAC,mBAAmB,CAAC,EAAE;YAC5C,MAAM,EAAE,GAAG,yBAAyB,CAAC,IAAI,CAAC,GAAG,CAAE,CAAC,CAAC,CAAC,CAAA;YAClD,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA;YACzC,IAAI,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE;gBAClC,KAAK,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAc,CAAC,CAAA;gBACjD,OAAO,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;aACjC;iBACI;gBACH,IAAI,KAAK,CAAC,QAAQ,CAAC;oBACjB,OAAO,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;;oBAEtD,OAAO,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;aACpD;SACF;QACD,uBAAuB;QACvB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAClB,uBAAuB;QACvB,OAAO,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;IACnD,CAAC,EACD;QACE,KAAK;QACL,SAAS;KACV,CACF,CAAA;AACH,CAAC;AAED,SAAS,UAAU,CAAC,GAAW;IAC7B,MAAM,KAAK,GAAG,0BAA0B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAClD,uBAAuB;IACvB,IAAI,CAAC,KAAK;QAAE,MAAM,KAAK,CAAA;IACvB,OAAO,KAAK,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './createFakeServerFetch.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../ts/test-util/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAA"}
@@ -0,0 +1,2 @@
1
+ export * from './createFakeServerFetch.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../ts/test-util/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAA"}
package/esm/types.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ export interface CreateIOOptions {
2
+ /**
3
+ * URL to the komondor server.
4
+ * This is used by browser tests to connect to the komondor server.
5
+ */
6
+ url: string;
7
+ }
8
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../ts/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAA;CACZ"}
@@ -0,0 +1,9 @@
1
+ export declare type Context = {
2
+ fetch: (url: RequestInfo, init?: RequestInit) => Promise<Response>;
3
+ location: {
4
+ protocol: string;
5
+ hostname: string;
6
+ };
7
+ importModule(moduleSpecifier: string): Promise<any>;
8
+ };
9
+ //# sourceMappingURL=types.internal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.internal.d.ts","sourceRoot":"","sources":["../ts/types.internal.ts"],"names":[],"mappings":"AAAA,oBAAY,OAAO,GAAG;IACpB,KAAK,EAAE,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnE,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAC;IACF,YAAY,CAAC,eAAe,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;CACpD,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.internal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.internal.js","sourceRoot":"","sources":["../ts/types.internal.ts"],"names":[],"mappings":""}
package/esm/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../ts/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@mocktomata/io-remote",
3
+ "version": "7.0.0-beta.12",
4
+ "description": "mocktomata remote IO",
5
+ "homepage": "https://github.com/mocktomata/mocktomata/tree/main/packages/io-remote",
6
+ "bugs": {
7
+ "url": "https://github.com/mocktomata/mocktomata/issues"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/mocktomata/mocktomata.git"
12
+ },
13
+ "license": "MIT",
14
+ "author": {
15
+ "name": "Homa Wong",
16
+ "email": "homawong@gmail.com"
17
+ },
18
+ "type": "module",
19
+ "exports": {
20
+ "import": "./esm/index.js"
21
+ },
22
+ "types": "./esm/index.d.ts",
23
+ "files": [
24
+ "esm",
25
+ "ts"
26
+ ],
27
+ "dependencies": {
28
+ "@mocktomata/framework": "^7.0.0-beta.12",
29
+ "cross-fetch": "^3.1.4",
30
+ "iso-error": "^4.4.0"
31
+ },
32
+ "devDependencies": {
33
+ "@kayahr/jest-electron-runner": "^29.0.0",
34
+ "@mocktomata/plugin-fixture-dummy": "^1.1.10",
35
+ "assertron": "^10.0.0",
36
+ "depcheck": "^1.4.3",
37
+ "jest": "^29.2.1",
38
+ "jest-validate": "29.2.1",
39
+ "jest-watch-suspend": "^1.1.2",
40
+ "jest-watch-toggle-config": "^2.0.1",
41
+ "jest-watch-typeahead": "^2.2.0",
42
+ "npm-run-all": "^4.1.5",
43
+ "rimraf": "^3.0.2",
44
+ "ts-jest": "^29.0.3",
45
+ "typescript": "~4.8.3"
46
+ },
47
+ "engines": {
48
+ "node": ">= 14.16"
49
+ },
50
+ "scripts": {
51
+ "build": "tsc",
52
+ "clean": "rimraf coverage esm lib libm tslib *.tsbuildinfo",
53
+ "coverage": "cross-env NODE_OPTIONS=--experimental-vm-modules jest -c jest.electron.cjs --coverage --reporters=default",
54
+ "depcheck": "depcheck",
55
+ "lint": "cross-env TIMING=1 eslint --ext=ts,js,cjs,mjs .",
56
+ "nuke": "pnpm run clean && rimraf node_modules",
57
+ "test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest -c jest.electron.cjs --reporters=default",
58
+ "test:watch": "cross-env NODE_OPTIONS=--experimental-vm-modules jest -c jest.electron.cjs --watch",
59
+ "verify": "npm-run-all -p lint build coverage -p depcheck",
60
+ "watch": "pnpm run test:watch"
61
+ }
62
+ }
package/ts/buildUrl.ts ADDED
@@ -0,0 +1,3 @@
1
+ export function buildUrl(urlBase: string, path: string) {
2
+ return `${urlBase}/mocktomata/${path}`
3
+ }
@@ -0,0 +1,36 @@
1
+ import { Mocktomata, SpecNotFound, SpecPlugin, SpecRecord } from '@mocktomata/framework'
2
+ import { buildUrl } from './buildUrl.js'
3
+ import { getServerInfo } from './getServerInfo.js'
4
+ import type { Context } from './types.internal.js'
5
+ import type { CreateIOOptions } from './types.js'
6
+
7
+ export async function createIOInternal(ctx: Context, options?: CreateIOOptions): Promise<Mocktomata.IO> {
8
+ const info = await getServerInfo(ctx, options)
9
+ return {
10
+ async loadConfig() {
11
+ // @TODO add browser config?
12
+ const url = buildUrl(info.url, `config`)
13
+ const response = await ctx.fetch(url)
14
+ return response.json()
15
+ },
16
+ async loadPlugin(name: string): Promise<SpecPlugin.Module> {
17
+ return ctx.importModule(name)
18
+ },
19
+ async readSpec(specName: string, specRelativePath: string): Promise<SpecRecord> {
20
+ const id = btoa(JSON.stringify({ specName, specRelativePath }))
21
+ const response = await ctx.fetch(buildUrl(info.url, `specs/${id}`))
22
+ if (response.status === 404) {
23
+ throw new SpecNotFound(id, specRelativePath)
24
+ }
25
+ return response.json()
26
+ },
27
+ async writeSpec(specName, specRelativePath, record) {
28
+ const id = btoa(JSON.stringify({ specName, specRelativePath }))
29
+ const response = await ctx.fetch(buildUrl(info.url, `specs/${id}`), { method: 'POST', body: JSON.stringify(record) })
30
+ // istanbul ignore next
31
+ if (!response.ok) {
32
+ throw new Error(`failed to write spec: ${response.statusText}`)
33
+ }
34
+ },
35
+ }
36
+ }
@@ -0,0 +1,70 @@
1
+ import { SpecNotFound, SpecRecord } from '@mocktomata/framework'
2
+ import { a } from 'assertron'
3
+ import { createIOInternal } from './createIO.internal.js'
4
+ import { createFakeServerFetch } from './test-util/index.js'
5
+
6
+ const location = {
7
+ hostname: 'localhost',
8
+ protocol: 'http:'
9
+ }
10
+
11
+ test('read not exist spec throws SpecNotFound', async () => {
12
+ const fetch = createFakeServerFetch()
13
+ const io = await createIOInternal({ fetch, location, importModule: () => Promise.resolve({}) })
14
+
15
+ await a.throws(io.readSpec('not exist', 'some-path/file'), SpecNotFound)
16
+ })
17
+
18
+ test('read existing spec', async () => {
19
+ const fetch = createFakeServerFetch()
20
+ const io = await createIOInternal({ fetch, location, importModule: () => Promise.resolve({}) })
21
+
22
+ const actual = await io.readSpec('exist', 'some-path/file')
23
+
24
+ expect(actual).toEqual({ actions: [] })
25
+ })
26
+
27
+ test('write spec', async () => {
28
+ const fetch = createFakeServerFetch()
29
+ const io = await createIOInternal({ fetch, location, importModule: () => Promise.resolve({}) })
30
+
31
+ const record: SpecRecord = { refs: [], actions: [{ type: 'invoke', refId: '1', performer: 'user', thisArg: '0', payload: [], tick: 0 }] }
32
+ await io.writeSpec('new spec', 'some-path/file', record)
33
+
34
+ const spec = fetch.specs['new spec']
35
+ expect(spec).toEqual(record)
36
+ })
37
+
38
+ describe('loadConfig()', () => {
39
+ test('returns installed plugin', async () => {
40
+ const fetch = createFakeServerFetch()
41
+ const io = await createIOInternal({ fetch, location, importModule: () => Promise.resolve({}) })
42
+
43
+ const list = await (await io.loadConfig()).plugins
44
+ expect(list).toEqual(['@mocktomata/plugin-fixture-dummy'])
45
+ })
46
+ })
47
+
48
+ describe('loadPlugin()', () => {
49
+ test('load existing plugin', async () => {
50
+ const fetch = createFakeServerFetch()
51
+ const dummy = { activate() { } }
52
+ const io = await createIOInternal({
53
+ fetch, location, importModule: (
54
+ moduleSpecifier
55
+ ) => Promise.resolve(moduleSpecifier
56
+ ? dummy : undefined)
57
+ })
58
+
59
+ const p = await io.loadPlugin(`@mocktomata/plugin-fixture-dummy`)
60
+
61
+ expect(p).toBe(dummy)
62
+ })
63
+ })
64
+
65
+ // describe('loadConfig()', () => {
66
+ // test('load...', async () => {
67
+ // const io = await createClientIO()
68
+ // await io.loadConfig()
69
+ // })
70
+ // })
package/ts/createIO.ts ADDED
@@ -0,0 +1,10 @@
1
+ import type { Mocktomata } from '@mocktomata/framework'
2
+ import fetch from 'cross-fetch'
3
+ import { createIOInternal } from './createIO.internal.js'
4
+ import { importModule } from './platform.js'
5
+ import type { CreateIOOptions } from './types.js'
6
+
7
+ export async function createIO(options?: CreateIOOptions): Promise<Mocktomata.IO> {
8
+ // istanbul ignore next
9
+ return createIOInternal({ fetch, location, importModule }, options)
10
+ }
package/ts/errors.ts ADDED
@@ -0,0 +1,14 @@
1
+ import { MocktomataError } from '@mocktomata/framework'
2
+ import { ModuleError } from 'iso-error'
3
+ export class ServerNotAvailable extends MocktomataError {
4
+ constructor(public url: string, options?: ModuleError.Options) {
5
+ super(`Unable to connect to server at ${url}`, options)
6
+ }
7
+ }
8
+
9
+ // istanbul ignore next
10
+ export class ServerNotAvailableAtPortRange extends MocktomataError {
11
+ constructor(public url: string, start: number, end: number, options?: ModuleError.Options) {
12
+ super(`Unable to find mocktomata server at ${url} between port ${start} and ${end}`, options)
13
+ }
14
+ }
@@ -0,0 +1,73 @@
1
+ import { a } from 'assertron'
2
+ import { ServerNotAvailable, ServerNotAvailableAtPortRange } from './errors.js'
3
+ import { getServerInfo } from './getServerInfo.js'
4
+
5
+ test('will try to search for server', async () => {
6
+ const fetch = (() => {
7
+ let count = 0
8
+ return () => {
9
+ if (count < 3) {
10
+ count++
11
+ return Promise.reject({ code: 'some error' })
12
+ }
13
+ return Promise.resolve({
14
+ json() {
15
+ return Promise.resolve({
16
+ name: 'mocktomata',
17
+ url: 'http://localhost:3712',
18
+ plugins: ['@mocktomata/plugin-fixture-dummy']
19
+ })
20
+ }
21
+ } as any)
22
+ }
23
+ })()
24
+ const info = await getServerInfo({
25
+ fetch, location: {
26
+ hostname: 'localhost',
27
+ protocol: 'http:'
28
+ }
29
+ })
30
+ a.satisfies(info, {
31
+ name: 'mocktomata',
32
+ url: 'http://localhost:3712',
33
+ plugins: ['@mocktomata/plugin-fixture-dummy']
34
+ })
35
+ })
36
+
37
+ test('throws when specific server is not available', async () => {
38
+ const fetch = () => Promise.reject({ code: 'ECONNREFUSED' })
39
+
40
+ await a.throws(getServerInfo({ fetch, location }, { url: 'http://localhost:4321' }), ServerNotAvailable)
41
+ })
42
+
43
+ test('throws when server is not up', async () => {
44
+ const fetch = () => Promise.reject({})
45
+ await a.throws(getServerInfo({
46
+ fetch, location: {
47
+ hostname: 'localhost',
48
+ protocol: 'http:'
49
+ }
50
+ }), ServerNotAvailableAtPortRange)
51
+ })
52
+
53
+ test('remote', async () => {
54
+ let actual: RequestInfo
55
+ const fetch = (url: RequestInfo) => {
56
+ actual = url
57
+ return Promise.resolve({
58
+ json() {
59
+ return Promise.resolve({
60
+ name: 'mocktomata',
61
+ url: 'http://mocktomata.com',
62
+ plugins: ['@mocktomata/plugin-fixture-dummy']
63
+ })
64
+ }
65
+ } as any)
66
+ }
67
+ const location = {
68
+ protocol: 'https:',
69
+ hostname: 'mocktomata.com'
70
+ }
71
+ await getServerInfo({ fetch, location })
72
+ expect(actual!).toBe('https://mocktomata.com/mocktomata/info')
73
+ })
@@ -0,0 +1,59 @@
1
+ import { buildUrl } from './buildUrl.js'
2
+ import { ServerNotAvailable, ServerNotAvailableAtPortRange } from './errors.js'
3
+ import type { CreateIOOptions } from './types.js'
4
+
5
+ export type ServerInfo = {
6
+ name: string,
7
+ version: string,
8
+ url: string,
9
+ // TODO: server not returning plugins
10
+ plugins?: string[]
11
+ }
12
+
13
+ export type Context = {
14
+ fetch: (url: RequestInfo, init?: RequestInit) => Promise<Response>,
15
+ location: {
16
+ protocol: string,
17
+ hostname: string
18
+ }
19
+ }
20
+
21
+ export async function getServerInfo(context: Context, options?: CreateIOOptions): Promise<ServerInfo> {
22
+ return options ? tryGetServerInfo(context, options.url) : lookupServerInfo(context)
23
+ }
24
+
25
+ async function lookupServerInfo(context: Context) {
26
+ const { location } = context
27
+ const url = `${location.protocol}//${location.hostname}`
28
+ if (location.hostname === 'localhost') {
29
+ return tryGetServerInfoAtPort(context, url, 3698, 3698, 3708)
30
+ }
31
+ else {
32
+ return tryGetServerInfo(context, url)
33
+ }
34
+ }
35
+
36
+ async function tryGetServerInfoAtPort(context: Context, urlBase: string, port: number, start: number, end: number): Promise<ServerInfo> {
37
+ if (port >= end) {
38
+ throw new ServerNotAvailableAtPortRange(urlBase, start, end)
39
+ }
40
+
41
+ const url = `${urlBase}:${port}`
42
+
43
+ try {
44
+ return await tryGetServerInfo(context, url)
45
+ }
46
+ catch (e: any) {
47
+ return tryGetServerInfoAtPort(context, urlBase, port + 1, start, end)
48
+ }
49
+ }
50
+
51
+ async function tryGetServerInfo({ fetch }: Context, url: string): Promise<ServerInfo> {
52
+ try {
53
+ const response = await fetch(buildUrl(url, 'info'))
54
+ return response.json()
55
+ }
56
+ catch (e: any) {
57
+ throw e.code === 'ECONNREFUSED' ? new ServerNotAvailable(url) : e
58
+ }
59
+ }
@@ -0,0 +1,5 @@
1
+ import { createIO } from './index.js'
2
+
3
+ test('exporting createIO', () => {
4
+ expect(createIO).toBeDefined()
5
+ })
package/ts/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from './createIO.js'
2
+ export * from './errors.js'
3
+ export * from './types.js'
package/ts/platform.ts ADDED
@@ -0,0 +1,3 @@
1
+ export function importModule(moduleSpecifier: string) {
2
+ return import(moduleSpecifier)
3
+ }
@@ -0,0 +1,58 @@
1
+ import * as f from 'cross-fetch'
2
+
3
+ export function createFakeServerFetch() {
4
+ const specs: Record<string, any> = {
5
+ 'exist': { 'actions': [] }
6
+ }
7
+
8
+ const scenarios: Record<string, any> = {
9
+ 'exist': { 'scenario': 'exist' }
10
+ }
11
+
12
+ return Object.assign(
13
+ async (url: RequestInfo, init?: RequestInit) => {
14
+ const uri = extractUri(url as string)
15
+ if (uri === 'mocktomata/info') {
16
+ return new f.Response(JSON.stringify({
17
+ url: 'http://localhost:3999',
18
+ version: '1.0',
19
+ }))
20
+ }
21
+ else if (uri === 'mocktomata/config') {
22
+ return new f.Response(JSON.stringify({
23
+ plugins: ['@mocktomata/plugin-fixture-dummy']
24
+ }))
25
+ }
26
+ // istanbul ignore next
27
+ else if (uri.startsWith('mocktomata/specs/')) {
28
+ const id = /mocktomata\/specs\/(.*)/.exec(uri)![1]
29
+ const { specName } = JSON.parse(atob(id))
30
+ if (init && init.method === 'POST') {
31
+ specs[specName] = JSON.parse(init.body as string)
32
+ return new f.Response(undefined)
33
+ }
34
+ else {
35
+ if (specs[specName])
36
+ return new f.Response(JSON.stringify(specs[specName]))
37
+ else
38
+ return new f.Response(undefined, { status: 404 })
39
+ }
40
+ }
41
+ // istanbul ignore next
42
+ console.error(url)
43
+ // istanbul ignore next
44
+ return new f.Response(undefined, { status: 404 })
45
+ },
46
+ {
47
+ specs,
48
+ scenarios
49
+ }
50
+ )
51
+ }
52
+
53
+ function extractUri(url: string) {
54
+ const match = /https?:\/\/\w*:\d+\/(.*)/.exec(url)
55
+ // istanbul ignore next
56
+ if (!match) throw match
57
+ return match[1]
58
+ }
@@ -0,0 +1 @@
1
+ export * from './createFakeServerFetch.js'
@@ -0,0 +1,9 @@
1
+ export type Context = {
2
+ fetch: (url: RequestInfo, init?: RequestInit) => Promise<Response>,
3
+ location: {
4
+ protocol: string,
5
+ hostname: string
6
+ },
7
+ importModule(moduleSpecifier: string): Promise<any>
8
+ }
9
+
package/ts/types.ts ADDED
@@ -0,0 +1,7 @@
1
+ export interface CreateIOOptions {
2
+ /**
3
+ * URL to the komondor server.
4
+ * This is used by browser tests to connect to the komondor server.
5
+ */
6
+ url: string
7
+ }