@synnaxlabs/freighter 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +3 -0
  3. package/build/main/index.d.ts +7 -0
  4. package/build/main/index.js +27 -0
  5. package/build/main/lib/caseconv.d.ts +2 -0
  6. package/build/main/lib/caseconv.js +14 -0
  7. package/build/main/lib/encoder.d.ts +60 -0
  8. package/build/main/lib/encoder.js +61 -0
  9. package/build/main/lib/encoder.spec.d.ts +1 -0
  10. package/build/main/lib/encoder.spec.js +26 -0
  11. package/build/main/lib/errors.d.ts +77 -0
  12. package/build/main/lib/errors.js +171 -0
  13. package/build/main/lib/errors.spec.d.ts +1 -0
  14. package/build/main/lib/errors.spec.js +76 -0
  15. package/build/main/lib/http.d.ts +46 -0
  16. package/build/main/lib/http.js +99 -0
  17. package/build/main/lib/http.spec.d.ts +1 -0
  18. package/build/main/lib/http.spec.js +49 -0
  19. package/build/main/lib/runtime.d.ts +5 -0
  20. package/build/main/lib/runtime.js +22 -0
  21. package/build/main/lib/stream.d.ts +75 -0
  22. package/build/main/lib/stream.js +3 -0
  23. package/build/main/lib/unary.d.ts +14 -0
  24. package/build/main/lib/unary.js +3 -0
  25. package/build/main/lib/url.d.ts +37 -0
  26. package/build/main/lib/url.js +57 -0
  27. package/build/main/lib/url.spec.d.ts +1 -0
  28. package/build/main/lib/url.spec.js +36 -0
  29. package/build/main/lib/websocket.d.ts +21 -0
  30. package/build/main/lib/websocket.js +154 -0
  31. package/build/main/lib/ws.spec.d.ts +1 -0
  32. package/build/main/lib/ws.spec.js +73 -0
  33. package/build/module/index.d.ts +7 -0
  34. package/build/module/index.js +6 -0
  35. package/build/module/lib/caseconv.d.ts +2 -0
  36. package/build/module/lib/caseconv.js +9 -0
  37. package/build/module/lib/encoder.d.ts +60 -0
  38. package/build/module/lib/encoder.js +51 -0
  39. package/build/module/lib/encoder.spec.d.ts +1 -0
  40. package/build/module/lib/encoder.spec.js +21 -0
  41. package/build/module/lib/errors.d.ts +77 -0
  42. package/build/module/lib/errors.js +160 -0
  43. package/build/module/lib/errors.spec.d.ts +1 -0
  44. package/build/module/lib/errors.spec.js +71 -0
  45. package/build/module/lib/http.d.ts +46 -0
  46. package/build/module/lib/http.js +94 -0
  47. package/build/module/lib/http.spec.d.ts +1 -0
  48. package/build/module/lib/http.spec.js +44 -0
  49. package/build/module/lib/runtime.d.ts +5 -0
  50. package/build/module/lib/runtime.js +19 -0
  51. package/build/module/lib/stream.d.ts +75 -0
  52. package/build/module/lib/stream.js +2 -0
  53. package/build/module/lib/unary.d.ts +14 -0
  54. package/build/module/lib/unary.js +2 -0
  55. package/build/module/lib/url.d.ts +37 -0
  56. package/build/module/lib/url.js +61 -0
  57. package/build/module/lib/url.spec.d.ts +1 -0
  58. package/build/module/lib/url.spec.js +31 -0
  59. package/build/module/lib/websocket.d.ts +21 -0
  60. package/build/module/lib/websocket.js +160 -0
  61. package/build/module/lib/ws.spec.d.ts +1 -0
  62. package/build/module/lib/ws.spec.js +69 -0
  63. package/package.json +118 -0
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.POSTClient = exports.GETClient = exports.HTTPClientFactory = void 0;
7
+ const axios_1 = __importDefault(require("axios"));
8
+ const errors_1 = require("./errors");
9
+ /**
10
+ * HTTPClientFactory provides a POST and GET implementation of the Unary protocol.
11
+ *
12
+ * @param url - The base URL of the API.
13
+ * @param encoder - The encoder/decoder to use for the request/response.
14
+ */
15
+ class HTTPClientFactory {
16
+ constructor(endpoint, encoder) {
17
+ this.endpoint = endpoint;
18
+ this.encoder = encoder;
19
+ }
20
+ getClient() {
21
+ return new GETClient(this.endpoint, this.encoder);
22
+ }
23
+ postClient() {
24
+ return new POSTClient(this.endpoint, this.encoder);
25
+ }
26
+ }
27
+ exports.HTTPClientFactory = HTTPClientFactory;
28
+ class Core {
29
+ constructor(endpoint, encoder) {
30
+ this.endpoint = endpoint.replace({ protocol: 'http' });
31
+ this.encoder = encoder;
32
+ }
33
+ get headers() {
34
+ return {
35
+ [Core.CONTENT_TYPE_HEADER_KEY]: this.encoder.contentType,
36
+ [Core.ERROR_ENCODING_HEADER_KEY]: Core.ERROR_ENCODING_HEADER_VALUE,
37
+ };
38
+ }
39
+ requestConfig() {
40
+ return {
41
+ headers: this.headers,
42
+ responseType: 'arraybuffer',
43
+ withCredentials: false,
44
+ validateStatus: () => true,
45
+ };
46
+ }
47
+ async execute(request, resSchema) {
48
+ const response = await axios_1.default.request(request);
49
+ if (response.status < 200 || response.status >= 300) {
50
+ try {
51
+ const err = this.encoder.decode(response.data, errors_1.ErrorPayloadSchema);
52
+ return [undefined, (0, errors_1.decodeError)(err)];
53
+ }
54
+ catch (_a) {
55
+ return [undefined, new Error(response.data)];
56
+ }
57
+ }
58
+ const data = this.encoder.decode(response.data, resSchema);
59
+ return [data, undefined];
60
+ }
61
+ }
62
+ Core.ERROR_ENCODING_HEADER_KEY = 'Error-Encoding';
63
+ Core.ERROR_ENCODING_HEADER_VALUE = 'freighter';
64
+ Core.CONTENT_TYPE_HEADER_KEY = 'Content-Type';
65
+ /**
66
+ * Implementation of the UnaryClient protocol backed by HTTP GET requests. It
67
+ * should not be instantiated directly, but through the HTTPClientFactory.
68
+ */
69
+ class GETClient extends Core {
70
+ async send(target, req, resSchema) {
71
+ const queryString = buildQueryString(req);
72
+ const request = this.requestConfig();
73
+ request.method = 'GET';
74
+ request.url = this.endpoint.child(target).stringify() + '?' + queryString;
75
+ return await this.execute(request, resSchema);
76
+ }
77
+ }
78
+ exports.GETClient = GETClient;
79
+ /**
80
+ * Implementation of the UnaryClient protocol backed by HTTP POST requests. It
81
+ * should not be instantiated directly, but through the HTTPClientFactory.
82
+ */
83
+ class POSTClient extends Core {
84
+ async send(target, req, resSchema) {
85
+ const url = this.endpoint.child(target).stringify();
86
+ const request = this.requestConfig();
87
+ request.method = 'POST';
88
+ request.url = url;
89
+ request.data = this.encoder.encode(req);
90
+ return await this.execute(request, resSchema);
91
+ }
92
+ }
93
+ exports.POSTClient = POSTClient;
94
+ const buildQueryString = (request) => {
95
+ return Object.keys(request)
96
+ .map((key) => `${key}=${request[key]}`)
97
+ .join('&');
98
+ };
99
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvaHR0cC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxrREFBa0Q7QUFJbEQscUNBQTJEO0FBSTNEOzs7OztHQUtHO0FBQ0gsTUFBYSxpQkFBaUI7SUFJNUIsWUFBWSxRQUFhLEVBQUUsT0FBdUI7UUFDaEQsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFDekIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7SUFDekIsQ0FBQztJQUVELFNBQVM7UUFDUCxPQUFPLElBQUksU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3BELENBQUM7SUFFRCxVQUFVO1FBQ1IsT0FBTyxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNyRCxDQUFDO0NBQ0Y7QUFoQkQsOENBZ0JDO0FBRUQsTUFBTSxJQUFJO0lBUVIsWUFBWSxRQUFhLEVBQUUsT0FBdUI7UUFDaEQsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDdkQsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7SUFDekIsQ0FBQztJQUVELElBQUksT0FBTztRQUNULE9BQU87WUFDTCxDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVztZQUN4RCxDQUFDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxFQUFFLElBQUksQ0FBQywyQkFBMkI7U0FDbkUsQ0FBQztJQUNKLENBQUM7SUFFRCxhQUFhO1FBQ1gsT0FBTztZQUNMLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztZQUNyQixZQUFZLEVBQUUsYUFBYTtZQUMzQixlQUFlLEVBQUUs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
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const ava_1 = __importDefault(require("ava"));
7
+ const zod_1 = require("zod");
8
+ const encoder_1 = require("./encoder");
9
+ const http_1 = require("./http");
10
+ const url_1 = __importDefault(require("./url"));
11
+ const ENDPOINT = new url_1.default({
12
+ host: '127.0.0.1',
13
+ port: 8080,
14
+ pathPrefix: 'http',
15
+ });
16
+ const factory = new http_1.HTTPClientFactory(ENDPOINT, new encoder_1.JSONEncoderDecoder());
17
+ const MessageSchema = zod_1.z.object({
18
+ id: zod_1.z.number().optional(),
19
+ message: zod_1.z.string().optional(),
20
+ });
21
+ const getClient = factory.getClient();
22
+ const postClient = factory.postClient();
23
+ (0, ava_1.default)('[http] - post echo', async (t) => {
24
+ const [response, error] = await postClient.send('/echo', {
25
+ id: 1,
26
+ message: 'hello',
27
+ }, MessageSchema);
28
+ t.is(error, undefined);
29
+ t.deepEqual(response, { id: 2, message: 'hello' });
30
+ });
31
+ (0, ava_1.default)('[http] - get echo', async (t) => {
32
+ const [response, error] = await getClient.send('/echo', {
33
+ id: 1,
34
+ message: 'hello',
35
+ }, MessageSchema);
36
+ t.is(error, undefined);
37
+ t.deepEqual(response, { id: 2, message: 'hello' });
38
+ });
39
+ (0, ava_1.default)('[http] - get not found', async (t) => {
40
+ const [response, error] = await getClient.send('/not-found', {}, MessageSchema);
41
+ t.is(error === null || error === void 0 ? void 0 : error.message, 'Cannot GET /http/not-found/');
42
+ t.is(response, undefined);
43
+ });
44
+ (0, ava_1.default)('[http] - post not found', async (t) => {
45
+ const [response, error] = await postClient.send('/not-found', {}, MessageSchema);
46
+ t.is(error === null || error === void 0 ? void 0 : error.message, 'Cannot POST /http/not-found/');
47
+ t.is(response, undefined);
48
+ });
49
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaHR0cC5zcGVjLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9odHRwLnNwZWMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw4Q0FBdUI7QUFDdkIsNkJBQXdCO0FBRXhCLHVDQUErQztBQUMvQyxpQ0FBMkM7QUFDM0MsZ0RBQXdCO0FBRXhCLE1BQU0sUUFBUSxHQUFHLElBQUksYUFBRyxDQUFDO0lBQ3ZCLElBQUksRUFBRSxXQUFXO0lBQ2pCLElBQUksRUFBRSxJQUFJO0lBQ1YsVUFBVSxFQUFFLE1BQU07Q0FDbkIsQ0FBQyxDQUFDO0FBRUgsTUFBTSxPQUFPLEdBQUcsSUFBSSx3QkFBaUIsQ0FBQyxRQUFRLEVBQUUsSUFBSSw0QkFBa0IsRUFBRSxDQUFDLENBQUM7QUFFMUUsTUFBTSxhQUFhLEdBQUcsT0FBQyxDQUFDLE1BQU0sQ0FBQztJQUM3QixFQUFFLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtJQUN6QixPQUFPLEVBQUUsT0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsRUFBRTtDQUMvQixDQUFDLENBQUM7QUFJSCxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsU0FBUyxFQUFFLENBQUM7QUFDdEMsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLFVBQVUsRUFBRSxDQUFDO0FBRXhDLElBQUEsYUFBSSxFQUFDLG9CQUFvQixFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRTtJQUNyQyxNQUFNLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxHQUFHLE1BQU0sVUFBVSxDQUFDLElBQUksQ0FDN0MsT0FBTyxFQUNQO1FBQ0UsRUFBRSxFQUFFLENBQUM7UUFDTCxPQUFPLEVBQUUsT0FBTztLQUNqQixFQUNELGFBQWEsQ0FDZCxDQUFDO0lBQ0YsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDdkIsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO0FBQ3JELENBQUMsQ0FBQyxDQUFDO0FBRUgsSUFBQSxhQUFJLEVBQUMsbUJBQW1CLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxFQUFFO0lBQ3BDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEdBQUcsTUFBTSxTQUFTLENBQUMsSUFBSSxDQUM1QyxPQUFPLEVBQ1A7UUFDRSxFQUFFLEVBQUUsQ0FBQztRQUNMLE9BQU8sRUFBRSxPQUFPO0tBQ2pCLEVBQ0QsYUFBYSxDQUNkLENBQUM7SUFDRixDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxTQUFTLENBQUMsQ0FBQztJQUN2QixDQUFDLENBQUMsU0FBUyxDQUFDLFFBQVEsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7QUFDckQsQ0FBQyxDQUFDLENBQUM7QUFFSCxJQUFBLGFBQUksRUFBQyx3QkFBd0IsRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLEVBQUU7SUFDekMsTUFBTSxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsR0FBRyxNQUFNLFNBQVMsQ0FBQyxJQUFJLENBQzVDLFlBQVksRUFDWixFQUFFLEVBQ0YsYUFBYSxDQUNkLENBQUM7SUFDRixDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssYUFBTCxLQUFLLHVCQUFMLEtBQUssQ0FBRSxPQUFPLEVBQUUsNkJBQTZCLENBQUMsQ0FBQztJQUNwRCxDQUFDLENBQUMsRUFBRSxDQUFDLFFBQVEsRUFBRSxTQUFTLENBQUMsQ0FBQztBQUM1QixDQUFDLENBQUMsQ0FBQztBQUVILElBQUEsYUFBSSxFQUFDLHlCQUF5QixFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsRUFBRTtJQUMxQyxNQUFNLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxHQUFHLE1BQU0sVUFBVSxDQUFDLElBQUksQ0FDN0MsWUFBWSxFQUNaLEVBQUUsRUFDRixhQUFhLENBQ2QsQ0FBQztJQUNGLENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBSyxhQUFMLEtBQUssdUJBQUwsS0FBSyxDQUFFLE9BQU8sRUFBRSw4QkFBOEIsQ0FBQyxDQUFDO0lBQ3JELENBQUMsQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQzVCLENBQUMsQ0FBQyxDQUFDIn0=
@@ -0,0 +1,5 @@
1
+ export declare enum Runtime {
2
+ Browser = "browser",
3
+ Node = "node"
4
+ }
5
+ export declare const RUNTIME: Runtime;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RUNTIME = exports.Runtime = void 0;
4
+ var Runtime;
5
+ (function (Runtime) {
6
+ Runtime["Browser"] = "browser";
7
+ Runtime["Node"] = "node";
8
+ })(Runtime = exports.Runtime || (exports.Runtime = {}));
9
+ const detectRuntime = () => {
10
+ if (typeof process !== 'undefined' &&
11
+ process.versions != null &&
12
+ process.versions.node != null) {
13
+ return Runtime.Node;
14
+ }
15
+ if (typeof window !== 'undefined' && typeof window.document !== 'undefined') {
16
+ return Runtime.Browser;
17
+ }
18
+ console.warn('Freighter unable to safely detect runtime, assuming browser');
19
+ return Runtime.Browser;
20
+ };
21
+ exports.RUNTIME = detectRuntime();
22
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVudGltZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9saWIvcnVudGltZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxJQUFZLE9BR1g7QUFIRCxXQUFZLE9BQU87SUFDakIsOEJBQW1CLENBQUE7SUFDbkIsd0JBQWEsQ0FBQTtBQUNmLENBQUMsRUFIVyxPQUFPLEdBQVAsZUFBTyxLQUFQLGVBQU8sUUFHbEI7QUFFRCxNQUFNLGFBQWEsR0FBRyxHQUFZLEVBQUU7SUFDbEMsSUFDRSxPQUFPLE9BQU8sS0FBSyxXQUFXO1FBQzlCLE9BQU8sQ0FBQyxRQUFRLElBQUksSUFBSTtRQUN4QixPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksSUFBSSxJQUFJLEVBQzdCO1FBQ0EsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDO0tBQ3JCO0lBRUQsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLElBQUksT0FBTyxNQUFNLENBQUMsUUFBUSxLQUFLLFdBQVcsRUFBRTtRQUMzRSxPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUM7S0FDeEI7SUFFRCxPQUFPLENBQUMsSUFBSSxDQUFDLDZEQUE2RCxDQUFDLENBQUM7SUFDNUUsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDO0FBQ3pCLENBQUMsQ0FBQztBQUVXLFFBQUEsT0FBTyxHQUFHLGFBQWEsRUFBRSxDQUFDIn0=
@@ -0,0 +1,75 @@
1
+ import { ZodSchema } from 'zod';
2
+ /**
3
+ * Interface for an entity that receives a stream of responses.
4
+ */
5
+ export interface StreamReceiver<RS> {
6
+ /**
7
+ * Receives a response from the stream. It's not safe to call receive
8
+ * concurrently.
9
+ *
10
+ * @returns freighter.EOF: if the server closed the stream nominally.
11
+ * @returns Error: if the server closed the stream abnormally,
12
+ * returns the error the server returned.
13
+ * @raises Error: if the transport fails.
14
+ */
15
+ receive(): Promise<[RS | undefined, Error | undefined]>;
16
+ /**
17
+ * @returns true if the stream has received a response
18
+ */
19
+ received(): boolean;
20
+ }
21
+ /**
22
+ * Interface for an entity that sends a stream of requests.
23
+ */
24
+ export interface StreamSender<RQ> {
25
+ /**
26
+ * Sends a request to the stream. It is not safe to call send concurrently
27
+ * with closeSend or send.
28
+
29
+ * @param req - the request to send.
30
+ * @returns freighter.EOF: if the server closed the stream. The caller
31
+ * can discover the error returned by the server by calling receive().
32
+ * @returns undefined: if the message was sent successfully.
33
+ * @raises freighter.StreamClosed: if the client called close_send()
34
+ * @raises Error: if the transport fails.
35
+ */
36
+ send(req: RQ): Error | undefined;
37
+ }
38
+ /**
39
+ * Extension of the StreamSender interface that allows the client to close the sending
40
+ * direction of the stream when finished issuing requrest.
41
+ */
42
+ export interface StreamSenderCloser<RQ> extends StreamSender<RQ> {
43
+ /**
44
+ * Lets the server know no more messages will be sent. If the client attempts
45
+ * to call send() after calling closeSend(), a freighter.StreamClosed
46
+ * exception will be raised. close_send is idempotent. If the server has
47
+ * already closed the stream, close_send will do nothing.
48
+
49
+ * After calling close_send, the client is responsible for calling receive()
50
+ * to successfully receive the server's acknowledgement.
51
+ */
52
+ closeSend(): void;
53
+ }
54
+ /**
55
+ * Interface for a bidirectional stream between a client and a server.
56
+ */
57
+ export interface Stream<RQ, RS> extends StreamSenderCloser<RQ>, StreamReceiver<RS> {
58
+ }
59
+ /**
60
+ * Interface for a bidirectional stream between a client and a server.
61
+ */
62
+ export interface StreamClient {
63
+ /**
64
+ * Dials the target and returns a stream that can be used to issue requests
65
+ * and receive responses
66
+ *
67
+ * @param target - The target to dial. In some implementations, this may be
68
+ * an endpoint path, or in others, a complete hostname or URL.
69
+ * @param reqSchema - The schema for the request type. This is used to
70
+ * validate the request before sending it.
71
+ * @param resSchema - The schema for the response type. This is used to
72
+ * validate the response before returning it.
73
+ */
74
+ stream<RQ, RS>(target: string, reqSchema: ZodSchema<RQ>, resSchema: ZodSchema<RS>): Promise<Stream<RQ, RS>>;
75
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RyZWFtLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9zdHJlYW0udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
@@ -0,0 +1,14 @@
1
+ import { ZodSchema } from 'zod';
2
+ /**
3
+ * An interface for an entity that implements a simple request-response
4
+ * transport between two entities.
5
+ */
6
+ export interface UnaryClient {
7
+ /**
8
+ * Sends a request to the target server and waits until a response is received.
9
+ * @param target - The target server to send the request to.
10
+ * @param req - The request to send.
11
+ * @param resSchema - The schema to validate the response against.
12
+ */
13
+ send<RQ, RS>(target: string, req: RQ, resSchema: ZodSchema<RS>): Promise<[RS | undefined, Error | undefined]>;
14
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW5hcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3VuYXJ5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIifQ==
@@ -0,0 +1,37 @@
1
+ declare type URLProps = {
2
+ host: string;
3
+ port: number;
4
+ protocol?: string;
5
+ pathPrefix?: string;
6
+ };
7
+ /**
8
+ * URL is a simple class for building and extending URLs.
9
+ */
10
+ export default class URL {
11
+ protocol: string;
12
+ host: string;
13
+ port: number;
14
+ path: string;
15
+ /**
16
+ * @param host - The hostname or IP address of the server.
17
+ * @param port - The port number of the server.
18
+ * @param protocol - The protocol to use for all requests. Defaults to "".
19
+ * @param pathPrefix - A path prefix to use for all requests. Defaults to "".
20
+ */
21
+ constructor({ host, port, protocol, pathPrefix }: URLProps);
22
+ /**
23
+ * Replaces creates a new URL with the specified properties replaced.
24
+ * @param props - The properties to replace.
25
+ * @returns a new URL.
26
+ */
27
+ replace(props: Partial<URLProps>): URL;
28
+ /**
29
+ * Creates a new url with the given path appended to the current path.
30
+ * @param path - the path to append to the URL.
31
+ * @returns a new URL.
32
+ */
33
+ child(path: string): URL;
34
+ /** @returns a string representation of the url */
35
+ stringify(): string;
36
+ }
37
+ export {};
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * URL is a simple class for building and extending URLs.
5
+ */
6
+ class URL {
7
+ /**
8
+ * @param host - The hostname or IP address of the server.
9
+ * @param port - The port number of the server.
10
+ * @param protocol - The protocol to use for all requests. Defaults to "".
11
+ * @param pathPrefix - A path prefix to use for all requests. Defaults to "".
12
+ */
13
+ constructor({ host, port, protocol = '', pathPrefix = '' }) {
14
+ this.protocol = protocol;
15
+ this.host = host;
16
+ this.port = port;
17
+ this.path = formatPath(pathPrefix);
18
+ }
19
+ /**
20
+ * Replaces creates a new URL with the specified properties replaced.
21
+ * @param props - The properties to replace.
22
+ * @returns a new URL.
23
+ */
24
+ replace(props) {
25
+ return new URL({
26
+ host: props.host || this.host,
27
+ port: props.port || this.port,
28
+ protocol: props.protocol || this.protocol,
29
+ pathPrefix: props.pathPrefix || this.path,
30
+ });
31
+ }
32
+ /**
33
+ * Creates a new url with the given path appended to the current path.
34
+ * @param path - the path to append to the URL.
35
+ * @returns a new URL.
36
+ */
37
+ child(path) {
38
+ return new URL(Object.assign(Object.assign({}, this), { pathPrefix: joinPaths(this.path, path) }));
39
+ }
40
+ /** @returns a string representation of the url */
41
+ stringify() {
42
+ return `${this.protocol}://${this.host}:${this.port}/${this.path}`;
43
+ }
44
+ }
45
+ exports.default = URL;
46
+ // joinPath joins the two paths, ensuring there is a single slash between them.
47
+ const joinPaths = (...paths) => {
48
+ return paths.map(formatPath).join('');
49
+ };
50
+ const formatPath = (path) => {
51
+ if (!path.endsWith('/'))
52
+ path += '/';
53
+ if (path.startsWith('/'))
54
+ path = path.slice(1);
55
+ return path;
56
+ };
57
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXJsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi91cmwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFPQTs7R0FFRztBQUNILE1BQXFCLEdBQUc7SUFNdEI7Ozs7O09BS0c7SUFDSCxZQUFZLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxRQUFRLEdBQUcsRUFBRSxFQUFFLFVBQVUsR0FBRyxFQUFFLEVBQVk7UUFDbEUsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFDekIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLElBQUksR0FBRyxVQUFVLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxPQUFPLENBQUMsS0FBd0I7UUFDOUIsT0FBTyxJQUFJLEdBQUcsQ0FBQztZQUNiLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxJQUFJO1lBQzdCLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxJQUFJO1lBQzdCLFFBQVEsRUFBRSxLQUFLLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxRQUFRO1lBQ3pDLFVBQVUsRUFBRSxLQUFLLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyxJQUFJO1NBQzFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsS0FBSyxDQUFDLElBQVk7UUFDaEIsT0FBTyxJQUFJLEdBQUcsaUNBQ1QsSUFBSSxLQUNQLFVBQVUsRUFBRSxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsSUFDdEMsQ0FBQztJQUNMLENBQUM7SUFFRCxrREFBa0Q7SUFDbEQsU0FBUztRQUNQLE9BQU8sR0FBRyxJQUFJLENBQUMsUUFBUSxNQUFNLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDckUsQ0FBQztDQUNGO0FBakRELHNCQWlEQztBQUVELCtFQUErRTtBQUMvRSxNQUFNLFNBQVMsR0FBRyxDQUFDLEdBQUcsS0FBZSxFQUFVLEVBQUU7SUFDL0MsT0FBTyxLQUFLLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUN4QyxDQUFDLENBQUM7QUFFRixNQUFNLFVBQVUsR0FBRyxDQUFDLElBQVksRUFBVSxFQUFFO0lBQzFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQztRQUFFLElBQUksSUFBSSxHQUFHLENBQUM7SUFDckMsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQztRQUFFLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQy9DLE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQyxDQUFDIn0=
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const ava_1 = __importDefault(require("ava"));
7
+ const url_1 = __importDefault(require("./url"));
8
+ (0, ava_1.default)('URL - child', (t) => {
9
+ const endpoint = new url_1.default({
10
+ host: 'localhost',
11
+ port: 8080,
12
+ protocol: 'http',
13
+ pathPrefix: 'api',
14
+ });
15
+ t.is(endpoint.child('test').stringify(), 'http://localhost:8080/api/test/');
16
+ });
17
+ (0, ava_1.default)('URL - child with trailing slash', (t) => {
18
+ const endpoint = new url_1.default({
19
+ host: 'localhost',
20
+ port: 8080,
21
+ protocol: 'http',
22
+ pathPrefix: 'api',
23
+ });
24
+ const child = endpoint.child('test/');
25
+ t.is(child.stringify(), 'http://localhost:8080/api/test/');
26
+ });
27
+ (0, ava_1.default)('URL - replacing protocol', (t) => {
28
+ const endpoint = new url_1.default({
29
+ host: 'localhost',
30
+ port: 8080,
31
+ protocol: 'http',
32
+ pathPrefix: 'api',
33
+ });
34
+ t.is(endpoint.child('test').replace({ protocol: 'https' }).stringify(), 'https://localhost:8080/api/test/');
35
+ });
36
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXJsLnNwZWMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3VybC5zcGVjLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsOENBQXVCO0FBRXZCLGdEQUF3QjtBQUV4QixJQUFBLGFBQUksRUFBQyxhQUFhLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRTtJQUN4QixNQUFNLFFBQVEsR0FBRyxJQUFJLGFBQUcsQ0FBQztRQUN2QixJQUFJLEVBQUUsV0FBVztRQUNqQixJQUFJLEVBQUUsSUFBSTtRQUNWLFFBQVEsRUFBRSxNQUFNO1FBQ2hCLFVBQVUsRUFBRSxLQUFLO0tBQ2xCLENBQUMsQ0FBQztJQUNILENBQUMsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxpQ0FBaUMsQ0FBQyxDQUFDO0FBQzlFLENBQUMsQ0FBQyxDQUFDO0FBRUgsSUFBQSxhQUFJLEVBQUMsaUNBQWlDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRTtJQUM1QyxNQUFNLFFBQVEsR0FBRyxJQUFJLGFBQUcsQ0FBQztRQUN2QixJQUFJLEVBQUUsV0FBVztRQUNqQixJQUFJLEVBQUUsSUFBSTtRQUNWLFFBQVEsRUFBRSxNQUFNO1FBQ2hCLFVBQVUsRUFBRSxLQUFLO0tBQ2xCLENBQUMsQ0FBQztJQUNILE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDdEMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFLEVBQUUsaUNBQWlDLENBQUMsQ0FBQztBQUM3RCxDQUFDLENBQUMsQ0FBQztBQUVILElBQUEsYUFBSSxFQUFDLDBCQUEwQixFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUU7SUFDckMsTUFBTSxRQUFRLEdBQUcsSUFBSSxhQUFHLENBQUM7UUFDdkIsSUFBSSxFQUFFLFdBQVc7UUFDakIsSUFBSSxFQUFFLElBQUk7UUFDVixRQUFRLEVBQUUsTUFBTTtRQUNoQixVQUFVLEVBQUUsS0FBSztLQUNsQixDQUFDLENBQUM7SUFDSCxDQUFDLENBQUMsRUFBRSxDQUNGLFFBQVEsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQ2pFLGtDQUFrQyxDQUNuQyxDQUFDO0FBQ0osQ0FBQyxDQUFDLENBQUMifQ==
@@ -0,0 +1,21 @@
1
+ import { ZodSchema } from 'zod';
2
+ import { EncoderDecoder } from './encoder';
3
+ import { Stream, StreamClient } from './stream';
4
+ import URL from './url';
5
+ /**
6
+ * WebSocketClient is an implementation of StreamClient that is backed by
7
+ * websockets.
8
+ */
9
+ export declare class WebSocketClient implements StreamClient {
10
+ url: URL;
11
+ encoder: EncoderDecoder;
12
+ static readonly MESSAGE_TYPE = "arraybuffer";
13
+ /**
14
+ * @param encoder - The encoder to use for encoding messages and decoding
15
+ * responses.
16
+ * @param baseURL - A base url to use as a prefix for all requests.
17
+ */
18
+ constructor(encoder: EncoderDecoder, baseURL: URL);
19
+ /** Implements the StreamClient interface. */
20
+ stream<RQ, RS>(target: string, reqSchema: ZodSchema<RQ>, resSchema: ZodSchema<RS>): Promise<Stream<RQ, RS>>;
21
+ }
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WebSocketClient = void 0;
4
+ const zod_1 = require("zod");
5
+ const errors_1 = require("./errors");
6
+ const runtime_1 = require("./runtime");
7
+ const resolveWebsocketProvider = () => {
8
+ if (runtime_1.RUNTIME == runtime_1.Runtime.Node)
9
+ return require('ws');
10
+ return WebSocket;
11
+ };
12
+ var MessageType;
13
+ (function (MessageType) {
14
+ MessageType["Data"] = "data";
15
+ MessageType["Close"] = "close";
16
+ })(MessageType || (MessageType = {}));
17
+ const MessageSchema = zod_1.z.object({
18
+ type: zod_1.z.nativeEnum(MessageType),
19
+ payload: zod_1.z.unknown().optional(),
20
+ error: zod_1.z.optional(errors_1.ErrorPayloadSchema),
21
+ });
22
+ var CloseCode;
23
+ (function (CloseCode) {
24
+ CloseCode[CloseCode["Normal"] = 1000] = "Normal";
25
+ CloseCode[CloseCode["GoingAway"] = 1001] = "GoingAway";
26
+ })(CloseCode || (CloseCode = {}));
27
+ /**
28
+ * WebSocketStream is an implementation of Stream that is backed by a websocket.
29
+ */
30
+ class WebSocketStream {
31
+ constructor(ws, encoder, reqSchema, resSchema) {
32
+ this.receiveDataQueue = [];
33
+ this.receiveCallbacksQueue = [];
34
+ this.encoder = encoder;
35
+ this.reqSchema = reqSchema;
36
+ this.resSchema = resSchema;
37
+ this.ws = ws;
38
+ this.send_closed = false;
39
+ this.listenForMessages();
40
+ }
41
+ /** Implements the Stream protocol */
42
+ send(req) {
43
+ if (this.server_closed)
44
+ return new errors_1.EOF();
45
+ if (this.send_closed)
46
+ throw new errors_1.StreamClosed();
47
+ this.ws.send(this.encoder.encode({
48
+ type: MessageType.Data,
49
+ payload: req,
50
+ error: undefined,
51
+ }));
52
+ return undefined;
53
+ }
54
+ /** Implements the Stream protocol */
55
+ async receive() {
56
+ if (this.server_closed)
57
+ return [undefined, this.server_closed];
58
+ const msg = await this.receiveMsg();
59
+ if (msg.type == MessageType.Close) {
60
+ if (!msg.error)
61
+ throw new Error('Message error must be defined');
62
+ this.server_closed = (0, errors_1.decodeError)(msg.error);
63
+ return [undefined, this.server_closed];
64
+ }
65
+ return [this.resSchema.parse(msg.payload), undefined];
66
+ }
67
+ /** Implements the Stream protocol */
68
+ received() {
69
+ return this.receiveDataQueue.length !== 0;
70
+ }
71
+ /** Implements the Stream protocol */
72
+ closeSend() {
73
+ if (this.send_closed || this.server_closed) {
74
+ return undefined;
75
+ }
76
+ const msg = { type: MessageType.Close };
77
+ try {
78
+ this.ws.send(this.encoder.encode(msg));
79
+ }
80
+ finally {
81
+ this.send_closed = true;
82
+ }
83
+ return undefined;
84
+ }
85
+ async receiveMsg() {
86
+ if (this.receiveDataQueue.length !== 0) {
87
+ const msg = this.receiveDataQueue.shift();
88
+ if (msg)
89
+ return msg;
90
+ throw new Error('unexpected undefined message');
91
+ }
92
+ return new Promise((resolve, reject) => {
93
+ this.receiveCallbacksQueue.push({ resolve, reject });
94
+ });
95
+ }
96
+ listenForMessages() {
97
+ this.ws.onmessage = (ev) => {
98
+ const msg = this.encoder.decode(ev.data, MessageSchema);
99
+ if (this.receiveCallbacksQueue.length > 0) {
100
+ const callback = this.receiveCallbacksQueue.shift();
101
+ if (callback)
102
+ callback.resolve(msg);
103
+ else
104
+ throw new Error('Unexpected empty callback queue');
105
+ }
106
+ else {
107
+ this.receiveDataQueue.push(msg);
108
+ }
109
+ };
110
+ this.ws.onclose = (ev) => {
111
+ if ([CloseCode.Normal, CloseCode.GoingAway].includes(ev.code)) {
112
+ this.server_closed = new errors_1.EOF();
113
+ }
114
+ else {
115
+ this.server_closed = new errors_1.StreamClosed();
116
+ }
117
+ };
118
+ }
119
+ }
120
+ /**
121
+ * WebSocketClient is an implementation of StreamClient that is backed by
122
+ * websockets.
123
+ */
124
+ class WebSocketClient {
125
+ /**
126
+ * @param encoder - The encoder to use for encoding messages and decoding
127
+ * responses.
128
+ * @param baseURL - A base url to use as a prefix for all requests.
129
+ */
130
+ constructor(encoder, baseURL) {
131
+ this.url = baseURL.replace({ protocol: 'ws' });
132
+ this.encoder = encoder;
133
+ }
134
+ /** Implements the StreamClient interface. */
135
+ async stream(target, reqSchema, resSchema) {
136
+ const ResolvedWebSocket = resolveWebsocketProvider();
137
+ const url = this.url.child(target).stringify() +
138
+ '?contentType=' +
139
+ this.encoder.contentType;
140
+ const ws = new ResolvedWebSocket(url);
141
+ ws.binaryType = WebSocketClient.MESSAGE_TYPE;
142
+ return new Promise((resolve, reject) => {
143
+ ws.onopen = () => {
144
+ resolve(new WebSocketStream(ws, this.encoder, reqSchema, resSchema));
145
+ };
146
+ ws.onerror = (ev) => {
147
+ reject(ev);
148
+ };
149
+ });
150
+ }
151
+ }
152
+ exports.WebSocketClient = WebSocketClient;
153
+ WebSocketClient.MESSAGE_TYPE = 'arraybuffer';
154
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic29ja2V0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi93ZWJzb2NrZXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkJBQW1DO0FBR25DLHFDQUE4RTtBQUM5RSx1Q0FBNkM7QUFJN0MsTUFBTSx3QkFBd0IsR0FBRyxHQUFxQixFQUFFO0lBQ3RELElBQUksaUJBQU8sSUFBSSxpQkFBTyxDQUFDLElBQUk7UUFBRSxPQUFPLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNsRCxPQUFPLFNBQVMsQ0FBQztBQUNuQixDQUFDLENBQUM7QUFFRixJQUFLLFdBR0o7QUFIRCxXQUFLLFdBQVc7SUFDZCw0QkFBYSxDQUFBO0lBQ2IsOEJBQWUsQ0FBQTtBQUNqQixDQUFDLEVBSEksV0FBVyxLQUFYLFdBQVcsUUFHZjtBQUVELE1BQU0sYUFBYSxHQUFHLE9BQUMsQ0FBQyxNQUFNLENBQUM7SUFDN0IsSUFBSSxFQUFFLE9BQUMsQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDO0lBQy9CLE9BQU8sRUFBRSxPQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQy9CLEtBQUssRUFBRSxPQUFDLENBQUMsUUFBUSxDQUFDLDJCQUFrQixDQUFDO0NBQ3RDLENBQUMsQ0FBQztBQUlILElBQUssU0FHSjtBQUhELFdBQUssU0FBUztJQUNaLGdEQUFhLENBQUE7SUFDYixzREFBZ0IsQ0FBQTtBQUNsQixDQUFDLEVBSEksU0FBUyxLQUFULFNBQVMsUUFHYjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxlQUFlO0lBZ0JuQixZQUNFLEVBQWEsRUFDYixPQUF1QixFQUN2QixTQUEwQixFQUMxQixTQUEwQjtRQVZwQixxQkFBZ0IsR0FBYyxFQUFFLENBQUM7UUFDakMsMEJBQXFCLEdBR3ZCLEVBQUUsQ0FBQztRQVFQLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FB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
@@ -0,0 +1 @@
1
+ export {};