@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.
Files changed (287) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +202 -8
  3. package/dist/application/index.d.ts +93 -9
  4. package/dist/application/index.d.ts.map +1 -1
  5. package/dist/application/index.js +11 -11
  6. package/dist/application/index.js.map +1 -1
  7. package/dist/client/client.d.ts +73 -12
  8. package/dist/client/client.d.ts.map +1 -1
  9. package/dist/client/client.js +37 -12
  10. package/dist/client/client.js.map +1 -1
  11. package/dist/client/index.d.ts +12 -0
  12. package/dist/client/index.d.ts.map +1 -1
  13. package/dist/client/index.js +6 -0
  14. package/dist/client/index.js.map +1 -1
  15. package/dist/client/types.d.ts +69 -8
  16. package/dist/client/types.d.ts.map +1 -1
  17. package/dist/config/index.d.ts +84 -0
  18. package/dist/config/index.d.ts.map +1 -1
  19. package/dist/config/index.js +36 -0
  20. package/dist/config/index.js.map +1 -1
  21. package/dist/contracts/contract-builder.d.ts +49 -22
  22. package/dist/contracts/contract-builder.d.ts.map +1 -1
  23. package/dist/contracts/contract-builder.js +48 -21
  24. package/dist/contracts/contract-builder.js.map +1 -1
  25. package/dist/contracts/contract-group.d.ts +35 -19
  26. package/dist/contracts/contract-group.d.ts.map +1 -1
  27. package/dist/contracts/contract-group.js +35 -19
  28. package/dist/contracts/contract-group.js.map +1 -1
  29. package/dist/contracts/contract-like.d.ts +4 -4
  30. package/dist/contracts/contract-like.d.ts.map +1 -1
  31. package/dist/contracts/contract-like.js +2 -1
  32. package/dist/contracts/contract-like.js.map +1 -1
  33. package/dist/contracts/index.d.ts +28 -0
  34. package/dist/contracts/index.d.ts.map +1 -1
  35. package/dist/contracts/index.js +12 -0
  36. package/dist/contracts/index.js.map +1 -1
  37. package/dist/contracts/openapi-meta.d.ts +8 -8
  38. package/dist/contracts/openapi-meta.d.ts.map +1 -1
  39. package/dist/contracts/path-template.d.ts +27 -0
  40. package/dist/contracts/path-template.d.ts.map +1 -1
  41. package/dist/contracts/path-template.js +6 -0
  42. package/dist/contracts/path-template.js.map +1 -1
  43. package/dist/contracts/types.d.ts +104 -10
  44. package/dist/contracts/types.d.ts.map +1 -1
  45. package/dist/contracts/types.js +15 -0
  46. package/dist/contracts/types.js.map +1 -1
  47. package/dist/contracts/utils.d.ts +6 -0
  48. package/dist/contracts/utils.d.ts.map +1 -1
  49. package/dist/contracts/utils.js +6 -0
  50. package/dist/contracts/utils.js.map +1 -1
  51. package/dist/domain/entity.d.ts +22 -11
  52. package/dist/domain/entity.d.ts.map +1 -1
  53. package/dist/domain/entity.js +5 -1
  54. package/dist/domain/entity.js.map +1 -1
  55. package/dist/domain/events.d.ts +5 -2
  56. package/dist/domain/events.d.ts.map +1 -1
  57. package/dist/domain/events.js +4 -1
  58. package/dist/domain/events.js.map +1 -1
  59. package/dist/domain/value-object.d.ts +19 -9
  60. package/dist/domain/value-object.d.ts.map +1 -1
  61. package/dist/domain/value-object.js +5 -1
  62. package/dist/domain/value-object.js.map +1 -1
  63. package/dist/errors/catalog.d.ts +40 -16
  64. package/dist/errors/catalog.d.ts.map +1 -1
  65. package/dist/errors/catalog.js +18 -7
  66. package/dist/errors/catalog.js.map +1 -1
  67. package/dist/errors/response.d.ts +16 -4
  68. package/dist/errors/response.d.ts.map +1 -1
  69. package/dist/errors/response.js +3 -3
  70. package/dist/errors/response.js.map +1 -1
  71. package/dist/errors/validation.d.ts +10 -1
  72. package/dist/errors/validation.d.ts.map +1 -1
  73. package/dist/errors/validation.js +3 -0
  74. package/dist/errors/validation.js.map +1 -1
  75. package/dist/events/index.d.ts +133 -0
  76. package/dist/events/index.d.ts.map +1 -1
  77. package/dist/events/index.js +30 -0
  78. package/dist/events/index.js.map +1 -1
  79. package/dist/idempotency/index.d.ts +355 -0
  80. package/dist/idempotency/index.d.ts.map +1 -0
  81. package/dist/idempotency/index.js +360 -0
  82. package/dist/idempotency/index.js.map +1 -0
  83. package/dist/jobs/index.d.ts +248 -4
  84. package/dist/jobs/index.d.ts.map +1 -1
  85. package/dist/jobs/index.js +183 -1
  86. package/dist/jobs/index.js.map +1 -1
  87. package/dist/mail/index.d.ts +149 -0
  88. package/dist/mail/index.d.ts.map +1 -1
  89. package/dist/mail/index.js +30 -0
  90. package/dist/mail/index.js.map +1 -1
  91. package/dist/notifications/index.d.ts +369 -0
  92. package/dist/notifications/index.d.ts.map +1 -0
  93. package/dist/notifications/index.js +310 -0
  94. package/dist/notifications/index.js.map +1 -0
  95. package/dist/openapi/index.d.ts +132 -16
  96. package/dist/openapi/index.d.ts.map +1 -1
  97. package/dist/openapi/index.js +1 -1
  98. package/dist/openapi/index.js.map +1 -1
  99. package/dist/outbox/index.d.ts +474 -0
  100. package/dist/outbox/index.d.ts.map +1 -0
  101. package/dist/outbox/index.js +538 -0
  102. package/dist/outbox/index.js.map +1 -0
  103. package/dist/pagination/index.d.ts +166 -0
  104. package/dist/pagination/index.d.ts.map +1 -0
  105. package/dist/pagination/index.js +96 -0
  106. package/dist/pagination/index.js.map +1 -0
  107. package/dist/ports/audit.d.ts +271 -0
  108. package/dist/ports/audit.d.ts.map +1 -1
  109. package/dist/ports/audit.js +128 -0
  110. package/dist/ports/audit.js.map +1 -1
  111. package/dist/ports/auth.d.ts +70 -0
  112. package/dist/ports/auth.d.ts.map +1 -1
  113. package/dist/ports/auth.js +30 -0
  114. package/dist/ports/auth.js.map +1 -1
  115. package/dist/ports/cache.d.ts +41 -0
  116. package/dist/ports/cache.d.ts.map +1 -1
  117. package/dist/ports/cache.js +10 -0
  118. package/dist/ports/cache.js.map +1 -1
  119. package/dist/ports/clock.d.ts +38 -0
  120. package/dist/ports/clock.d.ts.map +1 -1
  121. package/dist/ports/clock.js +20 -0
  122. package/dist/ports/clock.js.map +1 -1
  123. package/dist/ports/id-generator.d.ts +37 -0
  124. package/dist/ports/id-generator.d.ts.map +1 -1
  125. package/dist/ports/id-generator.js +22 -0
  126. package/dist/ports/id-generator.js.map +1 -1
  127. package/dist/ports/index.d.ts +83 -0
  128. package/dist/ports/index.d.ts.map +1 -1
  129. package/dist/ports/index.js +41 -5
  130. package/dist/ports/index.js.map +1 -1
  131. package/dist/ports/logger.d.ts +56 -0
  132. package/dist/ports/logger.d.ts.map +1 -1
  133. package/dist/ports/logger.js +17 -0
  134. package/dist/ports/logger.js.map +1 -1
  135. package/dist/ports/policy.d.ts +132 -0
  136. package/dist/ports/policy.d.ts.map +1 -1
  137. package/dist/ports/policy.js +45 -0
  138. package/dist/ports/policy.js.map +1 -1
  139. package/dist/ports/rate-limit.d.ts +25 -0
  140. package/dist/ports/rate-limit.d.ts.map +1 -1
  141. package/dist/ports/rate-limit.js +10 -0
  142. package/dist/ports/rate-limit.js.map +1 -1
  143. package/dist/ports/redaction.d.ts +101 -0
  144. package/dist/ports/redaction.d.ts.map +1 -1
  145. package/dist/ports/redaction.js +59 -0
  146. package/dist/ports/redaction.js.map +1 -1
  147. package/dist/ports/storage.d.ts +100 -0
  148. package/dist/ports/storage.d.ts.map +1 -1
  149. package/dist/ports/storage.js +10 -0
  150. package/dist/ports/storage.js.map +1 -1
  151. package/dist/ports/testing.d.ts +47 -0
  152. package/dist/ports/testing.d.ts.map +1 -1
  153. package/dist/ports/testing.js +23 -0
  154. package/dist/ports/testing.js.map +1 -1
  155. package/dist/ports/unit-of-work.d.ts +60 -3
  156. package/dist/ports/unit-of-work.d.ts.map +1 -1
  157. package/dist/ports/unit-of-work.js +11 -2
  158. package/dist/ports/unit-of-work.js.map +1 -1
  159. package/dist/providers/instrumentation.d.ts +205 -1
  160. package/dist/providers/instrumentation.d.ts.map +1 -1
  161. package/dist/providers/instrumentation.js +14 -0
  162. package/dist/providers/instrumentation.js.map +1 -1
  163. package/dist/providers/provider.d.ts +14 -1
  164. package/dist/providers/provider.d.ts.map +1 -1
  165. package/dist/providers/provider.js.map +1 -1
  166. package/dist/schedules/index.d.ts +246 -0
  167. package/dist/schedules/index.d.ts.map +1 -1
  168. package/dist/schedules/index.js +27 -0
  169. package/dist/schedules/index.js.map +1 -1
  170. package/dist/server/health.d.ts +14 -5
  171. package/dist/server/health.d.ts.map +1 -1
  172. package/dist/server/health.js +5 -2
  173. package/dist/server/health.js.map +1 -1
  174. package/dist/server/hooks/auth.d.ts +68 -26
  175. package/dist/server/hooks/auth.d.ts.map +1 -1
  176. package/dist/server/hooks/auth.js +44 -55
  177. package/dist/server/hooks/auth.js.map +1 -1
  178. package/dist/server/hooks/cors.d.ts +27 -0
  179. package/dist/server/hooks/cors.d.ts.map +1 -1
  180. package/dist/server/hooks/cors.js +12 -0
  181. package/dist/server/hooks/cors.js.map +1 -1
  182. package/dist/server/hooks/errors.d.ts +15 -6
  183. package/dist/server/hooks/errors.d.ts.map +1 -1
  184. package/dist/server/hooks/errors.js.map +1 -1
  185. package/dist/server/hooks/index.d.ts +4 -1
  186. package/dist/server/hooks/index.d.ts.map +1 -1
  187. package/dist/server/hooks/index.js +3 -0
  188. package/dist/server/hooks/index.js.map +1 -1
  189. package/dist/server/hooks/logging.d.ts +36 -0
  190. package/dist/server/hooks/logging.d.ts.map +1 -1
  191. package/dist/server/hooks/logging.js +6 -0
  192. package/dist/server/hooks/logging.js.map +1 -1
  193. package/dist/server/hooks/rate-limit.d.ts +33 -0
  194. package/dist/server/hooks/rate-limit.d.ts.map +1 -1
  195. package/dist/server/hooks/rate-limit.js +11 -0
  196. package/dist/server/hooks/rate-limit.js.map +1 -1
  197. package/dist/server/http.d.ts +222 -0
  198. package/dist/server/http.d.ts.map +1 -1
  199. package/dist/server/http.js +20 -1
  200. package/dist/server/http.js.map +1 -1
  201. package/dist/server/index.d.ts +19 -1
  202. package/dist/server/index.d.ts.map +1 -1
  203. package/dist/server/index.js +7 -1
  204. package/dist/server/index.js.map +1 -1
  205. package/dist/server/openapi.d.ts +5 -3
  206. package/dist/server/openapi.d.ts.map +1 -1
  207. package/dist/server/openapi.js +4 -2
  208. package/dist/server/openapi.js.map +1 -1
  209. package/dist/server/providers/loadProviderConfig.d.ts +9 -0
  210. package/dist/server/providers/loadProviderConfig.d.ts.map +1 -1
  211. package/dist/server/providers/loadProviderConfig.js +9 -0
  212. package/dist/server/providers/loadProviderConfig.js.map +1 -1
  213. package/dist/server/server.d.ts +159 -19
  214. package/dist/server/server.d.ts.map +1 -1
  215. package/dist/server/server.js +72 -31
  216. package/dist/server/server.js.map +1 -1
  217. package/dist/testing/index.d.ts +171 -0
  218. package/dist/testing/index.d.ts.map +1 -0
  219. package/dist/testing/index.js +127 -0
  220. package/dist/testing/index.js.map +1 -0
  221. package/dist/uploads/client.d.ts +278 -0
  222. package/dist/uploads/client.d.ts.map +1 -0
  223. package/dist/uploads/client.js +428 -0
  224. package/dist/uploads/client.js.map +1 -0
  225. package/dist/uploads/index.d.ts +361 -0
  226. package/dist/uploads/index.d.ts.map +1 -0
  227. package/dist/uploads/index.js +543 -0
  228. package/dist/uploads/index.js.map +1 -0
  229. package/package.json +31 -2
  230. package/src/application/index.ts +85 -22
  231. package/src/client/client.ts +73 -12
  232. package/src/client/index.ts +12 -0
  233. package/src/client/types.ts +70 -9
  234. package/src/config/index.ts +86 -0
  235. package/src/contracts/contract-builder.ts +49 -22
  236. package/src/contracts/contract-group.ts +35 -19
  237. package/src/contracts/contract-like.ts +4 -4
  238. package/src/contracts/index.ts +28 -1
  239. package/src/contracts/openapi-meta.ts +8 -8
  240. package/src/contracts/path-template.ts +27 -0
  241. package/src/contracts/types.ts +111 -10
  242. package/src/contracts/utils.ts +6 -0
  243. package/src/domain/entity.ts +22 -11
  244. package/src/domain/events.ts +5 -2
  245. package/src/domain/value-object.ts +19 -9
  246. package/src/errors/catalog.ts +40 -16
  247. package/src/errors/response.ts +16 -4
  248. package/src/errors/validation.ts +10 -1
  249. package/src/events/index.ts +134 -0
  250. package/src/idempotency/index.ts +767 -0
  251. package/src/jobs/index.ts +437 -5
  252. package/src/mail/index.ts +149 -0
  253. package/src/notifications/index.ts +771 -0
  254. package/src/openapi/index.ts +133 -16
  255. package/src/outbox/index.ts +1104 -0
  256. package/src/pagination/index.ts +278 -0
  257. package/src/ports/audit.ts +271 -0
  258. package/src/ports/auth.ts +70 -0
  259. package/src/ports/cache.ts +41 -0
  260. package/src/ports/clock.ts +38 -0
  261. package/src/ports/id-generator.ts +37 -0
  262. package/src/ports/index.ts +106 -11
  263. package/src/ports/logger.ts +56 -0
  264. package/src/ports/policy.ts +133 -0
  265. package/src/ports/rate-limit.ts +25 -0
  266. package/src/ports/redaction.ts +101 -0
  267. package/src/ports/storage.ts +100 -0
  268. package/src/ports/testing.ts +47 -0
  269. package/src/ports/unit-of-work.ts +60 -3
  270. package/src/providers/instrumentation.ts +211 -1
  271. package/src/providers/provider.ts +14 -1
  272. package/src/schedules/index.ts +247 -0
  273. package/src/server/health.ts +14 -5
  274. package/src/server/hooks/auth.ts +105 -120
  275. package/src/server/hooks/cors.ts +27 -0
  276. package/src/server/hooks/errors.ts +15 -6
  277. package/src/server/hooks/index.ts +4 -5
  278. package/src/server/hooks/logging.ts +36 -0
  279. package/src/server/hooks/rate-limit.ts +33 -0
  280. package/src/server/http.ts +249 -1
  281. package/src/server/index.ts +19 -1
  282. package/src/server/openapi.ts +5 -3
  283. package/src/server/providers/loadProviderConfig.ts +9 -0
  284. package/src/server/server.ts +296 -30
  285. package/src/testing/index.ts +348 -0
  286. package/src/uploads/client.ts +861 -0
  287. package/src/uploads/index.ts +1067 -0
