@relkit/runtime-hono 0.0.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 (123) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +5 -0
  3. package/dist/api-docs.d.ts +21 -0
  4. package/dist/api-docs.d.ts.map +1 -0
  5. package/dist/api-docs.js +91 -0
  6. package/dist/api-docs.js.map +1 -0
  7. package/dist/auth.d.ts +18 -0
  8. package/dist/auth.d.ts.map +1 -0
  9. package/dist/auth.js +52 -0
  10. package/dist/auth.js.map +1 -0
  11. package/dist/client-contract.d.ts +8 -0
  12. package/dist/client-contract.d.ts.map +1 -0
  13. package/dist/client-contract.js +10 -0
  14. package/dist/client-contract.js.map +1 -0
  15. package/dist/create-app.d.ts +22 -0
  16. package/dist/create-app.d.ts.map +1 -0
  17. package/dist/create-app.js +76 -0
  18. package/dist/create-app.js.map +1 -0
  19. package/dist/index.d.ts +15 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +15 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/internal-endpoints-utils.d.ts +16 -0
  24. package/dist/internal-endpoints-utils.d.ts.map +1 -0
  25. package/dist/internal-endpoints-utils.js +154 -0
  26. package/dist/internal-endpoints-utils.js.map +1 -0
  27. package/dist/internal-endpoints.d.ts +58 -0
  28. package/dist/internal-endpoints.d.ts.map +1 -0
  29. package/dist/internal-endpoints.js +106 -0
  30. package/dist/internal-endpoints.js.map +1 -0
  31. package/dist/materialize-routes-utils.d.ts +8 -0
  32. package/dist/materialize-routes-utils.d.ts.map +1 -0
  33. package/dist/materialize-routes-utils.js +82 -0
  34. package/dist/materialize-routes-utils.js.map +1 -0
  35. package/dist/materialize-routes.d.ts +90 -0
  36. package/dist/materialize-routes.d.ts.map +1 -0
  37. package/dist/materialize-routes.js +86 -0
  38. package/dist/materialize-routes.js.map +1 -0
  39. package/dist/mcp.d.ts +7 -0
  40. package/dist/mcp.d.ts.map +1 -0
  41. package/dist/mcp.js +81 -0
  42. package/dist/mcp.js.map +1 -0
  43. package/dist/middleware-limits.d.ts +4 -0
  44. package/dist/middleware-limits.d.ts.map +1 -0
  45. package/dist/middleware-limits.js +53 -0
  46. package/dist/middleware-limits.js.map +1 -0
  47. package/dist/middleware-utils.d.ts +57 -0
  48. package/dist/middleware-utils.d.ts.map +1 -0
  49. package/dist/middleware-utils.js +90 -0
  50. package/dist/middleware-utils.js.map +1 -0
  51. package/dist/middleware.d.ts +17 -0
  52. package/dist/middleware.d.ts.map +1 -0
  53. package/dist/middleware.js +106 -0
  54. package/dist/middleware.js.map +1 -0
  55. package/dist/rate-limit-store.d.ts +17 -0
  56. package/dist/rate-limit-store.d.ts.map +1 -0
  57. package/dist/rate-limit-store.js +77 -0
  58. package/dist/rate-limit-store.js.map +1 -0
  59. package/dist/rate-limit-telemetry.d.ts +8 -0
  60. package/dist/rate-limit-telemetry.d.ts.map +1 -0
  61. package/dist/rate-limit-telemetry.js +57 -0
  62. package/dist/rate-limit-telemetry.js.map +1 -0
  63. package/dist/rate-limit.d.ts +12 -0
  64. package/dist/rate-limit.d.ts.map +1 -0
  65. package/dist/rate-limit.js +126 -0
  66. package/dist/rate-limit.js.map +1 -0
  67. package/dist/request-context.d.ts +4 -0
  68. package/dist/request-context.d.ts.map +1 -0
  69. package/dist/request-context.js +65 -0
  70. package/dist/request-context.js.map +1 -0
  71. package/dist/request-mapping-body.d.ts +27 -0
  72. package/dist/request-mapping-body.d.ts.map +1 -0
  73. package/dist/request-mapping-body.js +101 -0
  74. package/dist/request-mapping-body.js.map +1 -0
  75. package/dist/request-mapping-fields.d.ts +16 -0
  76. package/dist/request-mapping-fields.d.ts.map +1 -0
  77. package/dist/request-mapping-fields.js +63 -0
  78. package/dist/request-mapping-fields.js.map +1 -0
  79. package/dist/request-mapping-object.d.ts +14 -0
  80. package/dist/request-mapping-object.d.ts.map +1 -0
  81. package/dist/request-mapping-object.js +26 -0
  82. package/dist/request-mapping-object.js.map +1 -0
  83. package/dist/request-mapping-sources.d.ts +7 -0
  84. package/dist/request-mapping-sources.d.ts.map +1 -0
  85. package/dist/request-mapping-sources.js +60 -0
  86. package/dist/request-mapping-sources.js.map +1 -0
  87. package/dist/request-mapping-transform.d.ts +3 -0
  88. package/dist/request-mapping-transform.d.ts.map +1 -0
  89. package/dist/request-mapping-transform.js +55 -0
  90. package/dist/request-mapping-transform.js.map +1 -0
  91. package/dist/request-mapping.d.ts +33 -0
  92. package/dist/request-mapping.d.ts.map +1 -0
  93. package/dist/request-mapping.js +111 -0
  94. package/dist/request-mapping.js.map +1 -0
  95. package/dist/request-record-middleware.d.ts +6 -0
  96. package/dist/request-record-middleware.d.ts.map +1 -0
  97. package/dist/request-record-middleware.js +58 -0
  98. package/dist/request-record-middleware.js.map +1 -0
  99. package/dist/request-record-utils.d.ts +11 -0
  100. package/dist/request-record-utils.d.ts.map +1 -0
  101. package/dist/request-record-utils.js +71 -0
  102. package/dist/request-record-utils.js.map +1 -0
  103. package/dist/response-mapping-utils.d.ts +19 -0
  104. package/dist/response-mapping-utils.d.ts.map +1 -0
  105. package/dist/response-mapping-utils.js +72 -0
  106. package/dist/response-mapping-utils.js.map +1 -0
  107. package/dist/response-mapping.d.ts +18 -0
  108. package/dist/response-mapping.d.ts.map +1 -0
  109. package/dist/response-mapping.js +100 -0
  110. package/dist/response-mapping.js.map +1 -0
  111. package/dist/route-middleware.d.ts +4 -0
  112. package/dist/route-middleware.d.ts.map +1 -0
  113. package/dist/route-middleware.js +62 -0
  114. package/dist/route-middleware.js.map +1 -0
  115. package/dist/rpc.d.ts +4 -0
  116. package/dist/rpc.d.ts.map +1 -0
  117. package/dist/rpc.js +163 -0
  118. package/dist/rpc.js.map +1 -0
  119. package/dist/static-files.d.ts +6 -0
  120. package/dist/static-files.d.ts.map +1 -0
  121. package/dist/static-files.js +100 -0
  122. package/dist/static-files.js.map +1 -0
  123. package/package.json +55 -0
