@rest-vir/define-service 0.0.2

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 (50) hide show
  1. package/LICENSE-CC0 +121 -0
  2. package/LICENSE-MIT +21 -0
  3. package/README.md +88 -0
  4. package/dist/augments/json.d.ts +8 -0
  5. package/dist/augments/json.js +13 -0
  6. package/dist/dev-port/find-dev-port.d.ts +132 -0
  7. package/dist/dev-port/find-dev-port.js +156 -0
  8. package/dist/endpoint/endpoint-path.d.ts +27 -0
  9. package/dist/endpoint/endpoint-path.js +14 -0
  10. package/dist/endpoint/endpoint.d.ts +198 -0
  11. package/dist/endpoint/endpoint.js +80 -0
  12. package/dist/frontend-connect/connect-web-socket.d.ts +95 -0
  13. package/dist/frontend-connect/connect-web-socket.js +64 -0
  14. package/dist/frontend-connect/fetch-endpoint.d.ts +199 -0
  15. package/dist/frontend-connect/fetch-endpoint.js +135 -0
  16. package/dist/frontend-connect/generate-api.d.ts +102 -0
  17. package/dist/frontend-connect/generate-api.js +83 -0
  18. package/dist/frontend-connect/mock-client-web-socket.d.ts +187 -0
  19. package/dist/frontend-connect/mock-client-web-socket.js +198 -0
  20. package/dist/frontend-connect/web-socket-protocol-parse.d.ts +10 -0
  21. package/dist/frontend-connect/web-socket-protocol-parse.js +111 -0
  22. package/dist/index.d.ts +23 -0
  23. package/dist/index.js +23 -0
  24. package/dist/service/define-service.d.ts +19 -0
  25. package/dist/service/define-service.js +133 -0
  26. package/dist/service/match-url.d.ts +30 -0
  27. package/dist/service/match-url.js +31 -0
  28. package/dist/service/minimal-service.d.ts +44 -0
  29. package/dist/service/minimal-service.js +1 -0
  30. package/dist/service/service-definition.d.ts +80 -0
  31. package/dist/service/service-definition.error.d.ts +35 -0
  32. package/dist/service/service-definition.error.js +34 -0
  33. package/dist/service/service-definition.js +1 -0
  34. package/dist/util/mock-fetch.d.ts +107 -0
  35. package/dist/util/mock-fetch.js +199 -0
  36. package/dist/util/no-param.d.ts +16 -0
  37. package/dist/util/no-param.js +8 -0
  38. package/dist/util/origin.d.ts +43 -0
  39. package/dist/util/origin.js +19 -0
  40. package/dist/util/path-to-regexp.d.ts +54 -0
  41. package/dist/util/path-to-regexp.js +307 -0
  42. package/dist/util/search-params.d.ts +9 -0
  43. package/dist/util/search-params.js +1 -0
  44. package/dist/web-socket/common-web-socket.d.ts +103 -0
  45. package/dist/web-socket/common-web-socket.js +28 -0
  46. package/dist/web-socket/overwrite-web-socket-methods.d.ts +276 -0
  47. package/dist/web-socket/overwrite-web-socket-methods.js +210 -0
  48. package/dist/web-socket/web-socket-definition.d.ts +170 -0
  49. package/dist/web-socket/web-socket-definition.js +78 -0
  50. package/package.json +68 -0
