prool 0.0.0 → 0.0.1

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 (46) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +21 -0
  3. package/_lib/exports/index.d.ts +4 -0
  4. package/_lib/exports/index.d.ts.map +1 -0
  5. package/_lib/exports/index.js +4 -0
  6. package/_lib/exports/index.js.map +1 -0
  7. package/_lib/exports/instances.d.ts +2 -0
  8. package/_lib/exports/instances.d.ts.map +1 -0
  9. package/_lib/exports/instances.js +2 -0
  10. package/_lib/exports/instances.js.map +1 -0
  11. package/_lib/instance.d.ts +111 -0
  12. package/_lib/instance.d.ts.map +1 -0
  13. package/_lib/instance.js +141 -0
  14. package/_lib/instance.js.map +1 -0
  15. package/_lib/instances/anvil.d.ts +459 -0
  16. package/_lib/instances/anvil.d.ts.map +1 -0
  17. package/_lib/instances/anvil.js +74 -0
  18. package/_lib/instances/anvil.js.map +1 -0
  19. package/_lib/pool.d.ts +38 -0
  20. package/_lib/pool.d.ts.map +1 -0
  21. package/_lib/pool.js +134 -0
  22. package/_lib/pool.js.map +1 -0
  23. package/_lib/proxy.d.ts +21 -0
  24. package/_lib/proxy.d.ts.map +1 -0
  25. package/_lib/proxy.js +93 -0
  26. package/_lib/proxy.js.map +1 -0
  27. package/_lib/utils.d.ts +35 -0
  28. package/_lib/utils.d.ts.map +1 -0
  29. package/_lib/utils.js +71 -0
  30. package/_lib/utils.js.map +1 -0
  31. package/exports/index.test.ts +12 -0
  32. package/exports/index.ts +20 -0
  33. package/exports/instances.test.ts +10 -0
  34. package/exports/instances.ts +1 -0
  35. package/instance.test.ts +311 -0
  36. package/instance.ts +277 -0
  37. package/instances/anvil.test.ts +130 -0
  38. package/instances/anvil.ts +322 -0
  39. package/package.json +39 -8
  40. package/pool.test.ts +209 -0
  41. package/pool.ts +183 -0
  42. package/proxy.test.ts +294 -0
  43. package/proxy.ts +135 -0
  44. package/tsconfig.build.tsbuildinfo +1 -0
  45. package/utils.test.ts +44 -0
  46. package/utils.ts +92 -0