@@ -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
- * Contract builder for constructing HTTP contracts in a fluent API style
76
- * Schemas are accessible via the .schema property for introspection
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
- * Access schemas for introspection
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
- * Get response schemas for introspection
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
- * Get the URL path template
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
- * Get the URL path (alias for pathTemplate)
167
+ * URL path template alias.
161
168
  */
162
169
  get path(): TPath {
163
170
  return this._path;
164
171
  }
165
172
 
166
173
  /**
167
- * Get contract metadata
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
- * Get the contract as an HttpContractConfig object
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
- * Set path parameters schema (chainable builder method)
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
- * Set query parameters schema (chainable builder method)
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
- * Set request body schema (chainable builder method)
267
- * Only available on POST, PUT, and PATCH contracts.
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
- * Add request header schema (chainable).
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 keeps group-level headers library-agnostic.
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 (chainable).
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. Use
408
- * `.responses()` when a route needs a custom error response body.
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
- * Set or merge contract metadata (chainable builder method)
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
- * Set or merge OpenAPI metadata for this operation (chainable)
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 a contract with the factory function
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 with the builder pattern.
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
- * ContractGroup is a feature-scoped factory for creating related contracts
107
- * with shared configuration. Immutable — each method returns a new instance.
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 all contracts created from this group
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 all contracts created from this group.
165
+ * Add a path prefix to contracts created from this group.
160
166
  *
161
- * Prefixes compose immutably, so `prefix("/api").prefix("/v1")`
162
- * produces paths under `/api/v1`.
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
- * Set shared metadata for all contracts created from this group
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
- * Set shared response schemas for all contracts created from this group.
211
- * Typically used for shared error responses (e.g. 401, 403, 500).
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
- * Set shared route-owned application errors for all contracts in the group.
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 for all contracts created from this group.
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 a OPTIONS contract
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 ContractGroup for grouping related contracts with shared configuration.
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
- * A type that represents either a raw HttpContractConfig
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
- * Resolves a ContractLike to its underlying HttpContractConfig
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
- * Helper function to resolve a ContractLike to its underlying HttpContractConfig
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
  */
@@ -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
- /** A brief summary of the operation */
5
+ /** Brief operation summary. */
6
6
  summary?: string;
7
- /** A detailed description of the operation */
7
+ /** Detailed operation description. */
8
8
  description?: string;
9
- /** Tags for grouping operations */
9
+ /** Tags used to group operations. */
10
10
  tags?: string[];
11
- /** Marks the operation as deprecated */
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
- /** Override for operationId (default is contract.name) */
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(