@beignet/core 0.0.33 → 0.0.35

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 (142) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +207 -30
  3. package/dist/agent-capabilities/index.d.ts +167 -0
  4. package/dist/agent-capabilities/index.d.ts.map +1 -0
  5. package/dist/agent-capabilities/index.js +275 -0
  6. package/dist/agent-capabilities/index.js.map +1 -0
  7. package/dist/application/index.d.ts +2 -2
  8. package/dist/application/index.d.ts.map +1 -1
  9. package/dist/application/index.js +13 -3
  10. package/dist/application/index.js.map +1 -1
  11. package/dist/client/client.d.ts +2 -0
  12. package/dist/client/client.d.ts.map +1 -1
  13. package/dist/client/client.js +33 -16
  14. package/dist/client/client.js.map +1 -1
  15. package/dist/contracts/contract-builder.d.ts +5 -7
  16. package/dist/contracts/contract-builder.d.ts.map +1 -1
  17. package/dist/contracts/contract-builder.js +3 -18
  18. package/dist/contracts/contract-builder.js.map +1 -1
  19. package/dist/contracts/contract-group.d.ts +2 -2
  20. package/dist/contracts/contract-group.d.ts.map +1 -1
  21. package/dist/contracts/contract-group.js +2 -1
  22. package/dist/contracts/contract-group.js.map +1 -1
  23. package/dist/contracts/metadata.d.ts +3 -0
  24. package/dist/contracts/metadata.d.ts.map +1 -0
  25. package/dist/contracts/metadata.js +14 -0
  26. package/dist/contracts/metadata.js.map +1 -0
  27. package/dist/contracts/types.d.ts +20 -0
  28. package/dist/contracts/types.d.ts.map +1 -1
  29. package/dist/contracts/types.js.map +1 -1
  30. package/dist/events/index.d.ts +4 -4
  31. package/dist/events/index.d.ts.map +1 -1
  32. package/dist/events/index.js +5 -5
  33. package/dist/events/index.js.map +1 -1
  34. package/dist/flags/index.d.ts +0 -4
  35. package/dist/flags/index.d.ts.map +1 -1
  36. package/dist/flags/index.js +0 -4
  37. package/dist/flags/index.js.map +1 -1
  38. package/dist/idempotency/index.d.ts.map +1 -1
  39. package/dist/idempotency/index.js +14 -9
  40. package/dist/idempotency/index.js.map +1 -1
  41. package/dist/jobs/index.d.ts.map +1 -1
  42. package/dist/jobs/index.js +10 -4
  43. package/dist/jobs/index.js.map +1 -1
  44. package/dist/notifications/index.d.ts +194 -10
  45. package/dist/notifications/index.d.ts.map +1 -1
  46. package/dist/notifications/index.js +397 -59
  47. package/dist/notifications/index.js.map +1 -1
  48. package/dist/openapi/index.js +15 -8
  49. package/dist/openapi/index.js.map +1 -1
  50. package/dist/ports/auth.d.ts +2 -0
  51. package/dist/ports/auth.d.ts.map +1 -1
  52. package/dist/ports/auth.js +2 -0
  53. package/dist/ports/auth.js.map +1 -1
  54. package/dist/ports/events.d.ts +2 -2
  55. package/dist/ports/index.d.ts +1 -1
  56. package/dist/ports/index.d.ts.map +1 -1
  57. package/dist/ports/index.js +1 -1
  58. package/dist/ports/index.js.map +1 -1
  59. package/dist/providers/index.d.ts +1 -1
  60. package/dist/providers/index.d.ts.map +1 -1
  61. package/dist/providers/index.js.map +1 -1
  62. package/dist/providers/provider.d.ts +10 -2
  63. package/dist/providers/provider.d.ts.map +1 -1
  64. package/dist/providers/provider.js.map +1 -1
  65. package/dist/schedules/index.d.ts +6 -13
  66. package/dist/schedules/index.d.ts.map +1 -1
  67. package/dist/schedules/index.js +24 -44
  68. package/dist/schedules/index.js.map +1 -1
  69. package/dist/server/index.d.ts +2 -2
  70. package/dist/server/index.d.ts.map +1 -1
  71. package/dist/server/index.js +1 -1
  72. package/dist/server/index.js.map +1 -1
  73. package/dist/server/request-executor.d.ts +72 -0
  74. package/dist/server/request-executor.d.ts.map +1 -0
  75. package/dist/server/request-executor.js +781 -0
  76. package/dist/server/request-executor.js.map +1 -0
  77. package/dist/server/request-preparation.d.ts +39 -0
  78. package/dist/server/request-preparation.d.ts.map +1 -0
  79. package/dist/server/request-preparation.js +248 -0
  80. package/dist/server/request-preparation.js.map +1 -0
  81. package/dist/server/response-finalization.d.ts +34 -0
  82. package/dist/server/response-finalization.d.ts.map +1 -0
  83. package/dist/server/response-finalization.js +279 -0
  84. package/dist/server/response-finalization.js.map +1 -0
  85. package/dist/server/route-definitions.d.ts +139 -0
  86. package/dist/server/route-definitions.d.ts.map +1 -0
  87. package/dist/server/route-definitions.js +94 -0
  88. package/dist/server/route-definitions.js.map +1 -0
  89. package/dist/server/route-matching.d.ts +15 -0
  90. package/dist/server/route-matching.d.ts.map +1 -0
  91. package/dist/server/route-matching.js +46 -0
  92. package/dist/server/route-matching.js.map +1 -0
  93. package/dist/server/server.d.ts +6 -157
  94. package/dist/server/server.d.ts.map +1 -1
  95. package/dist/server/server.js +29 -1340
  96. package/dist/server/server.js.map +1 -1
  97. package/dist/server/use-case-route.d.ts +1 -1
  98. package/dist/testing/index.d.ts +1 -1
  99. package/dist/testing/index.d.ts.map +1 -1
  100. package/dist/testing/index.js +1 -0
  101. package/dist/testing/index.js.map +1 -1
  102. package/dist/tracing/index.d.ts +1 -1
  103. package/dist/tracing/index.d.ts.map +1 -1
  104. package/dist/tracing/index.js.map +1 -1
  105. package/dist/uploads/client.js +4 -7
  106. package/dist/uploads/client.js.map +1 -1
  107. package/dist/uploads/index.d.ts.map +1 -1
  108. package/dist/uploads/index.js +59 -12
  109. package/dist/uploads/index.js.map +1 -1
  110. package/package.json +5 -5
  111. package/skills/app-architecture/SKILL.md +31 -1
  112. package/src/agent-capabilities/index.ts +578 -0
  113. package/src/application/index.ts +19 -5
  114. package/src/client/client.ts +41 -17
  115. package/src/contracts/contract-builder.ts +8 -23
  116. package/src/contracts/contract-group.ts +4 -6
  117. package/src/contracts/metadata.ts +20 -0
  118. package/src/contracts/types.ts +39 -0
  119. package/src/events/index.ts +16 -20
  120. package/src/flags/index.ts +0 -5
  121. package/src/idempotency/index.ts +17 -9
  122. package/src/jobs/index.ts +8 -3
  123. package/src/notifications/index.ts +678 -70
  124. package/src/openapi/index.ts +24 -12
  125. package/src/ports/auth.ts +2 -0
  126. package/src/ports/events.ts +2 -2
  127. package/src/ports/index.ts +0 -1
  128. package/src/providers/index.ts +1 -0
  129. package/src/providers/provider.ts +18 -3
  130. package/src/schedules/index.ts +57 -63
  131. package/src/server/index.ts +4 -2
  132. package/src/server/request-executor.ts +1170 -0
  133. package/src/server/request-preparation.ts +409 -0
  134. package/src/server/response-finalization.ts +385 -0
  135. package/src/server/route-definitions.ts +338 -0
  136. package/src/server/route-matching.ts +64 -0
  137. package/src/server/server.ts +63 -2171
  138. package/src/server/use-case-route.ts +1 -1
  139. package/src/testing/index.ts +2 -0
  140. package/src/tracing/index.ts +1 -0
  141. package/src/uploads/client.ts +4 -7
  142. package/src/uploads/index.ts +70 -12