package/_lib/pool.js ADDED
@@ -0,0 +1,134 @@
1
+ import getPort from 'get-port';
2
+ /**
3
+ * Defines an instance pool. Instances can be started, cached, and stopped against an identifier.
4
+ *
5
+ * @example
6
+ * ```
7
+ * const pool = definePool({
8
+ * instance: anvil(),
9
+ * })
10
+ *
11
+ * const instance_1 = await pool.start(1)
12
+ * const instance_2 = await pool.start(2)
13
+ * const instance_3 = await pool.start(3)
14
+ * ```
15
+ */
16
+ export function definePool(parameters) {
17
+ const { instance, limit } = parameters;
18
+ const instances = new Map();
19
+ // Define promise instances for mutators to avoid race conditions, and return
20
+ // identical instances of the promises (instead of duplicating them).
21
+ // We utilize `Promise.withResolvers` instead of `new Promise((resolve, reject) => ...)`
22
+ // to avoid async Promise executor functions (https://biomejs.dev/linter/rules/no-async-promise-executor/).
23
+ const promises = {
24
+ destroy: new Map(),
25
+ destroyAll: undefined,
26
+ start: new Map(),
27
+ stop: new Map(),
28
+ stopAll: undefined,
29
+ };
30
+ return {
31
+ _internal: {
32
+ instance,
33
+ },
34
+ async destroy(key) {
35
+ const destroyPromise = promises.destroy.get(key);
36
+ if (destroyPromise)
37
+ return destroyPromise;
38
+ const resolver = Promise.withResolvers();
39
+ try {
40
+ promises.destroy.set(key, resolver.promise);
41
+ await this.stop(key);
42
+ instances.delete(key);
43
+ resolver.resolve();
44
+ }
45
+ catch (error) {
46
+ resolver.reject(error);
47
+ }
48
+ return resolver.promise;
49
+ },
50
+ async destroyAll() {
51
+ if (promises.destroyAll)
52
+ return promises.destroyAll;
53
+ const resolver = Promise.withResolvers();
54
+ try {
55
+ promises.destroyAll = resolver.promise;
56
+ await Promise.all([...instances.keys()].map((key) => this.destroy(key)));
57
+ promises.destroyAll = undefined;
58
+ resolver.resolve();
59
+ }
60
+ catch (error) {
61
+ resolver.reject(error);
62
+ }
63
+ },
64
+ async start(key, options = {}) {
65
+ const startPromise = promises.start.get(key);
66
+ if (startPromise)
67
+ return startPromise;
68
+ const resolver = Promise.withResolvers();
69
+ try {
70
+ promises.start.set(key, resolver.promise);
71
+ if (limit && instances.size >= limit)
72
+ throw new Error(`Instance limit of ${limit} reached.`);
73
+ const { port = await getPort() } = options;
74
+ const instance_ = instances.get(key) || instance.create({ port });
75
+ await instance_.start();
76
+ instances.set(key, instance_);
77
+ resolver.resolve(instance_);
78
+ }
79
+ catch (error) {
80
+ resolver.reject(error);
81
+ }
82
+ finally {
83
+ promises.start.delete(key);
84
+ }
85
+ return resolver.promise;
86
+ },
87
+ async stop(key) {
88
+ const stopPromise = promises.stop.get(key);
89
+ if (stopPromise)
90
+ return stopPromise;
91
+ const resolver = Promise.withResolvers();
92
+ try {
93
+ promises.stop.set(key, resolver.promise);
94
+ const instance_ = instances.get(key);
95
+ if (!instance_) {
96
+ resolver.resolve();
97
+ return;
98
+ }
99
+ await instance_.stop();
100
+ resolver.resolve();
101
+ }
102
+ catch (error) {
103
+ resolver.reject(error);
104
+ }
105
+ finally {
106
+ promises.stop.delete(key);
107
+ }
108
+ },
109
+ async stopAll() {
110
+ if (promises.stopAll)
111
+ return promises.stopAll;
112
+ const resolver = Promise.withResolvers();
113
+ try {
114
+ promises.stopAll = resolver.promise;
115
+ await Promise.all([...instances.keys()].map((key) => this.stop(key)));
116
+ promises.stopAll = undefined;
117
+ resolver.resolve();
118
+ }
119
+ catch (error) {
120
+ resolver.reject(error);
121
+ }
122
+ },
123
+ get size() {
124
+ return instances.size;
125
+ },
126
+ entries: instances.entries.bind(instances),
127
+ keys: instances.keys.bind(instances),
128
+ forEach: instances.forEach.bind(instances),
129
+ get: instances.get.bind(instances).bind(instances),
130
+ has: instances.has.bind(instances),
131
+ values: instances.values.bind(instances),
132
+ };
133
+ }
134
+ //# sourceMappingURL=pool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pool.js","sourceRoot":"","sources":["../pool.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,UAAU,CAAA;AA6B9B;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,UAAU,CACxB,UAAgC;IAEhC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,UAAU,CAAA;IAGtC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAA;IAE3C,6EAA6E;IAC7E,qEAAqE;IACrE,wFAAwF;IACxF,2GAA2G;IAC3G,MAAM,QAAQ,GAAG;QACf,OAAO,EAAE,IAAI,GAAG,EAAsB;QACtC,UAAU,EAAE,SAAsC;QAClD,KAAK,EAAE,IAAI,GAAG,EAA2B;QACzC,IAAI,EAAE,IAAI,GAAG,EAAsB;QACnC,OAAO,EAAE,SAAsC;KAChD,CAAA;IAED,OAAO;QACL,SAAS,EAAE;YACT,QAAQ;SACT;QACD,KAAK,CAAC,OAAO,CAAC,GAAG;YACf,MAAM,cAAc,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAChD,IAAI,cAAc;gBAAE,OAAO,cAAc,CAAA;YAEzC,MAAM,QAAQ,GAAG,OAAO,CAAC,aAAa,EAAQ,CAAA;YAE9C,IAAI,CAAC;gBACH,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;gBAE3C,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;gBACpB,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;gBAErB,QAAQ,CAAC,OAAO,EAAE,CAAA;YACpB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YACxB,CAAC;YAED,OAAO,QAAQ,CAAC,OAAO,CAAA;QACzB,CAAC;QACD,KAAK,CAAC,UAAU;YACd,IAAI,QAAQ,CAAC,UAAU;gBAAE,OAAO,QAAQ,CAAC,UAAU,CAAA;YAEnD,MAAM,QAAQ,GAAG,OAAO,CAAC,aAAa,EAAQ,CAAA;YAE9C,IAAI,CAAC;gBACH,QAAQ,CAAC,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAA;gBAEtC,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;gBAExE,QAAQ,CAAC,UAAU,GAAG,SAAS,CAAA;gBAE/B,QAAQ,CAAC,OAAO,EAAE,CAAA;YACpB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YACxB,CAAC;QACH,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,GAAG,EAAE;YAC3B,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAC5C,IAAI,YAAY;gBAAE,OAAO,YAAY,CAAA;YAErC,MAAM,QAAQ,GAAG,OAAO,CAAC,aAAa,EAAa,CAAA;YAEnD,IAAI,CAAC;gBACH,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;gBAEzC,IAAI,KAAK,IAAI,SAAS,CAAC,IAAI,IAAI,KAAK;oBAClC,MAAM,IAAI,KAAK,CAAC,qBAAqB,KAAK,WAAW,CAAC,CAAA;gBAExD,MAAM,EAAE,IAAI,GAAG,MAAM,OAAO,EAAE,EAAE,GAAG,OAAO,CAAA;gBAE1C,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAA;gBACjE,MAAM,SAAS,CAAC,KAAK,EAAE,CAAA;gBAEvB,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;gBAC7B,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;YAC7B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YACxB,CAAC;oBAAS,CAAC;gBACT,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YAC5B,CAAC;YAED,OAAO,QAAQ,CAAC,OAAO,CAAA;QACzB,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,GAAG;YACZ,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAC1C,IAAI,WAAW;gBAAE,OAAO,WAAW,CAAA;YAEnC,MAAM,QAAQ,GAAG,OAAO,CAAC,aAAa,EAAQ,CAAA;YAE9C,IAAI,CAAC;gBACH,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;gBAExC,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;gBACpC,IAAI,CAAC,SAAS,EAAE,CAAC;oBACf,QAAQ,CAAC,OAAO,EAAE,CAAA;oBAClB,OAAM;gBACR,CAAC;gBAED,MAAM,SAAS,CAAC,IAAI,EAAE,CAAA;gBAEtB,QAAQ,CAAC,OAAO,EAAE,CAAA;YACpB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YACxB,CAAC;oBAAS,CAAC;gBACT,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;YAC3B,CAAC;QACH,CAAC;QACD,KAAK,CAAC,OAAO;YACX,IAAI,QAAQ,CAAC,OAAO;gBAAE,OAAO,QAAQ,CAAC,OAAO,CAAA;YAE7C,MAAM,QAAQ,GAAG,OAAO,CAAC,aAAa,EAAQ,CAAA;YAE9C,IAAI,CAAC;gBACH,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAA;gBAEnC,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;gBAErE,QAAQ,CAAC,OAAO,GAAG,SAAS,CAAA;gBAE5B,QAAQ,CAAC,OAAO,EAAE,CAAA;YACpB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YACxB,CAAC;QACH,CAAC;QAED,IAAI,IAAI;YACN,OAAO,SAAS,CAAC,IAAI,CAAA;QACvB,CAAC;QACD,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;QAC1C,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;QACpC,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;QAC1C,GAAG,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;QAClD,GAAG,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;QAClC,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;KACzC,CAAA;AACH,CAAC"}
@@ -0,0 +1,21 @@
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ /// <reference types="node" resolution-mode="require"/>
3
+ import { type IncomingMessage, type Server, type ServerResponse } from 'node:http';
4
+ import type { AddressInfo } from 'node:net';
5
+ import { type DefinePoolParameters } from './pool.js';
6
+ export type DefineProxyPoolParameters = DefinePoolParameters & ({
7
+ /** Host to run the server on. */
8
+ host?: string | undefined;
9
+ /** Port to run the server on. */
10
+ port: number;
11
+ } | {
12
+ host?: undefined;
13
+ port?: undefined;
14
+ });
15
+ export type DefineProxyPoolReturnType = Omit<Server<typeof IncomingMessage, typeof ServerResponse>, 'address'> & {
16
+ address(): AddressInfo | null;
17
+ start(): Promise<() => Promise<void>>;
18
+ stop(): Promise<void>;
19
+ };
20
+ export declare function defineProxyPool(parameters: DefineProxyPoolParameters): DefineProxyPoolReturnType;
21
+ //# sourceMappingURL=proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../proxy.ts"],"names":[],"mappings":";;AAAA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,MAAM,EACX,KAAK,cAAc,EAEpB,MAAM,WAAW,CAAA;AAClB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAG3C,OAAO,EAAE,KAAK,oBAAoB,EAAc,MAAM,WAAW,CAAA;AAGjE,MAAM,MAAM,yBAAyB,GAAG,oBAAoB,GAC1D,CACI;IACE,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACzB,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAA;CACb,GACD;IACE,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,IAAI,CAAC,EAAE,SAAS,CAAA;CACjB,CACJ,CAAA;AAEH,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAC1C,MAAM,CAAC,OAAO,eAAe,EAAE,OAAO,cAAc,CAAC,EACrD,SAAS,CACV,GAAG;IACF,OAAO,IAAI,WAAW,GAAG,IAAI,CAAA;IAC7B,KAAK,IAAI,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAAA;IACrC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACtB,CAAA;AAED,wBAAgB,eAAe,CAC7B,UAAU,EAAE,yBAAyB,GACpC,yBAAyB,CAiG3B"}
package/_lib/proxy.js ADDED
@@ -0,0 +1,93 @@
1
+ import { createServer, } from 'node:http';
2
+ import { createProxyServer } from 'http-proxy';
3
+ import { definePool } from './pool.js';
4
+ import { extractPath } from './utils.js';
5
+ export function defineProxyPool(parameters) {
6
+ const { host = '::', instance, limit, port } = parameters;
7
+ const pool = definePool({ instance, limit });
8
+ const proxy = createProxyServer({
9
+ ignorePath: true,
10
+ ws: true,
11
+ });
12
+ const server = createServer(async (request, response) => {
13
+ try {
14
+ const url = request.url;
15
+ if (!url) {
16
+ response.end();
17
+ return;
18
+ }
19
+ const { id, path } = extractPath(url);
20
+ if (typeof id === 'number' && path === '/') {
21
+ const { host, port } = pool.get(id) || (await pool.start(id));
22
+ return proxy.web(request, response, {
23
+ target: `http://${host}:${port}`,
24
+ });
25
+ }
26
+ if (typeof id === 'number' && path === '/start') {
27
+ const { host, port } = await pool.start(id);
28
+ response
29
+ .writeHead(200, { 'Content-Type': 'application/json' })
30
+ .end(JSON.stringify({ host, port }));
31
+ return;
32
+ }
33
+ if (typeof id === 'number' && path === '/stop') {
34
+ await pool.stop(id);
35
+ response.writeHead(200, { 'Content-Type': 'application/json' }).end();
36
+ return;
37
+ }
38
+ if (typeof id === 'number' && path === '/messages') {
39
+ const messages = pool.get(id)?.messages.get() || [];
40
+ response
41
+ .writeHead(200, { 'Content-Type': 'application/json' })
42
+ .end(JSON.stringify(messages));
43
+ return;
44
+ }
45
+ if (path === '/healthcheck') {
46
+ response.writeHead(200, { 'Content-Type': 'application/json' }).end();
47
+ return;
48
+ }
49
+ response.writeHead(404, { 'Content-Type': 'application/json' }).end();
50
+ return;
51
+ }
52
+ catch (error) {
53
+ response
54
+ .writeHead(400, { 'Content-Type': 'application/json' })
55
+ .end(JSON.stringify({ message: error.message }));
56
+ return;
57
+ }
58
+ });
59
+ server.on('upgrade', async (request, socket, head) => {
60
+ const url = request.url;
61
+ if (!url) {
62
+ socket.destroy(new Error('Unsupported request'));
63
+ return;
64
+ }
65
+ const { id, path } = extractPath(url);
66
+ if (typeof id === 'number' && path === '/') {
67
+ const { host, port } = pool.get(id) || (await pool.start(id));
68
+ proxy.ws(request, socket, head, {
69
+ target: `ws://${host}:${port}`,
70
+ });
71
+ return;
72
+ }
73
+ socket.destroy(new Error('Unsupported request'));
74
+ return;
75
+ });
76
+ return Object.assign(server, {
77
+ start() {
78
+ return new Promise((resolve) => {
79
+ if (port)
80
+ server.listen(port, host, () => resolve(this.stop));
81
+ else
82
+ server.listen(() => resolve(this.stop));
83
+ });
84
+ },
85
+ async stop() {
86
+ await Promise.allSettled([
87
+ new Promise((resolve, reject) => server.close((error) => (error ? reject(error) : resolve()))),
88
+ pool.destroyAll(),
89
+ ]);
90
+ },
91
+ });
92
+ }
93
+ //# sourceMappingURL=proxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.js","sourceRoot":"","sources":["../proxy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ export type ExtractPathReturnType = {
2
+ id: number | undefined;
3
+ path: string;
4
+ };
5
+ /**
6
+ * Parse a request url into an object containing the id and path.
7
+ *
8
+ * @param request The request url.
9
+ * @returns The parsed request context or undefined.
10
+ */
11
+ export declare function extractPath(request: string): ExtractPathReturnType;
12
+ /**
13
+ * Strips ANSI color codes from a string.
14
+ *
15
+ * @param message The string to strip.
16
+ * @returns The stripped string.
17
+ */
18
+ export declare function stripColors(message: string): string;
19
+ /**
20
+ * Converts an object of options to an array of command line arguments.
21
+ *
22
+ * @param options The options object.
23
+ * @returns The command line arguments.
24
+ */
25
+ export declare function toArgs(options: {
26
+ [key: string]: Record<string, string> | string | boolean | number | bigint | undefined;
27
+ }): string[];
28
+ /**
29
+ * Converts a camelCase string to a flag case string.
30
+ *
31
+ * @param key The camelCase string.
32
+ * @returns The flag case string.
33
+ */
34
+ export declare function toFlagCase(key: string): string;
35
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../utils.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,qBAAqB,GAAG;IAClC,EAAE,EAAE,MAAM,GAAG,SAAS,CAAA;IACtB,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB,CAkBlE;AAMD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,UAE1C;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,OAAO,EAAE;IAC9B,CAAC,GAAG,EAAE,MAAM,GACR,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACtB,MAAM,GACN,OAAO,GACP,MAAM,GACN,MAAM,GACN,SAAS,CAAA;CACd,YAsBA;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,UAErC"}
package/_lib/utils.js ADDED
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Parse a request url into an object containing the id and path.
3
+ *
4
+ * @param request The request url.
5
+ * @returns The parsed request context or undefined.
6
+ */
7
+ export function extractPath(request) {
8
+ const host = 'http://localhost'; // Dummy value for URL constructor
9
+ const url = new URL(`${host}${request ?? '/'}`);
10
+ const [idOrPath, ...pathname] = url.pathname
11
+ .split('/')
12
+ .filter((part) => part !== '');
13
+ const id = !Number.isNaN(Number(idOrPath)) && Number(idOrPath) > 0
14
+ ? Number(idOrPath)
15
+ : undefined;
16
+ const path = `/${typeof id === 'number'
17
+ ? pathname.join('/')
18
+ : [idOrPath, ...pathname].join('/')}`;
19
+ return { id, path };
20
+ }
21
+ const ansiColorRegex =
22
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: <explanation>
23
+ /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g;
24
+ /**
25
+ * Strips ANSI color codes from a string.
26
+ *
27
+ * @param message The string to strip.
28
+ * @returns The stripped string.
29
+ */
30
+ export function stripColors(message) {
31
+ return message.replace(ansiColorRegex, '');
32
+ }
33
+ /**
34
+ * Converts an object of options to an array of command line arguments.
35
+ *
36
+ * @param options The options object.
37
+ * @returns The command line arguments.
38
+ */
39
+ export function toArgs(options) {
40
+ return Object.entries(options).flatMap(([key, value]) => {
41
+ if (value === undefined)
42
+ return [];
43
+ if (typeof value === 'object' && value !== null)
44
+ return Object.entries(value).flatMap(([subKey, subValue]) => {
45
+ if (subValue === undefined)
46
+ return [];
47
+ const flag = toFlagCase(key);
48
+ const value = `${subKey}: ${subValue}`;
49
+ return [flag, value];
50
+ });
51
+ const flag = toFlagCase(key);
52
+ if (value === false)
53
+ return [];
54
+ if (value === true)
55
+ return [flag];
56
+ const stringified = value.toString();
57
+ if (stringified === '')
58
+ return [flag];
59
+ return [flag, stringified];
60
+ });
61
+ }
62
+ /**
63
+ * Converts a camelCase string to a flag case string.
64
+ *
65
+ * @param key The camelCase string.
66
+ * @returns The flag case string.
67
+ */
68
+ export function toFlagCase(key) {
69
+ return `--${key.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`)}`;
70
+ }
71
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../utils.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,MAAM,IAAI,GAAG,kBAAkB,CAAA,CAAC,kCAAkC;IAClE,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,OAAO,IAAI,GAAG,EAAE,CAAC,CAAA;IAC/C,MAAM,CAAC,QAAQ,EAAE,GAAG,QAAQ,CAAC,GAAG,GAAG,CAAC,QAAQ;SACzC,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,CAAA;IAEhC,MAAM,EAAE,GACN,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;QACrD,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;QAClB,CAAC,CAAC,SAAS,CAAA;IACf,MAAM,IAAI,GAAG,IACX,OAAO,EAAE,KAAK,QAAQ;QACpB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC;QACpB,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,CACtC,EAAE,CAAA;IAEF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAA;AACrB,CAAC;AAED,MAAM,cAAc;AAClB,yEAAyE;AACzE,6EAA6E,CAAA;AAE/E;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,OAAO,OAAO,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAA;AAC5C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,MAAM,CAAC,OAQtB;IACC,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QACtD,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,EAAE,CAAA;QAElC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;YAC7C,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,EAAE;gBAC1D,IAAI,QAAQ,KAAK,SAAS;oBAAE,OAAO,EAAE,CAAA;gBACrC,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAA;gBAC5B,MAAM,KAAK,GAAG,GAAG,MAAM,KAAK,QAAQ,EAAE,CAAA;gBACtC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;YACtB,CAAC,CAAC,CAAA;QAEJ,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAA;QAE5B,IAAI,KAAK,KAAK,KAAK;YAAE,OAAO,EAAE,CAAA;QAC9B,IAAI,KAAK,KAAK,IAAI;YAAE,OAAO,CAAC,IAAI,CAAC,CAAA;QAEjC,MAAM,WAAW,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAA;QACpC,IAAI,WAAW,KAAK,EAAE;YAAE,OAAO,CAAC,IAAI,CAAC,CAAA;QAErC,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;IAC5B,CAAC,CAAC,CAAA;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,OAAO,KAAK,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC,EAAE,CAAA;AAC3E,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { expect, test } from 'vitest'
2
+ import * as exports from './index.js'
3
+
4
+ test('exports', () => {
5
+ expect(Object.keys(exports)).toMatchInlineSnapshot(`
6
+ [
7
+ "defineInstance",
8
+ "definePool",
9
+ "defineProxyPool",
10
+ ]
11
+ `)
12
+ })
@@ -0,0 +1,20 @@
1
+ export {
2
+ type DefineInstanceFn,
3
+ type Instance,
4
+ type InstanceOptions,
5
+ type InstanceStartOptions,
6
+ defineInstance,
7
+ } from '../instance.js'
8
+
9
+ export {
10
+ type DefinePoolParameters,
11
+ type DefinePoolReturnType,
12
+ type Pool,
13
+ definePool,
14
+ } from '../pool.js'
15
+
16
+ export {
17
+ type DefineProxyPoolParameters,
18
+ type DefineProxyPoolReturnType,
19
+ defineProxyPool,
20
+ } from '../proxy.js'
@@ -0,0 +1,10 @@
1
+ import { expect, test } from 'vitest'
2
+ import * as exports from './instances.js'
3
+
4
+ test('exports', () => {
5
+ expect(Object.keys(exports)).toMatchInlineSnapshot(`
6
+ [
7
+ "anvil",
8
+ ]
9
+ `)
10
+ })
@@ -0,0 +1 @@
1
+ export { type AnvilParameters, anvil } from '../instances/anvil.js'