@@ -0,0 +1,126 @@
1
+ import { rateLimiter } from "hono-rate-limiter";
2
+ import { getRequestState } from "./middleware.js";
3
+ import { createRateLimitStore } from "./rate-limit-store.js";
4
+ import { emitRateLimitSpan, recordRateLimitResult } from "./rate-limit-telemetry.js";
5
+ export const ROUTE_MIDDLEWARE_ORDER = Object.freeze([
6
+ "rate-limit",
7
+ "declared-middleware",
8
+ "request-mapping",
9
+ "target",
10
+ ]);
11
+ const INFO_KEY = "relkit.rateLimit";
12
+ export function withRateLimit(trigger, options, handler) {
13
+ const policy = trigger.config.rateLimit;
14
+ if (policy === undefined || policy === null)
15
+ return handler;
16
+ const store = policy.storeId === undefined
17
+ ? undefined
18
+ : createRateLimitStore(trigger.id, policy.storeId, policy.windowMs, requiredResolver(options, policy.storeId));
19
+ const middleware = rateLimiter({
20
+ limit: policy.limit,
21
+ windowMs: policy.windowMs,
22
+ standardHeaders: "draft-6",
23
+ requestPropertyName: INFO_KEY,
24
+ keyGenerator: (context) => requestKey(context, policy.key),
25
+ ...(store === undefined ? {} : { store }),
26
+ handler: (context) => {
27
+ const info = rateInfo(context);
28
+ const retryAfterMs = Math.max(0, info?.resetTime === undefined ? policy.windowMs : info.resetTime.getTime() - Date.now());
29
+ return context.json({ error: "rate-limit", retryAfterMs }, 429);
30
+ },
31
+ });
32
+ return async (context) => {
33
+ const startedAt = Date.now();
34
+ const state = getRequestState(context);
35
+ const spanId = `rate-limit:${crypto.randomUUID()}`;
36
+ let continued = false;
37
+ emitRateLimitSpan(options, trigger, state, spanId, startedAt, "started", false);
38
+ try {
39
+ const result = await middleware(context, async () => {
40
+ continued = true;
41
+ context.res = await handler(context);
42
+ });
43
+ const response = result instanceof Response ? result : context.res;
44
+ const blocked = !continued && response.status === 429;
45
+ const finalResponse = withStandardHeaders(response, policy, rateInfo(context), blocked);
46
+ context.res = finalResponse;
47
+ recordRateLimitResult(trigger, state, startedAt, finalResponse.status, blocked, continued);
48
+ emitRateLimitSpan(options, trigger, state, spanId, startedAt, "completed", blocked, rateInfo(context));
49
+ return finalResponse;
50
+ }
51
+ catch (cause) {
52
+ emitRateLimitSpan(options, trigger, state, spanId, startedAt, "completed", false, undefined, "defect");
53
+ throw cause;
54
+ }
55
+ };
56
+ }
57
+ function withStandardHeaders(response, policy, info, blocked) {
58
+ const headers = new Headers(response.headers);
59
+ const resetSeconds = Math.max(0, Math.ceil((info?.resetTime === undefined ? policy.windowMs : info.resetTime.getTime() - Date.now()) /
60
+ 1_000));
61
+ headers.set("RateLimit-Policy", `${policy.limit};w=${Math.ceil(policy.windowMs / 1_000)}`);
62
+ headers.set("RateLimit-Limit", String(policy.limit));
63
+ headers.set("RateLimit-Remaining", String(info?.remaining ?? policy.limit));
64
+ headers.set("RateLimit-Reset", String(resetSeconds));
65
+ if (blocked)
66
+ headers.set("Retry-After", String(resetSeconds));
67
+ return new Response(response.body, {
68
+ status: response.status,
69
+ statusText: response.statusText,
70
+ headers,
71
+ });
72
+ }
73
+ function requiredResolver(options, storeId) {
74
+ const resolver = options.rateLimitRuntime?.resolveStore;
75
+ if (resolver !== undefined)
76
+ return resolver;
77
+ return () => {
78
+ throw new Error(`Rate-limit store "${storeId}" is not bound to the active runtime.`);
79
+ };
80
+ }
81
+ function requestKey(context, source) {
82
+ const value = sourceValue(context, source);
83
+ return JSON.stringify([projection(source, "kind"), projection(source, "name"), value]);
84
+ }
85
+ function sourceValue(context, source) {
86
+ const kind = projection(source, "kind");
87
+ const name = projection(source, "name");
88
+ if (kind === "constant")
89
+ return projection(source, "value");
90
+ if (typeof name !== "string")
91
+ return null;
92
+ if (kind === "path")
93
+ return context.req.param(name) ?? null;
94
+ if (kind === "query") {
95
+ const values = new URL(context.req.url).searchParams.getAll(name);
96
+ return values.length === 0 ? null : values;
97
+ }
98
+ if (kind === "header")
99
+ return context.req.header(name) ?? null;
100
+ return kind === "cookie" ? cookie(context.req.header("cookie"), name) : null;
101
+ }
102
+ function cookie(header, name) {
103
+ const value = header
104
+ ?.split(";")
105
+ .map((part) => part.trim())
106
+ .find((part) => part.startsWith(`${name}=`))
107
+ ?.slice(name.length + 1);
108
+ if (value === undefined)
109
+ return null;
110
+ try {
111
+ return decodeURIComponent(value);
112
+ }
113
+ catch {
114
+ return value;
115
+ }
116
+ }
117
+ function projection(value, key) {
118
+ return value !== null && typeof value === "object"
119
+ ? value[key]
120
+ : undefined;
121
+ }
122
+ function rateInfo(context) {
123
+ const value = context.var[INFO_KEY];
124
+ return value !== null && typeof value === "object" ? value : undefined;
125
+ }
126
+ //# sourceMappingURL=rate-limit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Context } from "hono";
2
+ import type { HttpRouteRequest } from "./materialize-routes.js";
3
+ export declare function requestFromContext(context: Context, pathPattern?: string): HttpRouteRequest;
4
+ //# sourceMappingURL=request-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../src/request-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAuB3F"}
@@ -0,0 +1,65 @@
1
+ export function requestFromContext(context, pathPattern) {
2
+ const query = {};
3
+ const headers = {};
4
+ for (const [key, value] of new URL(context.req.url).searchParams.entries()) {
5
+ append(query, key, value);
6
+ }
7
+ for (const [key, value] of context.req.raw.headers.entries()) {
8
+ // ponytail: Fetch Headers combines repeated scalar values; raw server headers are needed to distinguish CSV values.
9
+ const values = value
10
+ .split(",")
11
+ .map((part) => part.trim())
12
+ .filter(Boolean);
13
+ headers[key] = values.length > 1 ? Object.freeze(values) : value;
14
+ }
15
+ const params = materializeParams(context, pathPattern);
16
+ return Object.freeze({
17
+ request: context.req.raw,
18
+ ...(pathPattern === undefined ? {} : { pathPattern }),
19
+ params,
20
+ query: Object.freeze(query),
21
+ headers: Object.freeze(headers),
22
+ validated: validatedData(context),
23
+ });
24
+ }
25
+ function materializeParams(context, pathPattern) {
26
+ const params = {};
27
+ for (const [name, value] of Object.entries(context.req.param())) {
28
+ const token = catchAllToken(pathPattern, name);
29
+ params[name] = token === undefined ? value : catchAllValues(context.req.url, token);
30
+ }
31
+ return Object.freeze(params);
32
+ }
33
+ function validatedData(context) {
34
+ const request = context.req;
35
+ return Object.freeze(Object.fromEntries(["param", "query", "header", "cookie", "json", "form"].flatMap((target) => {
36
+ const value = request.valid(target);
37
+ return value === undefined ? [] : [[target, value]];
38
+ })));
39
+ }
40
+ function catchAllToken(pathPattern, name) {
41
+ const token = pathPattern?.split("/").findIndex((segment) => {
42
+ return segment === `*${name}` || segment === `*${name}?`;
43
+ });
44
+ return token === undefined || token < 0 ? undefined : token;
45
+ }
46
+ function catchAllValues(url, token) {
47
+ const segments = new URL(url).pathname.split("/").slice(token);
48
+ return Object.freeze(segments.filter((segment) => segment !== "").map(decode));
49
+ }
50
+ function decode(value) {
51
+ try {
52
+ return decodeURIComponent(value);
53
+ }
54
+ catch {
55
+ return value;
56
+ }
57
+ }
58
+ function append(target, key, value) {
59
+ const previous = target[key];
60
+ target[key] =
61
+ previous === undefined
62
+ ? value
63
+ : Object.freeze(Array.isArray(previous) ? [...previous, value] : [previous, value]);
64
+ }
65
+ //# sourceMappingURL=request-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-context.js","sourceRoot":"","sources":["../src/request-context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ export declare const MISSING: unique symbol;
2
+ export type Missing = typeof MISSING;
3
+ export type BodyIssueCode = "content-type" | "body-too-large" | "malformed-json" | "malformed-multipart";
4
+ export interface BodyIssue {
5
+ readonly code: BodyIssueCode;
6
+ readonly message: string;
7
+ }
8
+ export interface FormDataLike {
9
+ readonly getAll: (name: string) => readonly unknown[];
10
+ }
11
+ export interface BodyValue<T> {
12
+ readonly value: T | Missing;
13
+ readonly issue?: BodyIssue;
14
+ }
15
+ export interface BodyState {
16
+ readonly request: Request;
17
+ readonly maxBodyBytes: number;
18
+ body?: Promise<{
19
+ readonly bytes?: Uint8Array;
20
+ readonly issue?: BodyIssue;
21
+ }>;
22
+ json?: Promise<BodyValue<unknown>>;
23
+ form?: Promise<BodyValue<FormDataLike>>;
24
+ }
25
+ export declare function parseJson(state: BodyState): Promise<BodyValue<unknown>>;
26
+ export declare function parseForm(state: BodyState): Promise<BodyValue<FormDataLike>>;
27
+ //# sourceMappingURL=request-mapping-body.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-mapping-body.d.ts","sourceRoot":"","sources":["../src/request-mapping-body.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,eAAmC,CAAC;AACxD,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC;AACrC,MAAM,MAAM,aAAa,GACvB,cAAc,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,qBAAqB,CAAC;AAC/E,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AACD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,OAAO,EAAE,CAAC;CACvD;AACD,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;CAC5B;AACD,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAC;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;QAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;IAC5E,IAAI,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;IACnC,IAAI,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC;CACzC;AAED,wBAAsB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAG7E;AAED,wBAAsB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAGlF"}
@@ -0,0 +1,101 @@
1
+ export const MISSING = Symbol("relkit.mapping.missing");
2
+ export async function parseJson(state) {
3
+ if (state.json === undefined)
4
+ state.json = parseJsonBody(state);
5
+ return state.json;
6
+ }
7
+ export async function parseForm(state) {
8
+ if (state.form === undefined)
9
+ state.form = parseFormBody(state);
10
+ return state.form;
11
+ }
12
+ async function parseJsonBody(state) {
13
+ const body = await readBody(state);
14
+ if (body.issue !== undefined || body.bytes === undefined)
15
+ return { value: MISSING, ...body };
16
+ const contentType = mediaType(state.request.headers.get("content-type"));
17
+ if (body.bytes.byteLength === 0)
18
+ return { value: MISSING };
19
+ if (contentType !== "application/json" && !contentType.endsWith("+json"))
20
+ return {
21
+ value: MISSING,
22
+ issue: { code: "content-type", message: "Request content type must be application/json" },
23
+ };
24
+ try {
25
+ return { value: JSON.parse(new TextDecoder().decode(body.bytes)) };
26
+ }
27
+ catch {
28
+ return {
29
+ value: MISSING,
30
+ issue: { code: "malformed-json", message: "Request body is not valid JSON" },
31
+ };
32
+ }
33
+ }
34
+ async function parseFormBody(state) {
35
+ const body = await readBody(state);
36
+ if (body.issue !== undefined || body.bytes === undefined)
37
+ return { value: MISSING, ...body };
38
+ if (body.bytes.byteLength === 0)
39
+ return { value: MISSING };
40
+ if (mediaType(state.request.headers.get("content-type")) !== "multipart/form-data")
41
+ return {
42
+ value: MISSING,
43
+ issue: { code: "content-type", message: "Request content type must be multipart/form-data" },
44
+ };
45
+ try {
46
+ const request = new Request(state.request.url, {
47
+ method: "POST",
48
+ headers: state.request.headers,
49
+ body: body.bytes,
50
+ });
51
+ return { value: await request.formData() };
52
+ }
53
+ catch {
54
+ return {
55
+ value: MISSING,
56
+ issue: { code: "malformed-multipart", message: "Request body is not valid multipart data" },
57
+ };
58
+ }
59
+ }
60
+ async function readBody(state) {
61
+ if (state.body !== undefined)
62
+ return state.body;
63
+ state.body = readBodyBytes(state.request, state.maxBodyBytes);
64
+ return state.body;
65
+ }
66
+ async function readBodyBytes(request, maxBytes) {
67
+ if (!Number.isSafeInteger(maxBytes) || maxBytes < 1)
68
+ throw new RangeError("maxBodyBytes must be a positive integer");
69
+ const length = Number(request.headers.get("content-length"));
70
+ if (Number.isSafeInteger(length) && length > maxBytes)
71
+ return { issue: { code: "body-too-large", message: `Request body exceeds ${maxBytes} bytes` } };
72
+ if (request.body === null)
73
+ return { bytes: new Uint8Array() };
74
+ const reader = request.body.getReader();
75
+ const chunks = [];
76
+ let total = 0;
77
+ while (true) {
78
+ const part = await reader.read();
79
+ if (part.done)
80
+ break;
81
+ total += part.value.byteLength;
82
+ if (total > maxBytes) {
83
+ await reader.cancel();
84
+ return {
85
+ issue: { code: "body-too-large", message: `Request body exceeds ${maxBytes} bytes` },
86
+ };
87
+ }
88
+ chunks.push(part.value);
89
+ }
90
+ const bytes = new Uint8Array(total);
91
+ let offset = 0;
92
+ for (const chunk of chunks) {
93
+ bytes.set(chunk, offset);
94
+ offset += chunk.byteLength;
95
+ }
96
+ return { bytes };
97
+ }
98
+ function mediaType(value) {
99
+ return value?.split(";", 1)[0]?.trim().toLowerCase() ?? "";
100
+ }
101
+ //# sourceMappingURL=request-mapping-body.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-mapping-body.js","sourceRoot":"","sources":["../src/request-mapping-body.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { type Missing } from "./request-mapping-body.js";
2
+ import type { MappingState } from "./request-mapping-object.js";
3
+ import type { RequestIssueCode, RequestMappingFailure } from "./request-mapping.js";
4
+ export declare function bodyField(name: string, state: MappingState, path: readonly (string | number)[]): Promise<unknown | Missing>;
5
+ export declare function jsonValue(state: MappingState, path: readonly (string | number)[]): Promise<unknown | Missing>;
6
+ export declare function validatedSource(state: MappingState, target: string, name: string): {
7
+ found: boolean;
8
+ value: unknown;
9
+ } | {
10
+ found: boolean;
11
+ value?: never;
12
+ };
13
+ export declare function formField(name: string, state: MappingState, path: readonly (string | number)[], all: boolean): Promise<unknown | Missing>;
14
+ export declare function mappingFailure(state: MappingState): RequestMappingFailure;
15
+ export declare function addMappingIssue(state: MappingState, code: RequestIssueCode, message: string, path: readonly (string | number)[]): void;
16
+ //# sourceMappingURL=request-mapping-fields.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-mapping-fields.d.ts","sourceRoot":"","sources":["../src/request-mapping-fields.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiC,KAAK,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACxF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAEpF,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GACjC,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,CAK5B;AAED,wBAAsB,SAAS,CAC7B,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GACjC,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,CAO5B;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;;;;;;EAKhF;AAED,wBAAsB,SAAS,CAC7B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EAClC,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,CAgB5B;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,qBAAqB,CAEzE;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GACjC,IAAI,CAKN"}
@@ -0,0 +1,63 @@
1
+ import { MISSING, parseForm, parseJson } from "./request-mapping-body.js";
2
+ export async function bodyField(name, state, path) {
3
+ const validated = validatedTarget(state, "json");
4
+ if (isRecord(validated) && Object.hasOwn(validated, name))
5
+ return validated[name];
6
+ const value = await jsonValue(state, path);
7
+ return value !== MISSING && isRecord(value) && Object.hasOwn(value, name) ? value[name] : MISSING;
8
+ }
9
+ export async function jsonValue(state, path) {
10
+ const validated = validatedTarget(state, "json");
11
+ if (validated !== undefined)
12
+ return validated;
13
+ const result = await parseJson(state.body);
14
+ if (result.issue !== undefined)
15
+ addMappingIssue(state, result.issue.code, result.issue.message, path);
16
+ return result.value;
17
+ }
18
+ export function validatedSource(state, target, name) {
19
+ const validated = validatedTarget(state, target);
20
+ return isRecord(validated) && Object.hasOwn(validated, name)
21
+ ? { found: true, value: validated[name] }
22
+ : { found: false };
23
+ }
24
+ export async function formField(name, state, path, all) {
25
+ const validated = validatedTarget(state, "form");
26
+ if (isRecord(validated) && Object.hasOwn(validated, name))
27
+ return validated[name];
28
+ if (isFormDataLike(validated)) {
29
+ const values = validated.getAll(name);
30
+ return all ? (values.length === 0 ? MISSING : values) : (values[0] ?? MISSING);
31
+ }
32
+ const result = await parseForm(state.body);
33
+ if (result.issue !== undefined)
34
+ addMappingIssue(state, result.issue.code, result.issue.message, path);
35
+ if (result.value === MISSING)
36
+ return MISSING;
37
+ const values = result.value.getAll(name);
38
+ if (all)
39
+ return values.length === 0 ? MISSING : Object.freeze([...values]);
40
+ if (values.length > 1)
41
+ addMappingIssue(state, "duplicate", `Duplicate multipart field "${name}"`, path);
42
+ return values.length === 1 ? values[0] : MISSING;
43
+ }
44
+ export function mappingFailure(state) {
45
+ return { ok: false, issues: Object.freeze(state.issues.map((item) => Object.freeze(item))) };
46
+ }
47
+ export function addMappingIssue(state, code, message, path) {
48
+ const key = `${code}:${path.join(".")}:${message}`;
49
+ if (state.reported.has(key))
50
+ return;
51
+ state.reported.add(key);
52
+ state.issues.push(Object.freeze({ code, message, path: Object.freeze([...path]) }));
53
+ }
54
+ function validatedTarget(state, target) {
55
+ return state.request.validated?.[target];
56
+ }
57
+ function isRecord(value) {
58
+ return value !== null && typeof value === "object" && !Array.isArray(value);
59
+ }
60
+ function isFormDataLike(value) {
61
+ return isRecord(value) && typeof value.getAll === "function";
62
+ }
63
+ //# sourceMappingURL=request-mapping-fields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-mapping-fields.js","sourceRoot":"","sources":["../src/request-mapping-fields.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { type BodyState, type Missing } from "./request-mapping-body.js";
2
+ import type { MappingRequest, RequestIssueCode, RequestMappingIssue, RequestMappingOptions } from "./request-mapping.js";
3
+ export interface MappingState {
4
+ readonly request: MappingRequest;
5
+ readonly body: BodyState;
6
+ readonly options: RequestMappingOptions;
7
+ readonly issues: RequestMappingIssue[];
8
+ readonly reported: Set<string>;
9
+ }
10
+ type Path = readonly (string | number)[];
11
+ type Visit = (node: unknown, state: MappingState, path: Path) => Promise<unknown | Missing>;
12
+ export declare function mapObject(fields: unknown, state: MappingState, path: Path, visit: Visit, report: (code: RequestIssueCode, message: string, path: Path) => void): Promise<unknown>;
13
+ export {};
14
+ //# sourceMappingURL=request-mapping-object.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-mapping-object.d.ts","sourceRoot":"","sources":["../src/request-mapping-object.ts"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,SAAS,EAAE,KAAK,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAClF,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAC;IACxC,QAAQ,CAAC,MAAM,EAAE,mBAAmB,EAAE,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAChC;AACD,KAAK,IAAI,GAAG,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;AACzC,KAAK,KAAK,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC;AAE5F,wBAAsB,SAAS,CAC7B,MAAM,EAAE,OAAO,EACf,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,GACpE,OAAO,CAAC,OAAO,CAAC,CAelB"}
@@ -0,0 +1,26 @@
1
+ import { MISSING } from "./request-mapping-body.js";
2
+ export async function mapObject(fields, state, path, visit, report) {
3
+ if (!isRecord(fields)) {
4
+ report("mapping", "Mapping fields must be an object", path);
5
+ return MISSING;
6
+ }
7
+ const result = {};
8
+ for (const [name, node] of Object.entries(fields)) {
9
+ const valuePath = [...path, name];
10
+ const value = await visit(node, state, valuePath);
11
+ if (value === MISSING) {
12
+ if (!state.issues.some((issue) => samePath(issue.path, valuePath)))
13
+ report("missing", `Missing request value "${name}"`, valuePath);
14
+ }
15
+ else
16
+ result[name] = value;
17
+ }
18
+ return result;
19
+ }
20
+ function samePath(left, right) {
21
+ return left.length === right.length && left.every((value, index) => value === right[index]);
22
+ }
23
+ function isRecord(value) {
24
+ return value !== null && typeof value === "object" && !Array.isArray(value);
25
+ }
26
+ //# sourceMappingURL=request-mapping-object.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-mapping-object.js","sourceRoot":"","sources":["../src/request-mapping-object.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAgC,MAAM,2BAA2B,CAAC;AAkBlF,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,MAAe,EACf,KAAmB,EACnB,IAAU,EACV,KAAY,EACZ,MAAqE;IAErE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACtB,MAAM,CAAC,SAAS,EAAE,kCAAkC,EAAE,IAAI,CAAC,CAAC;QAC5D,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,MAAM,SAAS,GAAG,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,CAAC;QAClC,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAClD,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YACtB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;gBAChE,MAAM,CAAC,SAAS,EAAE,0BAA0B,IAAI,GAAG,EAAE,SAAS,CAAC,CAAC;QACpE,CAAC;;YAAM,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;IAC9B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,QAAQ,CAAC,IAAU,EAAE,KAAW;IACvC,OAAO,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;AAC9F,CAAC;AACD,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { MappingValue, RequestIssueCode } from "./request-mapping.js";
2
+ import { type Missing } from "./request-mapping-body.js";
3
+ export declare function readHeader(headers: Readonly<Record<string, MappingValue>>, name: string): MappingValue | undefined;
4
+ export declare function readScalar(value: MappingValue | undefined, source: string, path: readonly (string | number)[], report: (code: RequestIssueCode, message: string, path: readonly (string | number)[]) => void): unknown | Missing;
5
+ export declare function readPathSegments(url: string, pattern: string | undefined, name: string, path: readonly (string | number)[], report: (code: RequestIssueCode, message: string, path: readonly (string | number)[]) => void): readonly string[] | Missing;
6
+ export declare function readCookie(name: string, headers: Readonly<Record<string, MappingValue>>, path: readonly (string | number)[], report: (code: RequestIssueCode, message: string, path: readonly (string | number)[]) => void): unknown | Missing;
7
+ //# sourceMappingURL=request-mapping-sources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-mapping-sources.d.ts","sourceRoot":"","sources":["../src/request-mapping-sources.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAW,KAAK,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAElE,wBAAgB,UAAU,CACxB,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,EAC/C,IAAI,EAAE,MAAM,GACX,YAAY,GAAG,SAAS,CAK1B;AAED,wBAAgB,UAAU,CACxB,KAAK,EAAE,YAAY,GAAG,SAAS,EAC/B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EAClC,MAAM,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK,IAAI,GAC5F,OAAO,GAAG,OAAO,CAOnB;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EAClC,MAAM,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK,IAAI,GAC5F,SAAS,MAAM,EAAE,GAAG,OAAO,CAgB7B;AAED,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,EAC/C,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EAClC,MAAM,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK,IAAI,GAC5F,OAAO,GAAG,OAAO,CAuBnB"}
@@ -0,0 +1,60 @@
1
+ import { MISSING } from "./request-mapping-body.js";
2
+ export function readHeader(headers, name) {
3
+ const key = Object.keys(headers).find((candidate) => candidate.toLowerCase() === name.toLowerCase());
4
+ return key === undefined ? undefined : headers[key];
5
+ }
6
+ export function readScalar(value, source, path, report) {
7
+ if (value === undefined)
8
+ return MISSING;
9
+ if (Array.isArray(value)) {
10
+ if (value.length !== 1)
11
+ report("duplicate", `Duplicate ${source} value`, path);
12
+ return value.length === 1 ? value[0] : MISSING;
13
+ }
14
+ return value;
15
+ }
16
+ export function readPathSegments(url, pattern, name, path, report) {
17
+ const token = pattern?.split("/").findIndex((segment) => {
18
+ return segment === `*${name}` || segment === `*${name}?`;
19
+ });
20
+ if (token === undefined || token < 0) {
21
+ report("mapping", `Catch-all path "${name}" is not declared by the route`, path);
22
+ return MISSING;
23
+ }
24
+ const segments = new URL(url).pathname.split("/").slice(token);
25
+ if (segments.length === 0 || segments.every((segment) => segment === ""))
26
+ return MISSING;
27
+ try {
28
+ return Object.freeze(segments.map((segment) => decodeURIComponent(segment)));
29
+ }
30
+ catch {
31
+ report("mapping", `Catch-all path "${name}" is not valid`, path);
32
+ return MISSING;
33
+ }
34
+ }
35
+ export function readCookie(name, headers, path, report) {
36
+ const raw = readHeader(headers, "cookie");
37
+ if (raw === undefined)
38
+ return MISSING;
39
+ const values = Array.isArray(raw) ? raw : [raw];
40
+ const matches = values.flatMap((value) => value.split(";").flatMap((part) => {
41
+ const index = part.indexOf("=");
42
+ return index < 0 || part.slice(0, index).trim() !== name
43
+ ? []
44
+ : [part.slice(index + 1).trim()];
45
+ }));
46
+ if (matches.length > 1) {
47
+ report("duplicate", `Duplicate cookie "${name}"`, path);
48
+ return MISSING;
49
+ }
50
+ if (matches.length === 0)
51
+ return MISSING;
52
+ try {
53
+ return decodeURIComponent(matches[0]);
54
+ }
55
+ catch {
56
+ report("mapping", `Cookie "${name}" is not valid`, path);
57
+ return MISSING;
58
+ }
59
+ }
60
+ //# sourceMappingURL=request-mapping-sources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-mapping-sources.js","sourceRoot":"","sources":["../src/request-mapping-sources.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type Missing } from "./request-mapping-body.js";
2
+ export declare function applyTransform(id: unknown, value: unknown | Missing, transforms: Readonly<Record<string, unknown>> | ReadonlyMap<string, unknown> | undefined, path: readonly (string | number)[], report: (message: string, path: readonly (string | number)[]) => void): Promise<unknown | Missing>;
3
+ //# sourceMappingURL=request-mapping-transform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-mapping-transform.d.ts","sourceRoot":"","sources":["../src/request-mapping-transform.ts"],"names":[],"mappings":"AACA,OAAO,EAAW,KAAK,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAElE,wBAAsB,cAAc,CAClC,EAAE,EAAE,OAAO,EACX,KAAK,EAAE,OAAO,GAAG,OAAO,EACxB,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EACxF,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,EAClC,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,KAAK,IAAI,GACpE,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,CA4B5B"}