@@ -553,10 +553,13 @@ function addPathParams(
553
553
 
554
554
  const shape = state.introspector.getShape(contract.pathParams);
555
555
  if (!shape) {
556
- if (pathKeys.length > 0) {
557
- throw new Error(
558
- `Unable to introspect pathParams for contract "${contract.name}" at "${contract.path}". OpenAPI path parameters must match the path template.`,
559
- );
556
+ for (const key of pathKeys) {
557
+ addParameter(operation, {
558
+ name: key,
559
+ in: "path",
560
+ required: true,
561
+ schema: { type: "string" },
562
+ });
560
563
  }
561
564
  return;
562
565
  }
@@ -612,14 +615,8 @@ function addQueryParams(
612
615
  const originalField = shape[key];
613
616
  const optional = state.introspector.isOptional(originalField);
614
617
 
615
- let description = state.introspector.getDescription(originalField);
616
-
617
618
  const field = originalField;
618
-
619
- // If outer optional didn't have description, check inner type
620
- if (!description && optional) {
621
- description = state.introspector.getDescription(field);
622
- }
619
+ const description = parameterDescription(field, optional, state);
623
620
 
624
621
  const paramSchemaRef = schemaToConvertedSchemaRef(
625
622
  field,
@@ -656,7 +653,7 @@ function addHeaderParams(
656
653
  for (const key of Object.keys(shape)) {
657
654
  const originalField = shape[key];
658
655
  const optional = state.introspector.isOptional(originalField);
659
- const description = state.introspector.getDescription(originalField);
656
+ const description = parameterDescription(originalField, optional, state);
660
657
 
661
658
  const paramSchemaRef = schemaToConvertedSchemaRef(
662
659
  originalField,
@@ -676,6 +673,21 @@ function addHeaderParams(
676
673
  }
677
674
  }
678
675
 
676
+ function parameterDescription(
677
+ field: unknown,
678
+ optional: boolean,
679
+ state: GeneratorState,
680
+ ): string | undefined {
681
+ return (
682
+ state.introspector.getDescription(field) ??
683
+ (optional
684
+ ? state.introspector.getDescription(
685
+ state.introspector.unwrapOptional(field),
686
+ )
687
+ : undefined)
688
+ );
689
+ }
690
+
679
691
  /**
680
692
  * Add request body from contract to operation
681
693
  */
package/src/ports/auth.ts CHANGED
@@ -36,6 +36,8 @@ export interface AuthSession<User = unknown, Session = unknown> {
36
36
  */
37
37
  export class AuthUnauthorizedError extends Error {
38
38
  readonly code = "UNAUTHORIZED";
39
+ /** HTTP status used when the server maps this framework error. */
40
+ readonly status = 401;
39
41
 
40
42
  constructor(message = "Unauthorized") {
41
43
  super(message);
@@ -51,9 +51,9 @@ export type InferJobPayload<J extends JobDef> = InferContractJobPayload<J>;
51
51
  *
52
52
  * @example
53
53
  * ```ts
54
- * import { createInMemoryEventBus } from "@beignet/provider-event-bus-memory";
54
+ * import { createMemoryEventBus } from "@beignet/provider-event-bus-memory";
55
55
  *
56
- * const eventBus = createInMemoryEventBus();
56
+ * const eventBus = createMemoryEventBus();
57
57
  *
58
58
  * // Subscribe to an event
59
59
  * const unsubscribe = eventBus.subscribe(UserRegistered, (payload) => {
@@ -224,7 +224,6 @@ export {
224
224
  createMemoryFlags,
225
225
  createStaticFlags,
226
226
  defineFlag,
227
- defineFlagRegistry,
228
227
  defineFlags,
229
228
  evaluateFlag,
230
229
  getFlagDetails,
@@ -39,6 +39,7 @@ export {
39
39
  parseProviderPackageMetadata,
40
40
  } from "./metadata.js";
41
41
  export {
42
+ type AnyProviderConfigSchema,
42
43
  type AnyServiceProvider,
43
44
  createProvider,
44
45
  type InferOutput,
@@ -170,7 +170,7 @@ export interface ServiceProviderMetadata {
170
170
  *
171
171
  * @example
172
172
  * ```ts
173
- * const redisCacheProvider = createProvider({
173
+ * const cacheProvider = createProvider({
174
174
  * name: "cache-redis",
175
175
  * config: {
176
176
  * schema: z.object({ URL: z.string().url() }),
@@ -240,6 +240,22 @@ export interface ServiceProvider<
240
240
  readonly __providedPorts?: ProvidedPorts;
241
241
  }
242
242
 
243
+ /**
244
+ * A provider configuration schema whose concrete validation library and input
245
+ * shape are intentionally erased while its validated output may stay typed.
246
+ *
247
+ * Reusable provider packages use this in their named provider return types so
248
+ * internal Zod schemas do not become part of the package's public API.
249
+ */
250
+ export type AnyProviderConfigSchema<
251
+ // biome-ignore lint/suspicious/noExplicitAny: arbitrary provider consumers may erase config output
252
+ Output = any,
253
+ > = StandardSchemaV1<
254
+ // biome-ignore lint/suspicious/noExplicitAny: reusable provider return types intentionally erase config input
255
+ any,
256
+ Output
257
+ >;
258
+
243
259
  /**
244
260
  * Loosely typed service provider.
245
261
  *
@@ -250,8 +266,7 @@ export interface ServiceProvider<
250
266
  */
251
267
  export type AnyServiceProvider = ServiceProvider<
252
268
  unknown,
253
- // biome-ignore lint/suspicious/noExplicitAny: provider config types are erased at this level
254
- StandardSchemaV1<any, any>,
269
+ AnyProviderConfigSchema,
255
270
  ProviderPorts,
256
271
  // biome-ignore lint/suspicious/noExplicitAny: provider context types are erased at this level
257
272
  any,
@@ -1,4 +1,9 @@
1
1
  import type { StandardSchemaV1 } from "@standard-schema/spec";
2
+ import {
3
+ createProviderInstrumentation,
4
+ type ProviderInstrumentation,
5
+ type ProviderInstrumentationTarget,
6
+ } from "../providers/index.js";
2
7
  import { runWithResolvedTracingContext } from "../tracing/execution.js";
3
8
  import type { TracingPort } from "../tracing/index.js";
4
9
 
@@ -312,16 +317,6 @@ export interface ScheduleDevtoolsEvent {
312
317
  details?: Record<string, unknown>;
313
318
  }
314
319
 
315
- /**
316
- * Sink for schedule devtools events, usually `ctx.ports.devtools`.
317
- */
318
- export interface ScheduleInstrumentation {
319
- /**
320
- * Record one schedule devtools event.
321
- */
322
- record(event: ScheduleDevtoolsEvent): unknown;
323
- }
324
-
325
320
  /**
326
321
  * Correlation fields attached to schedule instrumentation events.
327
322
  */
@@ -381,13 +376,14 @@ export interface InlineScheduleRunnerOptions<Ctx> {
381
376
  */
382
377
  now?: () => Date;
383
378
  /**
384
- * Devtools-compatible sink that receives `schedule` events for each run.
379
+ * Provider instrumentation target that receives `schedule` events for each
380
+ * run. Pass `ctx.ports`, `ctx.ports.instrumentation`, or
381
+ * `ctx.ports.devtools` directly.
385
382
  *
386
383
  * The runner records `started`, `completed`, and `failed` events. Recording
387
- * failures are isolated from schedule execution and reported to
388
- * `onHookError` when provided.
384
+ * failures are isolated from schedule execution.
389
385
  */
390
- instrumentation?: ScheduleInstrumentation;
386
+ instrumentation?: ProviderInstrumentationTarget;
391
387
  /**
392
388
  * Correlation fields attached to recorded schedule events.
393
389
  */
@@ -675,45 +671,28 @@ async function recordScheduleEvent<
675
671
  Ctx,
676
672
  S extends ScheduleDef<string, StandardSchema, Ctx>,
677
673
  >(
678
- options: InlineScheduleRunnerOptions<Ctx>,
674
+ instrumentation: ProviderInstrumentation,
675
+ instrumentationContext: ScheduleInstrumentationContext | undefined,
679
676
  schedule: S,
680
677
  status: ScheduleDevtoolsEvent["status"],
681
678
  run: ScheduleRunContext,
682
- args: {
683
- payload?: InferSchedulePayload<S>;
684
- hook: ScheduleHookName;
685
- scheduleError?: unknown;
686
- details?: Record<string, unknown>;
687
- },
679
+ details?: Record<string, unknown>,
688
680
  ): Promise<void> {
689
- if (!options.instrumentation) return;
690
-
691
- try {
692
- options.instrumentation.record({
693
- type: "schedule",
694
- watcher: "schedules",
695
- requestId: options.instrumentationContext?.requestId,
696
- traceId: options.instrumentationContext?.traceId,
697
- scheduleName: schedule.name,
698
- status,
699
- cron: schedule.cron,
700
- timezone: schedule.timezone,
701
- details: {
702
- source: run.source,
703
- scheduledAt: run.scheduledAt?.toISOString(),
704
- ...args.details,
705
- },
706
- });
707
- } catch (error) {
708
- await reportHookError(options.onHookError, {
709
- schedule,
710
- payload: args.payload,
711
- run,
712
- hook: args.hook,
713
- error,
714
- scheduleError: args.scheduleError,
715
- });
716
- }
681
+ instrumentation.record({
682
+ type: "schedule",
683
+ watcher: "schedules",
684
+ requestId: instrumentationContext?.requestId,
685
+ traceId: instrumentationContext?.traceId,
686
+ scheduleName: schedule.name,
687
+ status,
688
+ cron: schedule.cron,
689
+ timezone: schedule.timezone,
690
+ details: {
691
+ source: run.source,
692
+ scheduledAt: run.scheduledAt?.toISOString(),
693
+ ...details,
694
+ },
695
+ });
717
696
  }
718
697
 
719
698
  function defineScheduleImpl<
@@ -785,6 +764,13 @@ export function createInlineScheduleRunner<Ctx>(
785
764
  options: InlineScheduleRunnerOptions<Ctx> = {},
786
765
  ): InlineScheduleRunner<Ctx> {
787
766
  const now = options.now ?? (() => new Date());
767
+ const instrumentation = createProviderInstrumentation(
768
+ options.instrumentation,
769
+ {
770
+ providerName: "schedules",
771
+ watcher: "schedules",
772
+ },
773
+ );
788
774
 
789
775
  return {
790
776
  async run<S extends ScheduleDef<string, StandardSchema, Ctx>>(
@@ -798,10 +784,13 @@ export function createInlineScheduleRunner<Ctx>(
798
784
  payload = await resolveSchedulePayload(schedule, runOptions, run);
799
785
 
800
786
  const lifecycleArgs = { schedule, payload, run };
801
- await recordScheduleEvent(options, schedule, "started", run, {
802
- payload,
803
- hook: "start",
804
- });
787
+ await recordScheduleEvent(
788
+ instrumentation,
789
+ options.instrumentationContext,
790
+ schedule,
791
+ "started",
792
+ run,
793
+ );
805
794
  await runLifecycleHook(
806
795
  "start",
807
796
  options.onStart,
@@ -820,10 +809,13 @@ export function createInlineScheduleRunner<Ctx>(
820
809
  run,
821
810
  }),
822
811
  });
823
- await recordScheduleEvent(options, schedule, "completed", run, {
824
- payload,
825
- hook: "success",
826
- });
812
+ await recordScheduleEvent(
813
+ instrumentation,
814
+ options.instrumentationContext,
815
+ schedule,
816
+ "completed",
817
+ run,
818
+ );
827
819
  await runLifecycleHook(
828
820
  "success",
829
821
  options.onSuccess,
@@ -831,12 +823,14 @@ export function createInlineScheduleRunner<Ctx>(
831
823
  lifecycleArgs,
832
824
  );
833
825
  } catch (error) {
834
- await recordScheduleEvent(options, schedule, "failed", run, {
835
- payload,
836
- hook: "error",
837
- scheduleError: error,
838
- details: { error },
839
- });
826
+ await recordScheduleEvent(
827
+ instrumentation,
828
+ options.instrumentationContext,
829
+ schedule,
830
+ "failed",
831
+ run,
832
+ { error },
833
+ );
840
834
  await runErrorHook(options.onError, options.onHookError, {
841
835
  error,
842
836
  schedule,
@@ -76,7 +76,10 @@ export type {
76
76
  RawRouteBuilder,
77
77
  RawRouteInit,
78
78
  RouteDef,
79
+ RouteDefinitionBuilder,
79
80
  RouteGroup,
81
+ RouteGroupBuilder,
82
+ Routes,
80
83
  ServerInstance,
81
84
  } from "./server.js";
82
85
  /**
@@ -84,9 +87,8 @@ export type {
84
87
  */
85
88
  export {
86
89
  contractsFromRoutes,
90
+ createRoutes,
87
91
  createServer,
88
- defineRoute,
89
- defineRouteGroup,
90
92
  defineRoutes,
91
93
  } from "./server.js";
92
94
  /**