@beignet/core 0.0.1 → 0.0.3
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/CHANGELOG.md +27 -0
- package/README.md +202 -8
- package/dist/application/index.d.ts +93 -9
- package/dist/application/index.d.ts.map +1 -1
- package/dist/application/index.js +11 -11
- package/dist/application/index.js.map +1 -1
- package/dist/client/client.d.ts +73 -12
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +37 -12
- package/dist/client/client.js.map +1 -1
- package/dist/client/index.d.ts +12 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +6 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/types.d.ts +69 -8
- package/dist/client/types.d.ts.map +1 -1
- package/dist/config/index.d.ts +84 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +36 -0
- package/dist/config/index.js.map +1 -1
- package/dist/contracts/contract-builder.d.ts +49 -22
- package/dist/contracts/contract-builder.d.ts.map +1 -1
- package/dist/contracts/contract-builder.js +48 -21
- package/dist/contracts/contract-builder.js.map +1 -1
- package/dist/contracts/contract-group.d.ts +35 -19
- package/dist/contracts/contract-group.d.ts.map +1 -1
- package/dist/contracts/contract-group.js +35 -19
- package/dist/contracts/contract-group.js.map +1 -1
- package/dist/contracts/contract-like.d.ts +4 -4
- package/dist/contracts/contract-like.d.ts.map +1 -1
- package/dist/contracts/contract-like.js +2 -1
- package/dist/contracts/contract-like.js.map +1 -1
- package/dist/contracts/index.d.ts +28 -0
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/index.js +12 -0
- package/dist/contracts/index.js.map +1 -1
- package/dist/contracts/openapi-meta.d.ts +8 -8
- package/dist/contracts/openapi-meta.d.ts.map +1 -1
- package/dist/contracts/path-template.d.ts +27 -0
- package/dist/contracts/path-template.d.ts.map +1 -1
- package/dist/contracts/path-template.js +6 -0
- package/dist/contracts/path-template.js.map +1 -1
- package/dist/contracts/types.d.ts +104 -10
- package/dist/contracts/types.d.ts.map +1 -1
- package/dist/contracts/types.js +15 -0
- package/dist/contracts/types.js.map +1 -1
- package/dist/contracts/utils.d.ts +6 -0
- package/dist/contracts/utils.d.ts.map +1 -1
- package/dist/contracts/utils.js +6 -0
- package/dist/contracts/utils.js.map +1 -1
- package/dist/domain/entity.d.ts +22 -11
- package/dist/domain/entity.d.ts.map +1 -1
- package/dist/domain/entity.js +5 -1
- package/dist/domain/entity.js.map +1 -1
- package/dist/domain/events.d.ts +5 -2
- package/dist/domain/events.d.ts.map +1 -1
- package/dist/domain/events.js +4 -1
- package/dist/domain/events.js.map +1 -1
- package/dist/domain/value-object.d.ts +19 -9
- package/dist/domain/value-object.d.ts.map +1 -1
- package/dist/domain/value-object.js +5 -1
- package/dist/domain/value-object.js.map +1 -1
- package/dist/errors/catalog.d.ts +40 -16
- package/dist/errors/catalog.d.ts.map +1 -1
- package/dist/errors/catalog.js +18 -7
- package/dist/errors/catalog.js.map +1 -1
- package/dist/errors/response.d.ts +16 -4
- package/dist/errors/response.d.ts.map +1 -1
- package/dist/errors/response.js +3 -3
- package/dist/errors/response.js.map +1 -1
- package/dist/errors/validation.d.ts +10 -1
- package/dist/errors/validation.d.ts.map +1 -1
- package/dist/errors/validation.js +3 -0
- package/dist/errors/validation.js.map +1 -1
- package/dist/events/index.d.ts +133 -0
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +30 -0
- package/dist/events/index.js.map +1 -1
- package/dist/idempotency/index.d.ts +355 -0
- package/dist/idempotency/index.d.ts.map +1 -0
- package/dist/idempotency/index.js +360 -0
- package/dist/idempotency/index.js.map +1 -0
- package/dist/jobs/index.d.ts +248 -4
- package/dist/jobs/index.d.ts.map +1 -1
- package/dist/jobs/index.js +183 -1
- package/dist/jobs/index.js.map +1 -1
- package/dist/mail/index.d.ts +149 -0
- package/dist/mail/index.d.ts.map +1 -1
- package/dist/mail/index.js +30 -0
- package/dist/mail/index.js.map +1 -1
- package/dist/notifications/index.d.ts +369 -0
- package/dist/notifications/index.d.ts.map +1 -0
- package/dist/notifications/index.js +310 -0
- package/dist/notifications/index.js.map +1 -0
- package/dist/openapi/index.d.ts +132 -16
- package/dist/openapi/index.d.ts.map +1 -1
- package/dist/openapi/index.js +1 -1
- package/dist/openapi/index.js.map +1 -1
- package/dist/outbox/index.d.ts +474 -0
- package/dist/outbox/index.d.ts.map +1 -0
- package/dist/outbox/index.js +538 -0
- package/dist/outbox/index.js.map +1 -0
- package/dist/pagination/index.d.ts +166 -0
- package/dist/pagination/index.d.ts.map +1 -0
- package/dist/pagination/index.js +96 -0
- package/dist/pagination/index.js.map +1 -0
- package/dist/ports/audit.d.ts +271 -0
- package/dist/ports/audit.d.ts.map +1 -1
- package/dist/ports/audit.js +128 -0
- package/dist/ports/audit.js.map +1 -1
- package/dist/ports/auth.d.ts +70 -0
- package/dist/ports/auth.d.ts.map +1 -1
- package/dist/ports/auth.js +30 -0
- package/dist/ports/auth.js.map +1 -1
- package/dist/ports/cache.d.ts +41 -0
- package/dist/ports/cache.d.ts.map +1 -1
- package/dist/ports/cache.js +10 -0
- package/dist/ports/cache.js.map +1 -1
- package/dist/ports/clock.d.ts +38 -0
- package/dist/ports/clock.d.ts.map +1 -1
- package/dist/ports/clock.js +20 -0
- package/dist/ports/clock.js.map +1 -1
- package/dist/ports/id-generator.d.ts +37 -0
- package/dist/ports/id-generator.d.ts.map +1 -1
- package/dist/ports/id-generator.js +22 -0
- package/dist/ports/id-generator.js.map +1 -1
- package/dist/ports/index.d.ts +83 -0
- package/dist/ports/index.d.ts.map +1 -1
- package/dist/ports/index.js +41 -5
- package/dist/ports/index.js.map +1 -1
- package/dist/ports/logger.d.ts +56 -0
- package/dist/ports/logger.d.ts.map +1 -1
- package/dist/ports/logger.js +17 -0
- package/dist/ports/logger.js.map +1 -1
- package/dist/ports/policy.d.ts +132 -0
- package/dist/ports/policy.d.ts.map +1 -1
- package/dist/ports/policy.js +45 -0
- package/dist/ports/policy.js.map +1 -1
- package/dist/ports/rate-limit.d.ts +25 -0
- package/dist/ports/rate-limit.d.ts.map +1 -1
- package/dist/ports/rate-limit.js +10 -0
- package/dist/ports/rate-limit.js.map +1 -1
- package/dist/ports/redaction.d.ts +101 -0
- package/dist/ports/redaction.d.ts.map +1 -1
- package/dist/ports/redaction.js +59 -0
- package/dist/ports/redaction.js.map +1 -1
- package/dist/ports/storage.d.ts +100 -0
- package/dist/ports/storage.d.ts.map +1 -1
- package/dist/ports/storage.js +10 -0
- package/dist/ports/storage.js.map +1 -1
- package/dist/ports/testing.d.ts +47 -0
- package/dist/ports/testing.d.ts.map +1 -1
- package/dist/ports/testing.js +23 -0
- package/dist/ports/testing.js.map +1 -1
- package/dist/ports/unit-of-work.d.ts +60 -3
- package/dist/ports/unit-of-work.d.ts.map +1 -1
- package/dist/ports/unit-of-work.js +11 -2
- package/dist/ports/unit-of-work.js.map +1 -1
- package/dist/providers/instrumentation.d.ts +205 -1
- package/dist/providers/instrumentation.d.ts.map +1 -1
- package/dist/providers/instrumentation.js +14 -0
- package/dist/providers/instrumentation.js.map +1 -1
- package/dist/providers/provider.d.ts +14 -1
- package/dist/providers/provider.d.ts.map +1 -1
- package/dist/providers/provider.js.map +1 -1
- package/dist/schedules/index.d.ts +246 -0
- package/dist/schedules/index.d.ts.map +1 -1
- package/dist/schedules/index.js +27 -0
- package/dist/schedules/index.js.map +1 -1
- package/dist/server/health.d.ts +14 -5
- package/dist/server/health.d.ts.map +1 -1
- package/dist/server/health.js +5 -2
- package/dist/server/health.js.map +1 -1
- package/dist/server/hooks/auth.d.ts +68 -26
- package/dist/server/hooks/auth.d.ts.map +1 -1
- package/dist/server/hooks/auth.js +44 -55
- package/dist/server/hooks/auth.js.map +1 -1
- package/dist/server/hooks/cors.d.ts +27 -0
- package/dist/server/hooks/cors.d.ts.map +1 -1
- package/dist/server/hooks/cors.js +12 -0
- package/dist/server/hooks/cors.js.map +1 -1
- package/dist/server/hooks/errors.d.ts +15 -6
- package/dist/server/hooks/errors.d.ts.map +1 -1
- package/dist/server/hooks/errors.js.map +1 -1
- package/dist/server/hooks/index.d.ts +4 -1
- package/dist/server/hooks/index.d.ts.map +1 -1
- package/dist/server/hooks/index.js +3 -0
- package/dist/server/hooks/index.js.map +1 -1
- package/dist/server/hooks/logging.d.ts +36 -0
- package/dist/server/hooks/logging.d.ts.map +1 -1
- package/dist/server/hooks/logging.js +6 -0
- package/dist/server/hooks/logging.js.map +1 -1
- package/dist/server/hooks/rate-limit.d.ts +33 -0
- package/dist/server/hooks/rate-limit.d.ts.map +1 -1
- package/dist/server/hooks/rate-limit.js +11 -0
- package/dist/server/hooks/rate-limit.js.map +1 -1
- package/dist/server/http.d.ts +222 -0
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/http.js +20 -1
- package/dist/server/http.js.map +1 -1
- package/dist/server/index.d.ts +19 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +7 -1
- package/dist/server/index.js.map +1 -1
- package/dist/server/openapi.d.ts +5 -3
- package/dist/server/openapi.d.ts.map +1 -1
- package/dist/server/openapi.js +4 -2
- package/dist/server/openapi.js.map +1 -1
- package/dist/server/providers/loadProviderConfig.d.ts +9 -0
- package/dist/server/providers/loadProviderConfig.d.ts.map +1 -1
- package/dist/server/providers/loadProviderConfig.js +9 -0
- package/dist/server/providers/loadProviderConfig.js.map +1 -1
- package/dist/server/server.d.ts +159 -19
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +72 -31
- package/dist/server/server.js.map +1 -1
- package/dist/testing/index.d.ts +171 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +127 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/uploads/client.d.ts +278 -0
- package/dist/uploads/client.d.ts.map +1 -0
- package/dist/uploads/client.js +428 -0
- package/dist/uploads/client.js.map +1 -0
- package/dist/uploads/index.d.ts +361 -0
- package/dist/uploads/index.d.ts.map +1 -0
- package/dist/uploads/index.js +543 -0
- package/dist/uploads/index.js.map +1 -0
- package/package.json +31 -2
- package/src/application/index.ts +85 -22
- package/src/client/client.ts +73 -12
- package/src/client/index.ts +12 -0
- package/src/client/types.ts +70 -9
- package/src/config/index.ts +86 -0
- package/src/contracts/contract-builder.ts +49 -22
- package/src/contracts/contract-group.ts +35 -19
- package/src/contracts/contract-like.ts +4 -4
- package/src/contracts/index.ts +28 -1
- package/src/contracts/openapi-meta.ts +8 -8
- package/src/contracts/path-template.ts +27 -0
- package/src/contracts/types.ts +111 -10
- package/src/contracts/utils.ts +6 -0
- package/src/domain/entity.ts +22 -11
- package/src/domain/events.ts +5 -2
- package/src/domain/value-object.ts +19 -9
- package/src/errors/catalog.ts +40 -16
- package/src/errors/response.ts +16 -4
- package/src/errors/validation.ts +10 -1
- package/src/events/index.ts +134 -0
- package/src/idempotency/index.ts +767 -0
- package/src/jobs/index.ts +437 -5
- package/src/mail/index.ts +149 -0
- package/src/notifications/index.ts +771 -0
- package/src/openapi/index.ts +133 -16
- package/src/outbox/index.ts +1104 -0
- package/src/pagination/index.ts +278 -0
- package/src/ports/audit.ts +271 -0
- package/src/ports/auth.ts +70 -0
- package/src/ports/cache.ts +41 -0
- package/src/ports/clock.ts +38 -0
- package/src/ports/id-generator.ts +37 -0
- package/src/ports/index.ts +106 -11
- package/src/ports/logger.ts +56 -0
- package/src/ports/policy.ts +133 -0
- package/src/ports/rate-limit.ts +25 -0
- package/src/ports/redaction.ts +101 -0
- package/src/ports/storage.ts +100 -0
- package/src/ports/testing.ts +47 -0
- package/src/ports/unit-of-work.ts +60 -3
- package/src/providers/instrumentation.ts +211 -1
- package/src/providers/provider.ts +14 -1
- package/src/schedules/index.ts +247 -0
- package/src/server/health.ts +14 -5
- package/src/server/hooks/auth.ts +105 -120
- package/src/server/hooks/cors.ts +27 -0
- package/src/server/hooks/errors.ts +15 -6
- package/src/server/hooks/index.ts +4 -5
- package/src/server/hooks/logging.ts +36 -0
- package/src/server/hooks/rate-limit.ts +33 -0
- package/src/server/http.ts +249 -1
- package/src/server/index.ts +19 -1
- package/src/server/openapi.ts +5 -3
- package/src/server/providers/loadProviderConfig.ts +9 -0
- package/src/server/server.ts +296 -30
- package/src/testing/index.ts +348 -0
- package/src/uploads/client.ts +861 -0
- package/src/uploads/index.ts +1067 -0
package/src/config/index.ts
CHANGED
|
@@ -7,19 +7,39 @@
|
|
|
7
7
|
|
|
8
8
|
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Any Standard Schema compatible validator.
|
|
12
|
+
*/
|
|
10
13
|
export type StandardSchema = StandardSchemaV1<unknown, unknown>;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Runtime environment object shape.
|
|
17
|
+
*/
|
|
11
18
|
export type RuntimeEnv = Record<string, string | undefined>;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Map of environment variable names to Standard Schema validators.
|
|
22
|
+
*/
|
|
12
23
|
export type EnvSchemaShape = Record<string, StandardSchema>;
|
|
13
24
|
type EmptyEnvSchemaShape = Record<keyof never, never>;
|
|
14
25
|
type NoInferType<T> = [T][T extends unknown ? 0 : never];
|
|
15
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Infer the parsed output type from a Standard Schema.
|
|
29
|
+
*/
|
|
16
30
|
export type InferOutput<T extends StandardSchemaV1> =
|
|
17
31
|
StandardSchemaV1.InferOutput<T>;
|
|
18
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Infer the parsed output object for an env schema shape.
|
|
35
|
+
*/
|
|
19
36
|
export type InferEnvShape<Shape extends EnvSchemaShape> = {
|
|
20
37
|
[Key in keyof Shape]: InferOutput<Shape[Key]>;
|
|
21
38
|
};
|
|
22
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Env schema shape constrained to a client prefix.
|
|
42
|
+
*/
|
|
23
43
|
export type ClientEnvSchemaShape<ClientPrefix extends string> =
|
|
24
44
|
ClientPrefix extends ""
|
|
25
45
|
? EnvSchemaShape
|
|
@@ -36,9 +56,18 @@ type ValidateClientEnvShape<
|
|
|
36
56
|
: never;
|
|
37
57
|
};
|
|
38
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Raw Standard Schema validation issue produced while loading config.
|
|
61
|
+
*/
|
|
39
62
|
export type EnvValidationIssue = StandardSchemaV1.Issue;
|
|
40
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Error thrown when Beignet config validation fails.
|
|
66
|
+
*/
|
|
41
67
|
export class ConfigValidationError extends Error {
|
|
68
|
+
/**
|
|
69
|
+
* Raw Standard Schema validation issues.
|
|
70
|
+
*/
|
|
42
71
|
readonly issues: readonly EnvValidationIssue[];
|
|
43
72
|
|
|
44
73
|
constructor(issues: readonly EnvValidationIssue[], message?: string) {
|
|
@@ -48,12 +77,27 @@ export class ConfigValidationError extends Error {
|
|
|
48
77
|
}
|
|
49
78
|
}
|
|
50
79
|
|
|
80
|
+
/**
|
|
81
|
+
* Options for reading raw environment variables.
|
|
82
|
+
*/
|
|
51
83
|
export interface ReadEnvOptions {
|
|
84
|
+
/**
|
|
85
|
+
* Runtime environment object. Defaults to `process.env`.
|
|
86
|
+
*/
|
|
52
87
|
env?: RuntimeEnv;
|
|
88
|
+
/**
|
|
89
|
+
* Optional prefix to filter and strip from matching keys.
|
|
90
|
+
*/
|
|
53
91
|
prefix?: string;
|
|
92
|
+
/**
|
|
93
|
+
* Treat empty strings as missing values.
|
|
94
|
+
*/
|
|
54
95
|
emptyStringAsUndefined?: boolean;
|
|
55
96
|
}
|
|
56
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Options for defining a single validated env loader.
|
|
100
|
+
*/
|
|
57
101
|
export interface DefineEnvOptions<Schema extends StandardSchemaV1> {
|
|
58
102
|
/**
|
|
59
103
|
* Standard Schema for validating the full environment object.
|
|
@@ -88,10 +132,19 @@ export interface DefineEnvOptions<Schema extends StandardSchemaV1> {
|
|
|
88
132
|
onValidationError?: (issues: readonly EnvValidationIssue[]) => never;
|
|
89
133
|
}
|
|
90
134
|
|
|
135
|
+
/**
|
|
136
|
+
* Validated env loader returned by `defineEnv(...)`.
|
|
137
|
+
*/
|
|
91
138
|
export interface EnvInstance<Out> {
|
|
139
|
+
/**
|
|
140
|
+
* Read and validate the environment.
|
|
141
|
+
*/
|
|
92
142
|
load(options?: { env?: RuntimeEnv }): Out;
|
|
93
143
|
}
|
|
94
144
|
|
|
145
|
+
/**
|
|
146
|
+
* Options for `createEnv(...)`.
|
|
147
|
+
*/
|
|
95
148
|
export interface CreateEnvOptions<
|
|
96
149
|
Server extends EnvSchemaShape,
|
|
97
150
|
ClientPrefix extends string,
|
|
@@ -156,6 +209,9 @@ export interface CreateEnvOptions<
|
|
|
156
209
|
onInvalidAccess?: (key: string) => never;
|
|
157
210
|
}
|
|
158
211
|
|
|
212
|
+
/**
|
|
213
|
+
* Parsed env object returned by `createEnv(...)`.
|
|
214
|
+
*/
|
|
159
215
|
export type CreateEnvResult<
|
|
160
216
|
Server extends EnvSchemaShape,
|
|
161
217
|
Client extends EnvSchemaShape,
|
|
@@ -215,6 +271,9 @@ function prependIssuePath(
|
|
|
215
271
|
};
|
|
216
272
|
}
|
|
217
273
|
|
|
274
|
+
/**
|
|
275
|
+
* Format Standard Schema issues into a single readable message.
|
|
276
|
+
*/
|
|
218
277
|
export function formatStandardSchemaIssues(
|
|
219
278
|
issues: readonly StandardSchemaV1.Issue[],
|
|
220
279
|
): string {
|
|
@@ -226,6 +285,11 @@ export function formatStandardSchemaIssues(
|
|
|
226
285
|
.join("; ");
|
|
227
286
|
}
|
|
228
287
|
|
|
288
|
+
/**
|
|
289
|
+
* Read raw environment variables, optionally filtering by prefix.
|
|
290
|
+
*
|
|
291
|
+
* When a prefix is provided, matching keys are stripped before being returned.
|
|
292
|
+
*/
|
|
229
293
|
export function readEnv({
|
|
230
294
|
env = defaultRuntimeEnv(),
|
|
231
295
|
prefix,
|
|
@@ -265,6 +329,11 @@ function validationResultValue<Schema extends StandardSchemaV1>(
|
|
|
265
329
|
throw new Error("Invalid Standard Schema result: missing value");
|
|
266
330
|
}
|
|
267
331
|
|
|
332
|
+
/**
|
|
333
|
+
* Validate input with a synchronous Standard Schema.
|
|
334
|
+
*
|
|
335
|
+
* Throws when the schema returns a promise because env loading is synchronous.
|
|
336
|
+
*/
|
|
268
337
|
export function parseStandardSchemaSync<Schema extends StandardSchemaV1>(
|
|
269
338
|
schema: Schema,
|
|
270
339
|
input: unknown,
|
|
@@ -286,6 +355,9 @@ export function parseStandardSchemaSync<Schema extends StandardSchemaV1>(
|
|
|
286
355
|
return validationResultValue<Schema>(result);
|
|
287
356
|
}
|
|
288
357
|
|
|
358
|
+
/**
|
|
359
|
+
* Validate input with a Standard Schema that may be synchronous or async.
|
|
360
|
+
*/
|
|
289
361
|
export async function parseStandardSchemaAsync<Schema extends StandardSchemaV1>(
|
|
290
362
|
schema: Schema,
|
|
291
363
|
input: unknown,
|
|
@@ -323,6 +395,12 @@ function wrapEnvError(err: unknown, prefix?: string): Error {
|
|
|
323
395
|
);
|
|
324
396
|
}
|
|
325
397
|
|
|
398
|
+
/**
|
|
399
|
+
* Define a reusable validated env loader.
|
|
400
|
+
*
|
|
401
|
+
* This is useful for provider config and app-level config objects that are
|
|
402
|
+
* loaded from a prefixed subset of the environment.
|
|
403
|
+
*/
|
|
326
404
|
export function defineEnv<Schema extends StandardSchemaV1>(
|
|
327
405
|
options: DefineEnvOptions<Schema>,
|
|
328
406
|
): EnvInstance<InferOutput<Schema>> {
|
|
@@ -419,6 +497,14 @@ function validateRuntimeEnvStrict(
|
|
|
419
497
|
);
|
|
420
498
|
}
|
|
421
499
|
|
|
500
|
+
/**
|
|
501
|
+
* Create a server/client split env object.
|
|
502
|
+
*
|
|
503
|
+
* Server variables are available only on the server. Client variables must use
|
|
504
|
+
* `clientPrefix` when provided. Validation is synchronous, empty strings are
|
|
505
|
+
* treated as undefined by default, and client access to server-only keys throws
|
|
506
|
+
* through the returned proxy.
|
|
507
|
+
*/
|
|
422
508
|
export function createEnv<
|
|
423
509
|
const ClientPrefix extends string = "",
|
|
424
510
|
Server extends EnvSchemaShape = EmptyEnvSchemaShape,
|
|
@@ -72,8 +72,12 @@ function assertNoCatalogErrorStatusConflicts(
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
|
-
*
|
|
76
|
-
*
|
|
75
|
+
* Fluent builder for one HTTP contract.
|
|
76
|
+
*
|
|
77
|
+
* A contract describes the transport boundary for one endpoint: method, path,
|
|
78
|
+
* request schemas, response schemas, metadata, and route-owned catalog errors.
|
|
79
|
+
* Builder methods are immutable; each call returns a new builder with narrower
|
|
80
|
+
* types.
|
|
77
81
|
*/
|
|
78
82
|
export class ContractBuilder<
|
|
79
83
|
TMethod extends HttpMethod,
|
|
@@ -130,7 +134,10 @@ export class ContractBuilder<
|
|
|
130
134
|
}
|
|
131
135
|
|
|
132
136
|
/**
|
|
133
|
-
*
|
|
137
|
+
* Request and response schemas attached to this contract.
|
|
138
|
+
*
|
|
139
|
+
* Server adapters use these for validation. Client and frontend integrations
|
|
140
|
+
* use them for local validation and type inference.
|
|
134
141
|
*/
|
|
135
142
|
get schema() {
|
|
136
143
|
return {
|
|
@@ -143,36 +150,35 @@ export class ContractBuilder<
|
|
|
143
150
|
}
|
|
144
151
|
|
|
145
152
|
/**
|
|
146
|
-
*
|
|
153
|
+
* Response schemas keyed by HTTP status code.
|
|
147
154
|
*/
|
|
148
155
|
get responseSchemas(): TResponses {
|
|
149
156
|
return this._responses;
|
|
150
157
|
}
|
|
151
158
|
|
|
152
159
|
/**
|
|
153
|
-
*
|
|
160
|
+
* URL path template for this contract.
|
|
154
161
|
*/
|
|
155
162
|
get pathTemplate(): TPath {
|
|
156
163
|
return this._path;
|
|
157
164
|
}
|
|
158
165
|
|
|
159
166
|
/**
|
|
160
|
-
*
|
|
167
|
+
* URL path template alias.
|
|
161
168
|
*/
|
|
162
169
|
get path(): TPath {
|
|
163
170
|
return this._path;
|
|
164
171
|
}
|
|
165
172
|
|
|
166
173
|
/**
|
|
167
|
-
*
|
|
174
|
+
* Metadata consumed by hooks, OpenAPI generation, and app conventions.
|
|
168
175
|
*/
|
|
169
176
|
get metadata(): TMeta {
|
|
170
177
|
return this._meta;
|
|
171
178
|
}
|
|
172
179
|
|
|
173
180
|
/**
|
|
174
|
-
*
|
|
175
|
-
* Use this when passing to adapters that expect the plain config type
|
|
181
|
+
* Plain contract config consumed by framework internals and integrations.
|
|
176
182
|
*/
|
|
177
183
|
get config(): HttpContractConfig<
|
|
178
184
|
TMethod,
|
|
@@ -201,7 +207,10 @@ export class ContractBuilder<
|
|
|
201
207
|
}
|
|
202
208
|
|
|
203
209
|
/**
|
|
204
|
-
*
|
|
210
|
+
* Attach a schema for dynamic path parameters.
|
|
211
|
+
*
|
|
212
|
+
* The schema validates parameters parsed from path templates such as
|
|
213
|
+
* `/posts/:id` or `/posts/[id]`.
|
|
205
214
|
*/
|
|
206
215
|
pathParams<TNewPathParams extends StandardSchemaV1>(
|
|
207
216
|
schema: TNewPathParams,
|
|
@@ -232,7 +241,7 @@ export class ContractBuilder<
|
|
|
232
241
|
}
|
|
233
242
|
|
|
234
243
|
/**
|
|
235
|
-
*
|
|
244
|
+
* Attach a schema for query parameters.
|
|
236
245
|
*/
|
|
237
246
|
query<TNewQuery extends StandardSchemaV1>(
|
|
238
247
|
schema: TNewQuery,
|
|
@@ -263,8 +272,9 @@ export class ContractBuilder<
|
|
|
263
272
|
}
|
|
264
273
|
|
|
265
274
|
/**
|
|
266
|
-
*
|
|
267
|
-
*
|
|
275
|
+
* Attach a schema for a JSON request body.
|
|
276
|
+
*
|
|
277
|
+
* This method is only available on POST, PUT, and PATCH contracts.
|
|
268
278
|
*/
|
|
269
279
|
body<TNewBody extends StandardSchemaV1>(
|
|
270
280
|
this: ContractBuilder<
|
|
@@ -315,10 +325,11 @@ export class ContractBuilder<
|
|
|
315
325
|
}
|
|
316
326
|
|
|
317
327
|
/**
|
|
318
|
-
*
|
|
328
|
+
* Attach a request header schema.
|
|
319
329
|
*
|
|
320
330
|
* Multiple schemas are evaluated in declaration order and their parsed
|
|
321
|
-
* outputs are merged. This
|
|
331
|
+
* outputs are merged. This lets a contract inherit shared group headers and
|
|
332
|
+
* still declare route-specific headers.
|
|
322
333
|
*/
|
|
323
334
|
headers<TNewHeaders extends StandardSchemaV1>(
|
|
324
335
|
schema: TNewHeaders,
|
|
@@ -366,7 +377,12 @@ export class ContractBuilder<
|
|
|
366
377
|
}
|
|
367
378
|
|
|
368
379
|
/**
|
|
369
|
-
* Add or replace response schemas by status code
|
|
380
|
+
* Add or replace route-owned response schemas by status code.
|
|
381
|
+
*
|
|
382
|
+
* These schemas describe business responses returned by route handlers.
|
|
383
|
+
* Framework-owned errors such as request validation failures do not need to be
|
|
384
|
+
* declared here.
|
|
385
|
+
*
|
|
370
386
|
* Use `null` for void/empty responses such as 204 No Content.
|
|
371
387
|
*/
|
|
372
388
|
responses<TNewResponses extends ContractResponses>(
|
|
@@ -404,8 +420,9 @@ export class ContractBuilder<
|
|
|
404
420
|
/**
|
|
405
421
|
* Declare route-owned application errors from an error catalog.
|
|
406
422
|
*
|
|
407
|
-
* Catalog errors use Beignet's standard error response envelope
|
|
408
|
-
* `.responses()` when a
|
|
423
|
+
* Catalog errors use Beignet's standard error response envelope and remain
|
|
424
|
+
* distinguishable from framework-owned errors. Use `.responses()` when a
|
|
425
|
+
* route needs a custom error response body instead of catalog semantics.
|
|
409
426
|
*/
|
|
410
427
|
errors<TErrorDefs extends ContractErrorResponses>(
|
|
411
428
|
errorDefs: TErrorDefs,
|
|
@@ -449,7 +466,10 @@ export class ContractBuilder<
|
|
|
449
466
|
}
|
|
450
467
|
|
|
451
468
|
/**
|
|
452
|
-
*
|
|
469
|
+
* Merge metadata into this contract.
|
|
470
|
+
*
|
|
471
|
+
* Hooks and tooling can read metadata for concerns such as auth, rate limits,
|
|
472
|
+
* idempotency, OpenAPI, or app-specific conventions.
|
|
453
473
|
*/
|
|
454
474
|
meta<TNewMeta extends ContractMeta>(
|
|
455
475
|
newMeta: TNewMeta,
|
|
@@ -483,7 +503,7 @@ export class ContractBuilder<
|
|
|
483
503
|
}
|
|
484
504
|
|
|
485
505
|
/**
|
|
486
|
-
*
|
|
506
|
+
* Merge OpenAPI operation metadata into this contract.
|
|
487
507
|
*/
|
|
488
508
|
openapi(
|
|
489
509
|
patch: Partial<OpenAPIOperationMeta>,
|
|
@@ -522,7 +542,7 @@ export class ContractBuilder<
|
|
|
522
542
|
}
|
|
523
543
|
|
|
524
544
|
/**
|
|
525
|
-
* Options for creating
|
|
545
|
+
* Options for creating one contract with `createContract(...)`.
|
|
526
546
|
*/
|
|
527
547
|
export type CreateContractOptions<
|
|
528
548
|
TMethod extends HttpMethod = HttpMethod,
|
|
@@ -537,7 +557,11 @@ export type CreateContractOptions<
|
|
|
537
557
|
};
|
|
538
558
|
|
|
539
559
|
/**
|
|
540
|
-
* Create a new HTTP contract
|
|
560
|
+
* Create a new HTTP contract builder.
|
|
561
|
+
*
|
|
562
|
+
* Most apps prefer `createContractGroup().namespace(...).prefix(...)` for
|
|
563
|
+
* related feature contracts. Use this lower-level factory when a standalone
|
|
564
|
+
* contract is clearer.
|
|
541
565
|
*
|
|
542
566
|
* @example
|
|
543
567
|
* ```ts
|
|
@@ -548,6 +572,9 @@ export type CreateContractOptions<
|
|
|
548
572
|
* .pathParams(z.object({ id: z.string() }))
|
|
549
573
|
* .responses({ 200: TodoSchema });
|
|
550
574
|
* ```
|
|
575
|
+
*
|
|
576
|
+
* @param options - HTTP method, path template, and optional contract name.
|
|
577
|
+
* @returns A fluent contract builder.
|
|
551
578
|
*/
|
|
552
579
|
export function createContract<
|
|
553
580
|
TMethod extends HttpMethod,
|
|
@@ -103,8 +103,11 @@ function assertNoCatalogErrorStatusConflicts(
|
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
/**
|
|
106
|
-
*
|
|
107
|
-
*
|
|
106
|
+
* Feature-scoped factory for related HTTP contracts.
|
|
107
|
+
*
|
|
108
|
+
* Contract groups let a feature share a namespace, path prefix, headers,
|
|
109
|
+
* responses, errors, and metadata across multiple endpoint contracts. The group
|
|
110
|
+
* is immutable: every configuration method returns a new group.
|
|
108
111
|
*/
|
|
109
112
|
export class ContractGroup<
|
|
110
113
|
TSharedResponses extends ContractResponses = Record<never, never>,
|
|
@@ -141,7 +144,10 @@ export class ContractGroup<
|
|
|
141
144
|
}
|
|
142
145
|
|
|
143
146
|
/**
|
|
144
|
-
* Set the namespace for
|
|
147
|
+
* Set the namespace for contracts created from this group.
|
|
148
|
+
*
|
|
149
|
+
* The namespace prefixes contract names, not paths. Use `prefix(...)` for
|
|
150
|
+
* path composition.
|
|
145
151
|
*/
|
|
146
152
|
namespace(
|
|
147
153
|
ns: string,
|
|
@@ -156,10 +162,10 @@ export class ContractGroup<
|
|
|
156
162
|
}
|
|
157
163
|
|
|
158
164
|
/**
|
|
159
|
-
* Add a path prefix to
|
|
165
|
+
* Add a path prefix to contracts created from this group.
|
|
160
166
|
*
|
|
161
|
-
* Prefixes compose immutably, so `prefix("/api").prefix("/v1")`
|
|
162
|
-
*
|
|
167
|
+
* Prefixes compose immutably, so `prefix("/api").prefix("/v1")` produces
|
|
168
|
+
* paths under `/api/v1`.
|
|
163
169
|
*/
|
|
164
170
|
prefix<const TNewPrefix extends string>(
|
|
165
171
|
pathPrefix: TNewPrefix,
|
|
@@ -183,7 +189,7 @@ export class ContractGroup<
|
|
|
183
189
|
}
|
|
184
190
|
|
|
185
191
|
/**
|
|
186
|
-
*
|
|
192
|
+
* Merge shared metadata into contracts created from this group.
|
|
187
193
|
*/
|
|
188
194
|
meta<TNewMeta extends ContractMeta>(
|
|
189
195
|
meta: TNewMeta,
|
|
@@ -207,8 +213,10 @@ export class ContractGroup<
|
|
|
207
213
|
}
|
|
208
214
|
|
|
209
215
|
/**
|
|
210
|
-
*
|
|
211
|
-
*
|
|
216
|
+
* Add shared route-owned response schemas to contracts created from this group.
|
|
217
|
+
*
|
|
218
|
+
* Framework-owned responses, such as validation or auth hook failures, do not
|
|
219
|
+
* need to be declared here.
|
|
212
220
|
*/
|
|
213
221
|
responses<TNewResponses extends ContractResponses>(
|
|
214
222
|
responseSchemas: TNewResponses,
|
|
@@ -233,7 +241,10 @@ export class ContractGroup<
|
|
|
233
241
|
}
|
|
234
242
|
|
|
235
243
|
/**
|
|
236
|
-
*
|
|
244
|
+
* Declare shared route-owned application errors for contracts in this group.
|
|
245
|
+
*
|
|
246
|
+
* Catalog errors use Beignet's standard error envelope and remain separate
|
|
247
|
+
* from framework-owned errors.
|
|
237
248
|
*/
|
|
238
249
|
errors<TErrorDefs extends ContractErrorResponses>(
|
|
239
250
|
errorDefs: TErrorDefs,
|
|
@@ -263,7 +274,7 @@ export class ContractGroup<
|
|
|
263
274
|
}
|
|
264
275
|
|
|
265
276
|
/**
|
|
266
|
-
* Add shared request header schema
|
|
277
|
+
* Add a shared request header schema to contracts created from this group.
|
|
267
278
|
*/
|
|
268
279
|
headers<TNewHeaders extends StandardSchema>(
|
|
269
280
|
schema: TNewHeaders,
|
|
@@ -300,7 +311,7 @@ export class ContractGroup<
|
|
|
300
311
|
}
|
|
301
312
|
|
|
302
313
|
/**
|
|
303
|
-
* Create a GET contract
|
|
314
|
+
* Create a GET contract under this group.
|
|
304
315
|
*/
|
|
305
316
|
get<const TPath extends string>(
|
|
306
317
|
path: TPath,
|
|
@@ -319,7 +330,7 @@ export class ContractGroup<
|
|
|
319
330
|
}
|
|
320
331
|
|
|
321
332
|
/**
|
|
322
|
-
* Create a POST contract
|
|
333
|
+
* Create a POST contract under this group.
|
|
323
334
|
*/
|
|
324
335
|
post<const TPath extends string>(
|
|
325
336
|
path: TPath,
|
|
@@ -338,7 +349,7 @@ export class ContractGroup<
|
|
|
338
349
|
}
|
|
339
350
|
|
|
340
351
|
/**
|
|
341
|
-
* Create a PUT contract
|
|
352
|
+
* Create a PUT contract under this group.
|
|
342
353
|
*/
|
|
343
354
|
put<const TPath extends string>(
|
|
344
355
|
path: TPath,
|
|
@@ -357,7 +368,7 @@ export class ContractGroup<
|
|
|
357
368
|
}
|
|
358
369
|
|
|
359
370
|
/**
|
|
360
|
-
* Create a PATCH contract
|
|
371
|
+
* Create a PATCH contract under this group.
|
|
361
372
|
*/
|
|
362
373
|
patch<const TPath extends string>(
|
|
363
374
|
path: TPath,
|
|
@@ -376,7 +387,7 @@ export class ContractGroup<
|
|
|
376
387
|
}
|
|
377
388
|
|
|
378
389
|
/**
|
|
379
|
-
* Create a DELETE contract
|
|
390
|
+
* Create a DELETE contract under this group.
|
|
380
391
|
*/
|
|
381
392
|
delete<const TPath extends string>(
|
|
382
393
|
path: TPath,
|
|
@@ -395,7 +406,7 @@ export class ContractGroup<
|
|
|
395
406
|
}
|
|
396
407
|
|
|
397
408
|
/**
|
|
398
|
-
* Create a HEAD contract
|
|
409
|
+
* Create a HEAD contract under this group.
|
|
399
410
|
*/
|
|
400
411
|
head<const TPath extends string>(
|
|
401
412
|
path: TPath,
|
|
@@ -414,7 +425,7 @@ export class ContractGroup<
|
|
|
414
425
|
}
|
|
415
426
|
|
|
416
427
|
/**
|
|
417
|
-
* Create
|
|
428
|
+
* Create an OPTIONS contract under this group.
|
|
418
429
|
*/
|
|
419
430
|
options<const TPath extends string>(
|
|
420
431
|
path: TPath,
|
|
@@ -477,7 +488,10 @@ export class ContractGroup<
|
|
|
477
488
|
}
|
|
478
489
|
|
|
479
490
|
/**
|
|
480
|
-
* Create a new
|
|
491
|
+
* Create a new feature contract group.
|
|
492
|
+
*
|
|
493
|
+
* Start here for most feature HTTP surfaces, then add a namespace and path
|
|
494
|
+
* prefix before defining individual contracts.
|
|
481
495
|
*
|
|
482
496
|
* @example
|
|
483
497
|
* ```ts
|
|
@@ -491,6 +505,8 @@ export class ContractGroup<
|
|
|
491
505
|
*
|
|
492
506
|
* const getTodo = todos.get("/:id")...
|
|
493
507
|
* ```
|
|
508
|
+
*
|
|
509
|
+
* @returns An empty immutable contract group.
|
|
494
510
|
*/
|
|
495
511
|
export function createContractGroup(): ContractGroup<
|
|
496
512
|
Record<never, never>,
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import type { HttpContractConfig } from "./types";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* or a contract-like object with a .config property (e.g., ContractBuilder)
|
|
4
|
+
* Contract input accepted by APIs that can unwrap builders.
|
|
6
5
|
*/
|
|
7
6
|
export type ContractLike = HttpContractConfig | { config: HttpContractConfig };
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
|
-
*
|
|
9
|
+
* Resolve a contract-like type to its plain `HttpContractConfig`.
|
|
11
10
|
*/
|
|
12
11
|
export type ResolveContract<T> = T extends { config: infer C }
|
|
13
12
|
? C extends HttpContractConfig
|
|
@@ -18,7 +17,8 @@ export type ResolveContract<T> = T extends { config: infer C }
|
|
|
18
17
|
: never;
|
|
19
18
|
|
|
20
19
|
/**
|
|
21
|
-
*
|
|
20
|
+
* Resolve a contract builder or plain config to the underlying contract config.
|
|
21
|
+
*
|
|
22
22
|
* @param c - The contract-like object to resolve
|
|
23
23
|
* @returns The underlying HttpContractConfig
|
|
24
24
|
*/
|
package/src/contracts/index.ts
CHANGED
|
@@ -4,26 +4,53 @@
|
|
|
4
4
|
* HTTP contract definitions and builders for Beignet.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Standard Schema type re-exported for contract authors.
|
|
9
|
+
*/
|
|
7
10
|
export type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
8
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Idempotency metadata types for contracts.
|
|
13
|
+
*/
|
|
14
|
+
export type { IdempotencyMeta, IdempotencyScopeMode } from "../idempotency";
|
|
15
|
+
/**
|
|
16
|
+
* Contract builder exports.
|
|
17
|
+
*/
|
|
9
18
|
export {
|
|
10
19
|
ContractBuilder,
|
|
11
20
|
type CreateContractOptions,
|
|
12
21
|
createContract,
|
|
13
22
|
} from "./contract-builder";
|
|
23
|
+
/**
|
|
24
|
+
* Contract group exports.
|
|
25
|
+
*/
|
|
14
26
|
export { ContractGroup, createContractGroup } from "./contract-group";
|
|
27
|
+
/**
|
|
28
|
+
* Contract-like helper exports.
|
|
29
|
+
*/
|
|
15
30
|
export {
|
|
16
31
|
type ContractLike,
|
|
17
32
|
type ResolveContract,
|
|
18
33
|
resolveContract,
|
|
19
34
|
} from "./contract-like";
|
|
35
|
+
/**
|
|
36
|
+
* OpenAPI operation metadata type.
|
|
37
|
+
*/
|
|
20
38
|
export type { OpenAPIOperationMeta } from "./openapi-meta";
|
|
39
|
+
/**
|
|
40
|
+
* Path template parsing exports.
|
|
41
|
+
*/
|
|
21
42
|
export {
|
|
22
43
|
type ParsedPathTemplate,
|
|
23
44
|
type PathTemplateSegment,
|
|
24
45
|
parsePathTemplate,
|
|
25
46
|
} from "./path-template";
|
|
47
|
+
/**
|
|
48
|
+
* Rate limit metadata types for contracts.
|
|
49
|
+
*/
|
|
26
50
|
export type { RateLimitMeta, RateLimitScope } from "./rate-limit";
|
|
51
|
+
/**
|
|
52
|
+
* Contract config and inference types.
|
|
53
|
+
*/
|
|
27
54
|
export type {
|
|
28
55
|
AnyContract,
|
|
29
56
|
BodyHttpMethod,
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* OpenAPI operation-level metadata for HTTP contracts
|
|
2
|
+
* OpenAPI operation-level metadata for HTTP contracts.
|
|
3
3
|
*/
|
|
4
4
|
export type OpenAPIOperationMeta = {
|
|
5
|
-
/**
|
|
5
|
+
/** Brief operation summary. */
|
|
6
6
|
summary?: string;
|
|
7
|
-
/**
|
|
7
|
+
/** Detailed operation description. */
|
|
8
8
|
description?: string;
|
|
9
|
-
/** Tags
|
|
9
|
+
/** Tags used to group operations. */
|
|
10
10
|
tags?: string[];
|
|
11
|
-
/**
|
|
11
|
+
/** Whether the operation is deprecated. */
|
|
12
12
|
deprecated?: boolean;
|
|
13
|
-
/** External documentation reference */
|
|
13
|
+
/** External documentation reference. */
|
|
14
14
|
externalDocs?: {
|
|
15
15
|
description?: string;
|
|
16
16
|
url: string;
|
|
17
17
|
};
|
|
18
|
-
/**
|
|
18
|
+
/** Operation ID override. Defaults to `contract.name`. */
|
|
19
19
|
operationId?: string;
|
|
20
|
-
/** Per-operation security requirements */
|
|
20
|
+
/** Per-operation security requirements. */
|
|
21
21
|
security?: Array<Record<string, string[]>>;
|
|
22
22
|
};
|
|
@@ -1,12 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parsed path segment from a Beignet route template.
|
|
3
|
+
*/
|
|
1
4
|
export type PathTemplateSegment =
|
|
2
5
|
| { kind: "static"; value: string }
|
|
3
6
|
| { kind: "dynamic"; name: string; raw: string };
|
|
4
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Parsed representation of a Beignet route path template.
|
|
10
|
+
*/
|
|
5
11
|
export interface ParsedPathTemplate {
|
|
12
|
+
/**
|
|
13
|
+
* Dynamic parameter names in declaration order.
|
|
14
|
+
*/
|
|
6
15
|
keys: string[];
|
|
16
|
+
/**
|
|
17
|
+
* Static and dynamic path segments.
|
|
18
|
+
*/
|
|
7
19
|
segments: PathTemplateSegment[];
|
|
20
|
+
/**
|
|
21
|
+
* Normalized Beignet path using `:param` dynamic syntax.
|
|
22
|
+
*/
|
|
8
23
|
normalizedPath: string;
|
|
24
|
+
/**
|
|
25
|
+
* Route shape used for ambiguity detection, ignoring dynamic parameter names.
|
|
26
|
+
*/
|
|
9
27
|
shapeKey: string;
|
|
28
|
+
/**
|
|
29
|
+
* OpenAPI-compatible path using `{param}` syntax.
|
|
30
|
+
*/
|
|
10
31
|
openApiPath: string;
|
|
11
32
|
}
|
|
12
33
|
|
|
@@ -43,6 +64,12 @@ function parsePathSegment(path: string, segment: string): PathTemplateSegment {
|
|
|
43
64
|
return { kind: "static", value: segment };
|
|
44
65
|
}
|
|
45
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Parse a Beignet route path template.
|
|
69
|
+
*
|
|
70
|
+
* Paths must start with `/`. Dynamic segments may use `:id` or `[id]`.
|
|
71
|
+
* Catch-all segments and partial dynamic segments are intentionally rejected.
|
|
72
|
+
*/
|
|
46
73
|
export function parsePathTemplate(path: string): ParsedPathTemplate {
|
|
47
74
|
if (!path.startsWith("/")) {
|
|
48
75
|
throw new Error(
|