@rhythmjs/router 0.0.8 → 0.0.9
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.
- package/README.md +6 -4
- package/dist/adapters/aws-lambda.d.ts +4 -3
- package/dist/adapters/aws-lambda.js +4 -3
- package/dist/adapters/bun.d.ts +4 -4
- package/dist/adapters/bun.js +2 -4
- package/dist/adapters/cloudflare.d.ts +4 -4
- package/dist/adapters/cloudflare.js +10 -17
- package/dist/adapters/deno.d.ts +4 -4
- package/dist/adapters/deno.js +2 -4
- package/dist/adapters/netlify.d.ts +4 -4
- package/dist/adapters/netlify.js +7 -14
- package/dist/adapters/node.d.ts +6 -4
- package/dist/adapters/node.js +5 -13
- package/dist/adapters/service-worker.d.ts +5 -3
- package/dist/adapters/service-worker.js +4 -3
- package/dist/adapters/vercel.d.ts +4 -4
- package/dist/adapters/vercel.js +2 -4
- package/dist/base--TyruAfY.d.ts +10 -0
- package/dist/base-B8GEu3z4.js +25 -0
- package/dist/context-ChHlG-q0.d.ts +24 -0
- package/dist/context.d.ts +2 -20
- package/dist/context.js +4 -1
- package/dist/fetch.d.ts +1 -1
- package/dist/rhythm-router.d.ts +1 -1
- package/dist/serve.d.ts +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -77,15 +77,17 @@ Everything above (`RhythmRouter`, `ctx.response`, etc.) is runtime-agnostic. Two
|
|
|
77
77
|
|
|
78
78
|
## Deploying per runtime
|
|
79
79
|
|
|
80
|
-
One app definition; each runtime has its own adapter under `@rhythmjs/router/adapters/*`, hono-style: import
|
|
80
|
+
One app definition; each runtime has its own adapter under `@rhythmjs/router/adapters/*`, hono-style: import from your target's adapter and export what the platform expects. Runtimes that speak web-standard `Request`/`Response` natively (Bun, Deno, Vercel) can equally use `toFetchHandler(app)` from `@rhythmjs/router/fetch` — their adapters are aliases for it.
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
Every adapter maps errors thrown in the middleware chain to a response (`500`, or the error's own `status`) instead of crashing, and accepts `{ onError }` to replace that mapping: `handle(app, { onError: (error) => new Response("down", { status: 503 }) })`. Platform metadata (Cloudflare `env`/`ctx`, the Netlify context) is readable in middleware via `getRuntime(ctx.request)` from `@rhythmjs/router/context`.
|
|
83
|
+
|
|
84
|
+
**Node** — `getRequestListener` returns a listener for your own `node:http` server:
|
|
83
85
|
|
|
84
86
|
```ts
|
|
85
87
|
import { createServer } from "node:http";
|
|
86
|
-
import {
|
|
88
|
+
import { getRequestListener } from "@rhythmjs/router/adapters/node";
|
|
87
89
|
|
|
88
|
-
createServer(
|
|
90
|
+
createServer(getRequestListener(app, { maxRequestBodySize: 1024 * 1024 })).listen(3000);
|
|
89
91
|
```
|
|
90
92
|
|
|
91
93
|
(Or skip the adapter entirely and use `serve(app, { port: 3000 })`.)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { RhythmHttpContext } from "../context.js";
|
|
1
|
+
import { t as RhythmHttpContext } from "../context-ChHlG-q0.js";
|
|
2
|
+
import { t as AdapterOptions } from "../base--TyruAfY.js";
|
|
2
3
|
import { AWSLambdaHandler } from "srvx/aws-lambda";
|
|
3
4
|
import { Rhythm } from "@rhythmjs/rhythm";
|
|
4
5
|
//#region src/adapters/aws-lambda.d.ts
|
|
5
|
-
export declare function handle<TContext extends RhythmHttpContext, TProviders extends object = {}>(app: Rhythm<RhythmHttpContext, TContext, TProviders
|
|
6
|
+
export declare function handle<TContext extends RhythmHttpContext, TProviders extends object = {}>(app: Rhythm<RhythmHttpContext, TContext, TProviders>, options?: AdapterOptions): AWSLambdaHandler;
|
|
6
7
|
//#endregion
|
|
7
|
-
export type { AWSLambdaHandler };
|
|
8
|
+
export type { AWSLambdaHandler, AdapterOptions };
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { t as createFetchAdapter } from "../base-B8GEu3z4.js";
|
|
2
2
|
import { toLambdaHandler } from "srvx/aws-lambda";
|
|
3
3
|
//#region src/adapters/aws-lambda.ts
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
const fetchHandle = createFetchAdapter();
|
|
5
|
+
function handle(app, options = {}) {
|
|
6
|
+
return toLambdaHandler({ fetch: fetchHandle(app, options) });
|
|
6
7
|
}
|
|
7
8
|
//#endregion
|
|
8
9
|
export { handle };
|
package/dist/adapters/bun.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Rhythm } from "@rhythmjs/rhythm";
|
|
1
|
+
import { n as FetchAdapter, t as AdapterOptions } from "../base--TyruAfY.js";
|
|
3
2
|
//#region src/adapters/bun.d.ts
|
|
4
|
-
export declare
|
|
5
|
-
//#endregion
|
|
3
|
+
export declare const handle: FetchAdapter;
|
|
4
|
+
//#endregion
|
|
5
|
+
export type { AdapterOptions };
|
package/dist/adapters/bun.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { t as createFetchAdapter } from "../base-B8GEu3z4.js";
|
|
2
2
|
//#region src/adapters/bun.ts
|
|
3
|
-
|
|
4
|
-
return toFetchHandler(app);
|
|
5
|
-
}
|
|
3
|
+
const handle = createFetchAdapter();
|
|
6
4
|
//#endregion
|
|
7
5
|
export { handle };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Rhythm } from "@rhythmjs/rhythm";
|
|
1
|
+
import { n as FetchAdapter, t as AdapterOptions } from "../base--TyruAfY.js";
|
|
3
2
|
//#region src/adapters/cloudflare.d.ts
|
|
4
|
-
export declare
|
|
5
|
-
//#endregion
|
|
3
|
+
export declare const handle: FetchAdapter<[env?: unknown, context?: unknown]>;
|
|
4
|
+
//#endregion
|
|
5
|
+
export type { AdapterOptions };
|
|
@@ -1,20 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as setRuntime, t as createFetchAdapter } from "../base-B8GEu3z4.js";
|
|
2
2
|
//#region src/adapters/cloudflare.ts
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
configurable: true
|
|
15
|
-
});
|
|
16
|
-
return handler(request);
|
|
17
|
-
};
|
|
18
|
-
}
|
|
3
|
+
const handle = createFetchAdapter((request, env, context) => {
|
|
4
|
+
if (env !== void 0 || context !== void 0) setRuntime(request, {
|
|
5
|
+
name: "cloudflare",
|
|
6
|
+
cloudflare: {
|
|
7
|
+
env,
|
|
8
|
+
context
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
});
|
|
19
12
|
//#endregion
|
|
20
13
|
export { handle };
|
package/dist/adapters/deno.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Rhythm } from "@rhythmjs/rhythm";
|
|
1
|
+
import { n as FetchAdapter, t as AdapterOptions } from "../base--TyruAfY.js";
|
|
3
2
|
//#region src/adapters/deno.d.ts
|
|
4
|
-
export declare
|
|
5
|
-
//#endregion
|
|
3
|
+
export declare const handle: FetchAdapter;
|
|
4
|
+
//#endregion
|
|
5
|
+
export type { AdapterOptions };
|
package/dist/adapters/deno.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { t as createFetchAdapter } from "../base-B8GEu3z4.js";
|
|
2
2
|
//#region src/adapters/deno.ts
|
|
3
|
-
|
|
4
|
-
return toFetchHandler(app);
|
|
5
|
-
}
|
|
3
|
+
const handle = createFetchAdapter();
|
|
6
4
|
//#endregion
|
|
7
5
|
export { handle };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Rhythm } from "@rhythmjs/rhythm";
|
|
1
|
+
import { n as FetchAdapter, t as AdapterOptions } from "../base--TyruAfY.js";
|
|
3
2
|
//#region src/adapters/netlify.d.ts
|
|
4
|
-
export declare
|
|
5
|
-
//#endregion
|
|
3
|
+
export declare const handle: FetchAdapter<[context?: unknown]>;
|
|
4
|
+
//#endregion
|
|
5
|
+
export type { AdapterOptions };
|
package/dist/adapters/netlify.js
CHANGED
|
@@ -1,17 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as setRuntime, t as createFetchAdapter } from "../base-B8GEu3z4.js";
|
|
2
2
|
//#region src/adapters/netlify.ts
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
netlify: { context }
|
|
10
|
-
},
|
|
11
|
-
configurable: true
|
|
12
|
-
});
|
|
13
|
-
return handler(request);
|
|
14
|
-
};
|
|
15
|
-
}
|
|
3
|
+
const handle = createFetchAdapter((request, context) => {
|
|
4
|
+
if (context !== void 0) setRuntime(request, {
|
|
5
|
+
name: "netlify",
|
|
6
|
+
netlify: { context }
|
|
7
|
+
});
|
|
8
|
+
});
|
|
16
9
|
//#endregion
|
|
17
10
|
export { handle };
|
package/dist/adapters/node.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { RhythmHttpContext } from "../context.js";
|
|
2
|
-
import {
|
|
1
|
+
import { t as RhythmHttpContext } from "../context-ChHlG-q0.js";
|
|
2
|
+
import { t as AdapterOptions } from "../base--TyruAfY.js";
|
|
3
|
+
import { NodeHttp1Handler, NodeHttp2Handler } from "srvx";
|
|
3
4
|
import { Rhythm } from "@rhythmjs/rhythm";
|
|
4
5
|
//#region src/adapters/node.d.ts
|
|
5
|
-
export interface NodeHandlerOptions {
|
|
6
|
+
export interface NodeHandlerOptions extends AdapterOptions {
|
|
6
7
|
maxRequestBodySize?: number;
|
|
7
8
|
}
|
|
8
|
-
export
|
|
9
|
+
export type NodeHandler = NodeHttp1Handler & NodeHttp2Handler;
|
|
10
|
+
export declare function getRequestListener<TContext extends RhythmHttpContext, TProviders extends object = {}>(app: Rhythm<RhythmHttpContext, TContext, TProviders>, options?: NodeHandlerOptions): NodeHandler;
|
|
9
11
|
//#endregion
|
package/dist/adapters/node.js
CHANGED
|
@@ -1,17 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { errorToResponse } from "../serve.js";
|
|
1
|
+
import { t as createFetchAdapter } from "../base-B8GEu3z4.js";
|
|
3
2
|
import { toNodeHandler } from "srvx/node";
|
|
4
3
|
//#region src/adapters/node.ts
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
try {
|
|
9
|
-
return await handler(request);
|
|
10
|
-
} catch (error) {
|
|
11
|
-
return errorToResponse(error);
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
return toNodeHandler(safeHandler, options);
|
|
4
|
+
const fetchHandle = createFetchAdapter();
|
|
5
|
+
function getRequestListener(app, options = {}) {
|
|
6
|
+
return toNodeHandler(fetchHandle(app, options), options);
|
|
15
7
|
}
|
|
16
8
|
//#endregion
|
|
17
|
-
export {
|
|
9
|
+
export { getRequestListener };
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { RhythmHttpContext } from "../context.js";
|
|
1
|
+
import { t as RhythmHttpContext } from "../context-ChHlG-q0.js";
|
|
2
|
+
import { t as AdapterOptions } from "../base--TyruAfY.js";
|
|
2
3
|
import { Rhythm } from "@rhythmjs/rhythm";
|
|
3
4
|
//#region src/adapters/service-worker.d.ts
|
|
4
5
|
interface FetchEventLike {
|
|
5
6
|
readonly request: Request;
|
|
6
7
|
respondWith(response: Response | Promise<Response>): void;
|
|
7
8
|
}
|
|
8
|
-
export declare function handle<TContext extends RhythmHttpContext, TProviders extends object = {}>(app: Rhythm<RhythmHttpContext, TContext, TProviders
|
|
9
|
-
//#endregion
|
|
9
|
+
export declare function handle<TContext extends RhythmHttpContext, TProviders extends object = {}>(app: Rhythm<RhythmHttpContext, TContext, TProviders>, options?: AdapterOptions): (event: FetchEventLike) => void;
|
|
10
|
+
//#endregion
|
|
11
|
+
export type { AdapterOptions };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { t as createFetchAdapter } from "../base-B8GEu3z4.js";
|
|
2
2
|
//#region src/adapters/service-worker.ts
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
const fetchHandle = createFetchAdapter();
|
|
4
|
+
function handle(app, options = {}) {
|
|
5
|
+
const handler = fetchHandle(app, options);
|
|
5
6
|
return (event) => {
|
|
6
7
|
event.respondWith(handler(event.request));
|
|
7
8
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Rhythm } from "@rhythmjs/rhythm";
|
|
1
|
+
import { n as FetchAdapter, t as AdapterOptions } from "../base--TyruAfY.js";
|
|
3
2
|
//#region src/adapters/vercel.d.ts
|
|
4
|
-
export declare
|
|
5
|
-
//#endregion
|
|
3
|
+
export declare const handle: FetchAdapter;
|
|
4
|
+
//#endregion
|
|
5
|
+
export type { AdapterOptions };
|
package/dist/adapters/vercel.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { t as createFetchAdapter } from "../base-B8GEu3z4.js";
|
|
2
2
|
//#region src/adapters/vercel.ts
|
|
3
|
-
|
|
4
|
-
return toFetchHandler(app);
|
|
5
|
-
}
|
|
3
|
+
const handle = createFetchAdapter();
|
|
6
4
|
//#endregion
|
|
7
5
|
export { handle };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { t as RhythmHttpContext } from "./context-ChHlG-q0.js";
|
|
2
|
+
import { ErrorHandler, ServerRuntimeContext } from "srvx";
|
|
3
|
+
import { Rhythm } from "@rhythmjs/rhythm";
|
|
4
|
+
//#region src/adapters/base.d.ts
|
|
5
|
+
interface AdapterOptions {
|
|
6
|
+
onError?: ErrorHandler;
|
|
7
|
+
}
|
|
8
|
+
type FetchAdapter<TExtra extends unknown[] = []> = <TContext extends RhythmHttpContext, TProviders extends object = {}>(app: Rhythm<RhythmHttpContext, TContext, TProviders>, options?: AdapterOptions) => (request: Request, ...extra: TExtra) => Promise<Response>;
|
|
9
|
+
//#endregion
|
|
10
|
+
export { FetchAdapter as n, AdapterOptions as t };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { toFetchHandler } from "./fetch.js";
|
|
2
|
+
import { errorToResponse } from "./serve.js";
|
|
3
|
+
//#region src/adapters/base.ts
|
|
4
|
+
function setRuntime(request, runtime) {
|
|
5
|
+
Object.defineProperty(request, "runtime", {
|
|
6
|
+
value: runtime,
|
|
7
|
+
configurable: true
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
function createFetchAdapter(enrich) {
|
|
11
|
+
return (app, options = {}) => {
|
|
12
|
+
const handler = toFetchHandler(app);
|
|
13
|
+
const onError = options.onError ?? errorToResponse;
|
|
14
|
+
return async (request, ...extra) => {
|
|
15
|
+
try {
|
|
16
|
+
enrich?.(request, ...extra);
|
|
17
|
+
return await handler(request);
|
|
18
|
+
} catch (error) {
|
|
19
|
+
return onError(error);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { setRuntime as n, createFetchAdapter as t };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ServerRuntimeContext } from "srvx";
|
|
2
|
+
//#region src/context.d.ts
|
|
3
|
+
type RhythmRuntime = ServerRuntimeContext;
|
|
4
|
+
declare function getRuntime(request: Request): RhythmRuntime | undefined;
|
|
5
|
+
type RhythmResponseBody = string | ArrayBuffer | Uint8Array | Blob | FormData | URLSearchParams | ReadableStream<Uint8Array> | null;
|
|
6
|
+
declare class RhythmResponse {
|
|
7
|
+
status: number;
|
|
8
|
+
statusText: string | undefined;
|
|
9
|
+
headers: Headers;
|
|
10
|
+
body: RhythmResponseBody;
|
|
11
|
+
}
|
|
12
|
+
interface RhythmHttpContext {
|
|
13
|
+
readonly request: Request;
|
|
14
|
+
readonly response: RhythmResponse;
|
|
15
|
+
json(data: unknown, status?: number): void;
|
|
16
|
+
text(body: string, status?: number): void;
|
|
17
|
+
html(body: string, status?: number): void;
|
|
18
|
+
error(status: number, message?: string): void;
|
|
19
|
+
redirect(url: string, status?: number): void;
|
|
20
|
+
}
|
|
21
|
+
declare function createHttpContext(request: Request): RhythmHttpContext;
|
|
22
|
+
declare function toResponse(response: RhythmResponse): Response;
|
|
23
|
+
//#endregion
|
|
24
|
+
export { createHttpContext as a, RhythmRuntime as i, RhythmResponse as n, getRuntime as o, RhythmResponseBody as r, toResponse as s, RhythmHttpContext as t };
|
package/dist/context.d.ts
CHANGED
|
@@ -1,20 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
export declare class RhythmResponse {
|
|
4
|
-
status: number;
|
|
5
|
-
statusText: string | undefined;
|
|
6
|
-
headers: Headers;
|
|
7
|
-
body: RhythmResponseBody;
|
|
8
|
-
}
|
|
9
|
-
export interface RhythmHttpContext {
|
|
10
|
-
readonly request: Request;
|
|
11
|
-
readonly response: RhythmResponse;
|
|
12
|
-
json(data: unknown, status?: number): void;
|
|
13
|
-
text(body: string, status?: number): void;
|
|
14
|
-
html(body: string, status?: number): void;
|
|
15
|
-
error(status: number, message?: string): void;
|
|
16
|
-
redirect(url: string, status?: number): void;
|
|
17
|
-
}
|
|
18
|
-
export declare function createHttpContext(request: Request): RhythmHttpContext;
|
|
19
|
-
export declare function toResponse(response: RhythmResponse): Response;
|
|
20
|
-
//#endregion
|
|
1
|
+
import { a as createHttpContext, i as RhythmRuntime, n as RhythmResponse, o as getRuntime, r as RhythmResponseBody, s as toResponse, t as RhythmHttpContext } from "./context-ChHlG-q0.js";
|
|
2
|
+
export { RhythmHttpContext, RhythmResponse, RhythmResponseBody, RhythmRuntime, createHttpContext, getRuntime, toResponse };
|
package/dist/context.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
//#region src/context.ts
|
|
2
|
+
function getRuntime(request) {
|
|
3
|
+
return request.runtime;
|
|
4
|
+
}
|
|
2
5
|
var RhythmResponse = class {
|
|
3
6
|
status = 200;
|
|
4
7
|
statusText = void 0;
|
|
@@ -63,4 +66,4 @@ function toResponse(response) {
|
|
|
63
66
|
});
|
|
64
67
|
}
|
|
65
68
|
//#endregion
|
|
66
|
-
export { RhythmResponse, createHttpContext, toResponse };
|
|
69
|
+
export { RhythmResponse, createHttpContext, getRuntime, toResponse };
|
package/dist/fetch.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RhythmHttpContext } from "./context.js";
|
|
1
|
+
import { t as RhythmHttpContext } from "./context-ChHlG-q0.js";
|
|
2
2
|
import { Rhythm } from "@rhythmjs/rhythm";
|
|
3
3
|
//#region src/fetch.d.ts
|
|
4
4
|
export declare function toFetchHandler<TContext extends RhythmHttpContext, TProviders extends object = {}>(app: Rhythm<RhythmHttpContext, TContext, TProviders>): (request: Request) => Promise<Response>;
|
package/dist/rhythm-router.d.ts
CHANGED
package/dist/serve.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RhythmHttpContext } from "./context.js";
|
|
1
|
+
import { t as RhythmHttpContext } from "./context-ChHlG-q0.js";
|
|
2
2
|
import { ErrorHandler, Server, ServerMiddleware, ServerOptions, ServerPlugin } from "srvx";
|
|
3
3
|
import { Rhythm } from "@rhythmjs/rhythm";
|
|
4
4
|
//#region src/serve.d.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rhythmjs/router",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"description": "Radix-tree HTTP router for the Rhythm middleware kernel, with Bun, Node, and Deno adapters.",
|
|
5
5
|
"homepage": "https://rhythm.js.org/router",
|
|
6
6
|
"license": "ISC",
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
},
|
|
79
79
|
"dependencies": {
|
|
80
80
|
"srvx": "^1.0.5",
|
|
81
|
-
"@rhythmjs/rhythm": "0.0.
|
|
81
|
+
"@rhythmjs/rhythm": "0.0.9"
|
|
82
82
|
},
|
|
83
83
|
"devDependencies": {
|
|
84
84
|
"@types/node": "^26.6.3",
|