@@ -0,0 +1,307 @@
1
+ /* eslint-disable @typescript-eslint/no-non-null-assertion */
2
+ // cspell:ignore Embrey
3
+ /* node:coverage disable */
4
+ /**
5
+ * This file was copied from
6
+ * https://github.com/pillarjs/path-to-regexp/blob/39e861d02d959ba99d0632af994ab48d4a8eeb14/src/index.ts
7
+ * because its published package on Npm is not browser friendly. It has been modified here to remove
8
+ * all code not used in rest-vir and to meet rest-vir's coding standards.
9
+ *
10
+ * The original package and file source have the following license:
11
+ *
12
+ * The MIT License (MIT)
13
+ *
14
+ * Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
15
+ *
16
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
17
+ * associated documentation files (the "Software"), to deal in the Software without restriction,
18
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
19
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
20
+ * furnished to do so, subject to the following conditions:
21
+ *
22
+ * The above copyright notice and this permission notice shall be included in all copies or
23
+ * substantial portions of the Software.
24
+ *
25
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
26
+ * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
28
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30
+ */
31
+ const DEFAULT_DELIMITER = '/';
32
+ const ID_START = /^[$_\p{ID_Start}]$/u;
33
+ const ID_CONTINUE = /^[$\u200c\u200d\p{ID_Continue}]$/u;
34
+ const DEBUG_URL = 'https://git.new/pathToRegexpError';
35
+ const SIMPLE_TOKENS = {
36
+ // Groups.
37
+ '{': '{',
38
+ '}': '}',
39
+ // Reserved.
40
+ '(': '(',
41
+ ')': ')',
42
+ '[': '[',
43
+ ']': ']',
44
+ '+': '+',
45
+ '?': '?',
46
+ '!': '!',
47
+ };
48
+ /** Escape a regular expression string. */
49
+ function escape(str) {
50
+ return str.replace(/[.+*?^${}()[\]|/\\]/g, String.raw `\$&`);
51
+ }
52
+ /** Tokenize input string. */
53
+ function* lexer(str) {
54
+ const chars = str.split('');
55
+ let i = 0;
56
+ function name() {
57
+ let value = '';
58
+ if (ID_START.test(chars[++i])) {
59
+ value += chars[i];
60
+ while (ID_CONTINUE.test(chars[++i])) {
61
+ value += chars[i];
62
+ }
63
+ }
64
+ else if (chars[i] === '"') {
65
+ let pos = i;
66
+ while (i < chars.length) {
67
+ if (chars[++i] === '"') {
68
+ i++;
69
+ pos = 0;
70
+ break;
71
+ }
72
+ if (chars[i] === '\\') {
73
+ value += chars[++i];
74
+ }
75
+ else {
76
+ value += chars[i];
77
+ }
78
+ }
79
+ if (pos) {
80
+ throw new TypeError(`Unterminated quote at ${pos}: ${DEBUG_URL}`);
81
+ }
82
+ }
83
+ if (!value) {
84
+ throw new TypeError(`Missing parameter name at ${i}: ${DEBUG_URL}`);
85
+ }
86
+ return value;
87
+ }
88
+ while (i < chars.length) {
89
+ const value = chars[i];
90
+ const type = SIMPLE_TOKENS[value];
91
+ if (type) {
92
+ yield { type, index: i++, value };
93
+ }
94
+ else if (value === '\\') {
95
+ yield { type: 'ESCAPED', index: i++, value: chars[i++] };
96
+ }
97
+ else if (value === ':') {
98
+ const value = name();
99
+ yield { type: 'PARAM', index: i, value };
100
+ }
101
+ else if (value === '*') {
102
+ const value = name();
103
+ yield { type: 'WILDCARD', index: i, value };
104
+ }
105
+ else {
106
+ yield { type: 'CHAR', index: i, value: chars[i++] };
107
+ }
108
+ }
109
+ return { type: 'END', index: i, value: '' };
110
+ }
111
+ class Iter {
112
+ tokens;
113
+ _peek;
114
+ constructor(tokens) {
115
+ this.tokens = tokens;
116
+ }
117
+ peek() {
118
+ if (!this._peek) {
119
+ const next = this.tokens.next();
120
+ this._peek = next.value;
121
+ }
122
+ return this._peek;
123
+ }
124
+ tryConsume(type) {
125
+ const token = this.peek();
126
+ if (token.type !== type) {
127
+ return;
128
+ }
129
+ this._peek = undefined; // Reset after consumed.
130
+ return token.value;
131
+ }
132
+ consume(type) {
133
+ const value = this.tryConsume(type);
134
+ if (value !== undefined) {
135
+ return value;
136
+ }
137
+ const { type: nextType, index } = this.peek();
138
+ throw new TypeError(`Unexpected ${nextType} at ${index}, expected ${type}: ${DEBUG_URL}`);
139
+ }
140
+ text() {
141
+ let result = '';
142
+ let value;
143
+ while ((value = this.tryConsume('CHAR') || this.tryConsume('ESCAPED'))) {
144
+ result += value;
145
+ }
146
+ return result;
147
+ }
148
+ }
149
+ /** Tokenized path instance. */
150
+ class TokenData {
151
+ tokens;
152
+ constructor(tokens) {
153
+ this.tokens = tokens;
154
+ }
155
+ }
156
+ /** Parse a string for the raw tokens. */
157
+ function parse(stringToParse) {
158
+ const iterator = new Iter(lexer(stringToParse));
159
+ function consume(endType) {
160
+ const tokens = [];
161
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
162
+ while (true) {
163
+ const path = iterator.text();
164
+ if (path) {
165
+ tokens.push({ type: 'text', value: path });
166
+ }
167
+ const param = iterator.tryConsume('PARAM');
168
+ if (param) {
169
+ tokens.push({
170
+ type: 'param',
171
+ name: param,
172
+ });
173
+ continue;
174
+ }
175
+ const wildcard = iterator.tryConsume('WILDCARD');
176
+ if (wildcard) {
177
+ tokens.push({
178
+ type: 'wildcard',
179
+ name: wildcard,
180
+ });
181
+ continue;
182
+ }
183
+ const open = iterator.tryConsume('{');
184
+ if (open) {
185
+ tokens.push({
186
+ type: 'group',
187
+ tokens: consume('}'),
188
+ });
189
+ continue;
190
+ }
191
+ iterator.consume(endType);
192
+ return tokens;
193
+ }
194
+ }
195
+ const tokens = consume('END');
196
+ return new TokenData(tokens);
197
+ }
198
+ /**
199
+ * Transform a path into a match function.
200
+ *
201
+ * This is from the [path-to-regexp](https://www.npmjs.com/package/path-to-regexp) package.
202
+ *
203
+ * @category Internal
204
+ * @category Package : @rest-vir/define-service
205
+ * @package [`@rest-vir/define-service`](https://www.npmjs.com/package/@rest-vir/define-service)
206
+ */
207
+ export function match(path) {
208
+ const { regexp, keys } = pathToRegexp(path);
209
+ const decoders = keys.map((key) => {
210
+ if (key.type === 'param') {
211
+ return decodeURIComponent;
212
+ }
213
+ return (value) => value.split(DEFAULT_DELIMITER).map(decodeURIComponent);
214
+ });
215
+ return function match(input) {
216
+ const m = regexp.exec(input);
217
+ if (!m) {
218
+ return false;
219
+ }
220
+ const path = m[0];
221
+ const params = Object.create(null);
222
+ for (let i = 1; i < m.length; i++) {
223
+ if (m[i] === undefined) {
224
+ continue;
225
+ }
226
+ const key = keys[i - 1];
227
+ const decoder = decoders[i - 1];
228
+ params[key.name] = decoder(m[i]);
229
+ }
230
+ return { path, params };
231
+ };
232
+ }
233
+ function pathToRegexp(path) {
234
+ const keys = [];
235
+ const sources = [];
236
+ const flags = 'i';
237
+ for (const seq of flat(path)) {
238
+ sources.push(toRegExp(seq, keys));
239
+ }
240
+ let pattern = `^(?:${sources.join('|')})`;
241
+ pattern += `(?:${escape(DEFAULT_DELIMITER)}$)?`;
242
+ pattern += '$';
243
+ const regexp = new RegExp(pattern, flags);
244
+ return { regexp, keys };
245
+ }
246
+ /** Path or array of paths to normalize. */
247
+ function* flat(path) {
248
+ const data = parse(path);
249
+ yield* flatten(data.tokens, 0, []);
250
+ }
251
+ /** Generate a flat list of sequence tokens from the given tokens. */
252
+ function* flatten(tokens, index, init) {
253
+ if (index === tokens.length) {
254
+ return yield init;
255
+ }
256
+ const token = tokens[index];
257
+ if (token.type === 'group') {
258
+ for (const seq of flatten(token.tokens, 0, init.slice())) {
259
+ yield* flatten(tokens, index + 1, seq);
260
+ }
261
+ }
262
+ else {
263
+ init.push(token);
264
+ }
265
+ yield* flatten(tokens, index + 1, init);
266
+ }
267
+ /** Transform a flat sequence of tokens into a regular expression. */
268
+ function toRegExp(tokens, keys) {
269
+ let result = '';
270
+ let backtrack = '';
271
+ let isSafeSegmentParam = true;
272
+ for (const token of tokens) {
273
+ if (token.type === 'text') {
274
+ result += escape(token.value);
275
+ backtrack += token.value;
276
+ isSafeSegmentParam ||= token.value.includes(DEFAULT_DELIMITER);
277
+ }
278
+ else {
279
+ if (!isSafeSegmentParam && !backtrack) {
280
+ throw new TypeError(`Missing text after "${token.name}": ${DEBUG_URL}`);
281
+ }
282
+ if (token.type === 'param') {
283
+ result += `(${negate(DEFAULT_DELIMITER, isSafeSegmentParam ? '' : backtrack)}+)`;
284
+ }
285
+ else {
286
+ result += `([\\s\\S]+)`;
287
+ }
288
+ keys.push(token);
289
+ backtrack = '';
290
+ isSafeSegmentParam = false;
291
+ }
292
+ }
293
+ return result;
294
+ }
295
+ /** Block backtracking on previous text and ignore delimiter string. */
296
+ function negate(delimiter, backtrack) {
297
+ if (backtrack.length < 2) {
298
+ if (delimiter.length < 2) {
299
+ return `[^${escape(delimiter + backtrack)}]`;
300
+ }
301
+ return `(?:(?!${escape(delimiter)})[^${escape(backtrack)}])`;
302
+ }
303
+ if (delimiter.length < 2) {
304
+ return `(?:(?!${escape(backtrack)})[^${escape(delimiter)}])`;
305
+ }
306
+ return `(?:(?!${escape(backtrack)}|${escape(delimiter)})[\\s\\S])`;
307
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * The base, generic type for a parsed search params object, extracted from a request URL. If there
3
+ * are no search params, this will be an empty object.
4
+ *
5
+ * @category Internal
6
+ * @category Package : @rest-vir/define-service
7
+ * @package [`@rest-vir/define-service`](https://www.npmjs.com/package/@rest-vir/define-service)
8
+ */
9
+ export type BaseSearchParams = Record<string, string[]>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,103 @@
1
+ import type { AnyFunction } from '@augment-vir/common';
2
+ /**
3
+ * A WebSocket interface that matches both [client-side
4
+ * WebSockets](https://developer.mozilla.org/docs/Web/API/WebSocket) and [host-side
5
+ * WebSockets](https://github.com/websockets/ws/blob/HEAD/doc/ws.md#class-websocket).
6
+ *
7
+ * @category Internal
8
+ * @category Package : @rest-vir/define-service
9
+ * @package [`@rest-vir/define-service`](https://www.npmjs.com/package/@rest-vir/define-service)
10
+ */
11
+ export declare abstract class CommonWebSocket {
12
+ constructor(url: string | URL, protocols?: string | string[]);
13
+ /**
14
+ * A `WebSocket.send` method that is compatible with the native method
15
+ * (https://developer.mozilla.org/docs/Web/API/WebSocket/send) and the `ws` package's method
16
+ * (https://github.com/websockets/ws/blob/HEAD/doc/ws.md#websocketsenddata-options-callback)
17
+ */
18
+ abstract send: (data: any) => void;
19
+ /**
20
+ * A `WebSocket.readyState` property that is compatible with the native property
21
+ * (https://developer.mozilla.org/docs/Web/API/WebSocket/readyState) and the `ws` package's
22
+ * property (https://github.com/websockets/ws/blob/HEAD/doc/ws.md#websocketreadystate)
23
+ */
24
+ abstract readyState: CommonWebSocketState;
25
+ /**
26
+ * A `WebSocket.addEventListener` method that is compatible with the native method
27
+ * (https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener) and the `ws`
28
+ * package's method
29
+ * (https://github.com/websockets/ws/blob/HEAD/doc/ws.md#websocketaddeventlistenertype-listener-options)
30
+ */
31
+ abstract addEventListener<const EventName extends keyof CommonWebSocketEventMap>(eventName: EventName, listener: (event: CommonWebSocketEventMap[EventName]) => void, options?: CommonWebSocketListenerOptions): void;
32
+ /**
33
+ * A `WebSocket.removeEventListener` method that is compatible with the native method
34
+ * (https://developer.mozilla.org/docs/Web/API/EventTarget/removeEventListener) and the `ws`
35
+ * package's method
36
+ * (https://github.com/websockets/ws/blob/HEAD/doc/ws.md#websocketremoveeventlistenertype-listener)
37
+ */
38
+ abstract removeEventListener<const EventName extends keyof CommonWebSocketEventMap>(eventName: EventName, listener: AnyFunction): void;
39
+ /**
40
+ * A `WebSocket.close` method that is compatible with the native method
41
+ * (https://developer.mozilla.org/docs/Web/API/WebSocket/close) and the `ws` package's method
42
+ * (https://github.com/websockets/ws/blob/HEAD/doc/ws.md#websocketclosecode-reason)
43
+ */
44
+ abstract close(): void;
45
+ }
46
+ /**
47
+ * `WebSocket.addEventListener` options that are compatible with both the native method
48
+ * (https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener) and the `ws` package's
49
+ * method
50
+ * (https://github.com/websockets/ws/blob/HEAD/doc/ws.md#websocketaddeventlistenertype-listener-options)
51
+ *
52
+ * @category Internal
53
+ * @category Package : @rest-vir/define-service
54
+ * @package [`@rest-vir/define-service`](https://www.npmjs.com/package/@rest-vir/define-service)
55
+ */
56
+ export type CommonWebSocketListenerOptions = {
57
+ once?: boolean;
58
+ };
59
+ /**
60
+ * All values for
61
+ * [WebSocket.readyState](https://developer.mozilla.org/docs/Web/API/WebSocket/readyState).
62
+ *
63
+ * @category Internal
64
+ * @category Package : @rest-vir/define-service
65
+ * @package [`@rest-vir/define-service`](https://www.npmjs.com/package/@rest-vir/define-service)
66
+ */
67
+ export declare enum CommonWebSocketState {
68
+ Connecting = 0,
69
+ Open = 1,
70
+ Closing = 2,
71
+ Closed = 3
72
+ }
73
+ /**
74
+ * A mapping of WebSocket events that are compatible with both [client-side
75
+ * WebSockets](https://developer.mozilla.org/docs/Web/API/WebSocket) and [host-side
76
+ * WebSockets](https://github.com/websockets/ws/blob/HEAD/doc/ws.md#class-websocket).
77
+ *
78
+ * @category Internal
79
+ * @category Package : @rest-vir/define-service
80
+ * @package [`@rest-vir/define-service`](https://www.npmjs.com/package/@rest-vir/define-service)
81
+ */
82
+ export type CommonWebSocketEventMap = {
83
+ open: {
84
+ target: CommonWebSocket;
85
+ type: string;
86
+ };
87
+ error: {
88
+ target: CommonWebSocket;
89
+ type: string;
90
+ };
91
+ close: {
92
+ code: number;
93
+ reason: string;
94
+ wasClean: boolean;
95
+ target: CommonWebSocket;
96
+ type: string;
97
+ };
98
+ message: {
99
+ data: unknown;
100
+ target: CommonWebSocket;
101
+ type: string;
102
+ };
103
+ };
@@ -0,0 +1,28 @@
1
+ /**
2
+ * A WebSocket interface that matches both [client-side
3
+ * WebSockets](https://developer.mozilla.org/docs/Web/API/WebSocket) and [host-side
4
+ * WebSockets](https://github.com/websockets/ws/blob/HEAD/doc/ws.md#class-websocket).
5
+ *
6
+ * @category Internal
7
+ * @category Package : @rest-vir/define-service
8
+ * @package [`@rest-vir/define-service`](https://www.npmjs.com/package/@rest-vir/define-service)
9
+ */
10
+ export class CommonWebSocket {
11
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
12
+ constructor(url, protocols) { }
13
+ }
14
+ /**
15
+ * All values for
16
+ * [WebSocket.readyState](https://developer.mozilla.org/docs/Web/API/WebSocket/readyState).
17
+ *
18
+ * @category Internal
19
+ * @category Package : @rest-vir/define-service
20
+ * @package [`@rest-vir/define-service`](https://www.npmjs.com/package/@rest-vir/define-service)
21
+ */
22
+ export var CommonWebSocketState;
23
+ (function (CommonWebSocketState) {
24
+ CommonWebSocketState[CommonWebSocketState["Connecting"] = 0] = "Connecting";
25
+ CommonWebSocketState[CommonWebSocketState["Open"] = 1] = "Open";
26
+ CommonWebSocketState[CommonWebSocketState["Closing"] = 2] = "Closing";
27
+ CommonWebSocketState[CommonWebSocketState["Closed"] = 3] = "Closed";
28
+ })(CommonWebSocketState || (CommonWebSocketState = {}));