@beignet/core 0.0.2 → 0.0.4
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 +173 -0
- package/README.md +821 -30
- package/dist/application/index.d.ts +28 -2
- package/dist/application/index.d.ts.map +1 -1
- package/dist/application/index.js +140 -12
- package/dist/application/index.js.map +1 -1
- package/dist/client/client.d.ts +2 -2
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +136 -48
- package/dist/client/client.js.map +1 -1
- package/dist/client/error-messages.d.ts +14 -0
- package/dist/client/error-messages.d.ts.map +1 -0
- package/dist/client/error-messages.js +23 -0
- package/dist/client/error-messages.js.map +1 -0
- package/dist/client/index.d.ts +8 -4
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +6 -2
- package/dist/client/index.js.map +1 -1
- package/dist/client/types.d.ts +35 -5
- package/dist/client/types.d.ts.map +1 -1
- package/dist/client-only.d.ts +8 -0
- package/dist/client-only.d.ts.map +1 -0
- package/dist/client-only.js +8 -0
- package/dist/client-only.js.map +1 -0
- package/dist/config/index.d.ts +5 -5
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +2 -2
- package/dist/config/index.js.map +1 -1
- package/dist/contracts/catalog-errors.d.ts +27 -0
- package/dist/contracts/catalog-errors.d.ts.map +1 -0
- package/dist/contracts/catalog-errors.js +69 -0
- package/dist/contracts/catalog-errors.js.map +1 -0
- package/dist/contracts/contract-builder.d.ts +15 -12
- package/dist/contracts/contract-builder.d.ts.map +1 -1
- package/dist/contracts/contract-builder.js +15 -41
- package/dist/contracts/contract-builder.js.map +1 -1
- package/dist/contracts/contract-group.d.ts +11 -8
- package/dist/contracts/contract-group.d.ts.map +1 -1
- package/dist/contracts/contract-group.js +13 -40
- package/dist/contracts/contract-group.js.map +1 -1
- package/dist/contracts/contract-like.d.ts +1 -1
- package/dist/contracts/contract-like.d.ts.map +1 -1
- package/dist/contracts/index.d.ts +13 -9
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/index.js +9 -5
- package/dist/contracts/index.js.map +1 -1
- package/dist/contracts/openapi-meta.d.ts +48 -0
- package/dist/contracts/openapi-meta.d.ts.map +1 -1
- package/dist/contracts/openapi-meta.js +3 -0
- package/dist/contracts/openapi-meta.js.map +1 -1
- package/dist/contracts/path-template.d.ts +1 -1
- package/dist/contracts/path-template.js +2 -2
- package/dist/contracts/path-template.js.map +1 -1
- package/dist/contracts/schema-shape.d.ts +37 -0
- package/dist/contracts/schema-shape.d.ts.map +1 -0
- package/dist/contracts/schema-shape.js +61 -0
- package/dist/contracts/schema-shape.js.map +1 -0
- package/dist/contracts/success-status.d.ts +32 -0
- package/dist/contracts/success-status.d.ts.map +1 -0
- package/dist/contracts/success-status.js +18 -0
- package/dist/contracts/success-status.js.map +1 -0
- package/dist/contracts/types.d.ts +25 -5
- package/dist/contracts/types.d.ts.map +1 -1
- package/dist/contracts/types.js.map +1 -1
- package/dist/contracts/utils.d.ts +1 -1
- package/dist/contracts/utils.d.ts.map +1 -1
- package/dist/contracts/utils.js +1 -1
- package/dist/contracts/utils.js.map +1 -1
- package/dist/domain/events.d.ts +1 -1
- package/dist/domain/events.d.ts.map +1 -1
- package/dist/domain/events.js +1 -1
- package/dist/domain/events.js.map +1 -1
- package/dist/domain/index.d.ts +3 -3
- package/dist/domain/index.d.ts.map +1 -1
- package/dist/domain/index.js +3 -3
- package/dist/domain/index.js.map +1 -1
- package/dist/errors/catalog.d.ts +9 -1
- package/dist/errors/catalog.d.ts.map +1 -1
- package/dist/errors/catalog.js +7 -1
- package/dist/errors/catalog.js.map +1 -1
- package/dist/errors/http.d.ts +10 -0
- package/dist/errors/http.d.ts.map +1 -1
- package/dist/errors/http.js +11 -1
- package/dist/errors/http.js.map +1 -1
- package/dist/errors/index.d.ts +4 -4
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +4 -4
- package/dist/errors/index.js.map +1 -1
- package/dist/errors/response.d.ts +4 -1
- package/dist/errors/response.d.ts.map +1 -1
- package/dist/errors/response.js.map +1 -1
- package/dist/events/index.d.ts +10 -12
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +10 -10
- package/dist/events/index.js.map +1 -1
- package/dist/idempotency/index.d.ts +5 -3
- package/dist/idempotency/index.d.ts.map +1 -1
- package/dist/idempotency/index.js.map +1 -1
- package/dist/jobs/index.d.ts +148 -16
- package/dist/jobs/index.d.ts.map +1 -1
- package/dist/jobs/index.js +174 -14
- package/dist/jobs/index.js.map +1 -1
- package/dist/notifications/index.d.ts +14 -16
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +14 -14
- package/dist/notifications/index.js.map +1 -1
- package/dist/openapi/index.d.ts +8 -3
- package/dist/openapi/index.d.ts.map +1 -1
- package/dist/openapi/index.js +41 -29
- package/dist/openapi/index.js.map +1 -1
- package/dist/openapi/schema-introspector.d.ts +37 -0
- package/dist/openapi/schema-introspector.d.ts.map +1 -1
- package/dist/openapi/schema-introspector.js +23 -17
- package/dist/openapi/schema-introspector.js.map +1 -1
- package/dist/outbox/index.d.ts +18 -4
- package/dist/outbox/index.d.ts.map +1 -1
- package/dist/outbox/index.js +104 -4
- package/dist/outbox/index.js.map +1 -1
- package/dist/ports/audit.d.ts +56 -10
- package/dist/ports/audit.d.ts.map +1 -1
- package/dist/ports/audit.js +71 -3
- package/dist/ports/audit.js.map +1 -1
- package/dist/ports/auth.d.ts +92 -0
- package/dist/ports/auth.d.ts.map +1 -1
- package/dist/ports/auth.js +92 -0
- package/dist/ports/auth.js.map +1 -1
- package/dist/ports/events.d.ts +2 -2
- package/dist/ports/events.d.ts.map +1 -1
- package/dist/ports/index.d.ts +62 -33
- package/dist/ports/index.d.ts.map +1 -1
- package/dist/ports/index.js +28 -34
- package/dist/ports/index.js.map +1 -1
- package/dist/ports/policy.d.ts +32 -3
- package/dist/ports/policy.d.ts.map +1 -1
- package/dist/ports/policy.js +13 -2
- package/dist/ports/policy.js.map +1 -1
- package/dist/ports/testing.d.ts +1030 -2
- package/dist/ports/testing.d.ts.map +1 -1
- package/dist/ports/testing.js +1031 -1
- package/dist/ports/testing.js.map +1 -1
- package/dist/ports/unbound.d.ts +21 -0
- package/dist/ports/unbound.d.ts.map +1 -0
- package/dist/ports/unbound.js +57 -0
- package/dist/ports/unbound.js.map +1 -0
- package/dist/ports/unit-of-work.d.ts +1 -1
- package/dist/ports/unit-of-work.d.ts.map +1 -1
- package/dist/ports/unit-of-work.js +1 -1
- package/dist/ports/unit-of-work.js.map +1 -1
- package/dist/providers/index.d.ts +3 -2
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +3 -2
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/instrumentation.d.ts +46 -5
- package/dist/providers/instrumentation.d.ts.map +1 -1
- package/dist/providers/instrumentation.js +25 -6
- package/dist/providers/instrumentation.js.map +1 -1
- package/dist/providers/metadata.d.ts +39 -0
- package/dist/providers/metadata.d.ts.map +1 -0
- package/dist/providers/metadata.js +169 -0
- package/dist/providers/metadata.js.map +1 -0
- package/dist/providers/provider.d.ts +114 -9
- package/dist/providers/provider.d.ts.map +1 -1
- package/dist/providers/provider.js +3 -20
- package/dist/providers/provider.js.map +1 -1
- package/dist/schedules/index.d.ts +94 -13
- package/dist/schedules/index.d.ts.map +1 -1
- package/dist/schedules/index.js +66 -12
- package/dist/schedules/index.js.map +1 -1
- package/dist/server/audit-context.d.ts +29 -0
- package/dist/server/audit-context.d.ts.map +1 -0
- package/dist/server/audit-context.js +44 -0
- package/dist/server/audit-context.js.map +1 -0
- package/dist/server/context.d.ts +141 -0
- package/dist/server/context.d.ts.map +1 -0
- package/dist/server/context.js +39 -0
- package/dist/server/context.js.map +1 -0
- package/dist/server/contract-like.d.ts +1 -1
- package/dist/server/contract-like.d.ts.map +1 -1
- package/dist/server/contract-like.js +1 -1
- package/dist/server/contract-like.js.map +1 -1
- package/dist/server/health.d.ts +2 -2
- package/dist/server/health.d.ts.map +1 -1
- package/dist/server/hooks/auth.d.ts +89 -65
- package/dist/server/hooks/auth.d.ts.map +1 -1
- package/dist/server/hooks/auth.js +84 -55
- package/dist/server/hooks/auth.js.map +1 -1
- package/dist/server/hooks/cors.d.ts +1 -1
- package/dist/server/hooks/cors.d.ts.map +1 -1
- package/dist/server/hooks/errors.d.ts +2 -2
- package/dist/server/hooks/errors.d.ts.map +1 -1
- package/dist/server/hooks/errors.js +2 -2
- package/dist/server/hooks/errors.js.map +1 -1
- package/dist/server/hooks/idempotency.d.ts +78 -0
- package/dist/server/hooks/idempotency.d.ts.map +1 -0
- package/dist/server/hooks/idempotency.js +154 -0
- package/dist/server/hooks/idempotency.js.map +1 -0
- package/dist/server/hooks/index.d.ts +8 -7
- package/dist/server/hooks/index.d.ts.map +1 -1
- package/dist/server/hooks/index.js +6 -5
- package/dist/server/hooks/index.js.map +1 -1
- package/dist/server/hooks/logging.d.ts +2 -2
- package/dist/server/hooks/logging.d.ts.map +1 -1
- package/dist/server/hooks/logging.js +1 -1
- package/dist/server/hooks/logging.js.map +1 -1
- package/dist/server/hooks/rate-limit.d.ts +25 -7
- package/dist/server/hooks/rate-limit.d.ts.map +1 -1
- package/dist/server/hooks/rate-limit.js +47 -12
- package/dist/server/hooks/rate-limit.js.map +1 -1
- package/dist/server/hooks.d.ts +1 -1
- package/dist/server/hooks.d.ts.map +1 -1
- package/dist/server/hooks.js +1 -1
- package/dist/server/hooks.js.map +1 -1
- package/dist/server/http.d.ts +84 -6
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/index.d.ts +36 -12
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +24 -8
- package/dist/server/index.js.map +1 -1
- package/dist/server/instrumentation.d.ts +108 -0
- package/dist/server/instrumentation.d.ts.map +1 -0
- package/dist/server/instrumentation.js +297 -0
- package/dist/server/instrumentation.js.map +1 -0
- package/dist/server/openapi.d.ts +3 -3
- package/dist/server/openapi.d.ts.map +1 -1
- package/dist/server/openapi.js +1 -1
- package/dist/server/openapi.js.map +1 -1
- package/dist/server/providers/index.d.ts +3 -3
- package/dist/server/providers/index.d.ts.map +1 -1
- package/dist/server/providers/index.js +3 -3
- package/dist/server/providers/index.js.map +1 -1
- package/dist/server/providers/loadProviderConfig.d.ts +2 -2
- package/dist/server/providers/loadProviderConfig.d.ts.map +1 -1
- package/dist/server/providers/loadProviderConfig.js +2 -2
- package/dist/server/providers/loadProviderConfig.js.map +1 -1
- package/dist/server/request-context.d.ts +67 -0
- package/dist/server/request-context.d.ts.map +1 -0
- package/dist/server/request-context.js +79 -0
- package/dist/server/request-context.js.map +1 -0
- package/dist/server/server-context.d.ts +38 -0
- package/dist/server/server-context.d.ts.map +1 -0
- package/dist/server/server-context.js +38 -0
- package/dist/server/server-context.js.map +1 -0
- package/dist/server/server.d.ts +148 -35
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +482 -145
- package/dist/server/server.js.map +1 -1
- package/dist/server/types.d.ts +2 -2
- package/dist/server/types.d.ts.map +1 -1
- package/dist/server/types.js +2 -2
- package/dist/server/types.js.map +1 -1
- package/dist/server/use-case-route.d.ts +263 -0
- package/dist/server/use-case-route.d.ts.map +1 -0
- package/dist/server/use-case-route.js +77 -0
- package/dist/server/use-case-route.js.map +1 -0
- package/dist/server-only.d.ts +8 -0
- package/dist/server-only.d.ts.map +1 -0
- package/dist/server-only.js +8 -0
- package/dist/server-only.js.map +1 -0
- package/dist/tasks/index.d.ts +139 -0
- package/dist/tasks/index.d.ts.map +1 -0
- package/dist/tasks/index.js +98 -0
- package/dist/tasks/index.js.map +1 -0
- package/dist/testing/index.d.ts +611 -5
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +434 -4
- package/dist/testing/index.js.map +1 -1
- package/dist/tracing/index.d.ts +89 -0
- package/dist/tracing/index.d.ts.map +1 -0
- package/dist/tracing/index.js +101 -0
- package/dist/tracing/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 +34 -3
- package/src/application/index.ts +193 -10
- package/src/client/client.ts +148 -150
- package/src/client/error-messages.ts +35 -0
- package/src/client/index.ts +12 -4
- package/src/client/types.ts +44 -5
- package/src/client-only.ts +7 -0
- package/src/config/index.ts +6 -6
- package/src/contracts/catalog-errors.ts +115 -0
- package/src/contracts/contract-builder.ts +39 -76
- package/src/contracts/contract-group.ts +33 -68
- package/src/contracts/contract-like.ts +1 -1
- package/src/contracts/index.ts +24 -11
- package/src/contracts/openapi-meta.ts +55 -0
- package/src/contracts/path-template.ts +2 -2
- package/src/contracts/schema-shape.ts +75 -0
- package/src/contracts/success-status.ts +68 -0
- package/src/contracts/types.ts +32 -5
- package/src/contracts/utils.ts +5 -2
- package/src/domain/events.ts +6 -2
- package/src/domain/index.ts +3 -3
- package/src/errors/catalog.ts +9 -1
- package/src/errors/http.ts +11 -1
- package/src/errors/index.ts +4 -4
- package/src/errors/response.ts +4 -1
- package/src/events/index.ts +12 -26
- package/src/idempotency/index.ts +5 -3
- package/src/jobs/index.ts +340 -29
- package/src/notifications/index.ts +17 -27
- package/src/openapi/index.ts +73 -38
- package/src/openapi/schema-introspector.ts +68 -17
- package/src/outbox/index.ts +151 -6
- package/src/ports/audit.ts +120 -11
- package/src/ports/auth.ts +132 -0
- package/src/ports/events.ts +2 -2
- package/src/ports/index.ts +104 -35
- package/src/ports/policy.ts +50 -3
- package/src/ports/testing.ts +2220 -33
- package/src/ports/unbound.ts +64 -0
- package/src/ports/unit-of-work.ts +6 -2
- package/src/providers/index.ts +16 -3
- package/src/providers/instrumentation.ts +93 -8
- package/src/providers/metadata.ts +234 -0
- package/src/providers/provider.ts +168 -9
- package/src/schedules/index.ts +173 -23
- package/src/server/audit-context.ts +45 -0
- package/src/server/context.ts +224 -0
- package/src/server/contract-like.ts +1 -1
- package/src/server/health.ts +2 -2
- package/src/server/hooks/auth.ts +175 -158
- package/src/server/hooks/cors.ts +1 -1
- package/src/server/hooks/errors.ts +7 -4
- package/src/server/hooks/idempotency.ts +263 -0
- package/src/server/hooks/index.ts +15 -12
- package/src/server/hooks/logging.ts +3 -3
- package/src/server/hooks/rate-limit.ts +85 -17
- package/src/server/hooks.ts +1 -1
- package/src/server/http.ts +112 -6
- package/src/server/index.ts +63 -12
- package/src/server/instrumentation.ts +470 -0
- package/src/server/openapi.ts +4 -4
- package/src/server/providers/index.ts +6 -3
- package/src/server/providers/loadProviderConfig.ts +4 -4
- package/src/server/request-context.ts +116 -0
- package/src/server/server-context.ts +44 -0
- package/src/server/server.ts +1045 -229
- package/src/server/types.ts +2 -2
- package/src/server/use-case-route.ts +430 -0
- package/src/server-only.ts +7 -0
- package/src/tasks/index.ts +275 -0
- package/src/testing/index.ts +1153 -6
- package/src/tracing/index.ts +176 -0
- package/src/uploads/client.ts +861 -0
- package/src/uploads/index.ts +1071 -0
- package/dist/ports/mailer.d.ts +0 -6
- package/dist/ports/mailer.d.ts.map +0 -1
- package/dist/ports/mailer.js +0 -2
- package/dist/ports/mailer.js.map +0 -1
- package/dist/ports/schedules.d.ts +0 -9
- package/dist/ports/schedules.d.ts.map +0 -1
- package/dist/ports/schedules.js +0 -2
- package/dist/ports/schedules.js.map +0 -1
package/src/application/index.ts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
|
+
import {
|
|
3
|
+
type ProviderInstrumentationEventInput,
|
|
4
|
+
resolveProviderInstrumentationPort,
|
|
5
|
+
} from "../providers/instrumentation.js";
|
|
6
|
+
import {
|
|
7
|
+
createChildTraceContext,
|
|
8
|
+
type TraceContextInput,
|
|
9
|
+
} from "../tracing/index.js";
|
|
2
10
|
|
|
3
11
|
/**
|
|
4
12
|
* Any Standard Schema compatible validator.
|
|
@@ -315,6 +323,21 @@ function createUseCaseEventHelpers<Emits extends readonly DomainEventLike[]>(
|
|
|
315
323
|
*/
|
|
316
324
|
export type UseCaseKind = "command" | "query";
|
|
317
325
|
|
|
326
|
+
/**
|
|
327
|
+
* Symbol key for the trusted run path attached to finalized use cases.
|
|
328
|
+
*
|
|
329
|
+
* The server route binder calls this method instead of `run` when the route's
|
|
330
|
+
* input was already validated by the exact same schema object at the HTTP
|
|
331
|
+
* boundary. It behaves like `run` but skips the input parse; output
|
|
332
|
+
* validation, instrumentation, events, and `onRun` are unchanged.
|
|
333
|
+
*
|
|
334
|
+
* The key uses `Symbol.for(...)` so the binder and the application builder
|
|
335
|
+
* agree on the key even across separately bundled copies of the package.
|
|
336
|
+
*/
|
|
337
|
+
export const USE_CASE_TRUSTED_RUN: unique symbol = Symbol.for(
|
|
338
|
+
"beignet.useCase.trustedRun",
|
|
339
|
+
);
|
|
340
|
+
|
|
318
341
|
/**
|
|
319
342
|
* Finalized use case definition.
|
|
320
343
|
*
|
|
@@ -390,10 +413,24 @@ export interface UseCaseRunEvent<Ctx> {
|
|
|
390
413
|
*/
|
|
391
414
|
export interface CreateUseCaseOptions<Ctx> {
|
|
392
415
|
/**
|
|
393
|
-
* Optional
|
|
416
|
+
* Optional app-owned observer called on use case start, end, and error.
|
|
417
|
+
*
|
|
418
|
+
* Observers run in addition to the built-in instrumentation.
|
|
394
419
|
*/
|
|
395
420
|
onRun?: (event: UseCaseRunEvent<Ctx>) => void;
|
|
396
421
|
|
|
422
|
+
/**
|
|
423
|
+
* Built-in use-case instrumentation.
|
|
424
|
+
*
|
|
425
|
+
* By default every run records `usecase` lifecycle events (plus `error`
|
|
426
|
+
* events for failed runs) into the provider instrumentation port resolved
|
|
427
|
+
* from `ctx.ports` (`ports.instrumentation`, then `ports.devtools`). When no
|
|
428
|
+
* port is installed, runs stay silent. Pass `false` to opt out.
|
|
429
|
+
*
|
|
430
|
+
* @default true
|
|
431
|
+
*/
|
|
432
|
+
instrumentation?: boolean;
|
|
433
|
+
|
|
397
434
|
/**
|
|
398
435
|
* Enable or disable schema validation for use case boundaries.
|
|
399
436
|
*
|
|
@@ -423,6 +460,120 @@ function normalizeValidationOptions(
|
|
|
423
460
|
return { input: true, output: true };
|
|
424
461
|
}
|
|
425
462
|
|
|
463
|
+
type UseCaseRunInstrumentation = {
|
|
464
|
+
end(durationMs: number): void;
|
|
465
|
+
error(durationMs: number, error: unknown): void;
|
|
466
|
+
};
|
|
467
|
+
|
|
468
|
+
function getInstrumentationRequestId(ctx: unknown): string | undefined {
|
|
469
|
+
if (!ctx || typeof ctx !== "object") return undefined;
|
|
470
|
+
const requestId = (ctx as { requestId?: unknown }).requestId;
|
|
471
|
+
return typeof requestId === "string" ? requestId : undefined;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
function getInstrumentationTrace(ctx: unknown): TraceContextInput | undefined {
|
|
475
|
+
if (!ctx || typeof ctx !== "object") return undefined;
|
|
476
|
+
const context = ctx as TraceContextInput;
|
|
477
|
+
if (!context.traceId && !context.spanId && !context.traceparent) {
|
|
478
|
+
return undefined;
|
|
479
|
+
}
|
|
480
|
+
return {
|
|
481
|
+
traceId: context.traceId,
|
|
482
|
+
spanId: context.spanId,
|
|
483
|
+
parentSpanId: context.parentSpanId,
|
|
484
|
+
traceparent: context.traceparent,
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
function getRunErrorMessage(error: unknown): string {
|
|
489
|
+
if (error instanceof Error) return error.message;
|
|
490
|
+
if (typeof error === "string") return error;
|
|
491
|
+
return "Unknown error";
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* Start built-in instrumentation for one use-case run.
|
|
496
|
+
*
|
|
497
|
+
* The instrumentation port is resolved from `ctx.ports` per run so use cases
|
|
498
|
+
* stay decoupled from any specific sink. Runs without a resolved port stay
|
|
499
|
+
* silent.
|
|
500
|
+
*/
|
|
501
|
+
function startUseCaseRunInstrumentation(args: {
|
|
502
|
+
ctx: unknown;
|
|
503
|
+
name: string;
|
|
504
|
+
kind: UseCaseKind;
|
|
505
|
+
}): UseCaseRunInstrumentation | undefined {
|
|
506
|
+
const ports =
|
|
507
|
+
args.ctx && typeof args.ctx === "object"
|
|
508
|
+
? (args.ctx as { ports?: unknown }).ports
|
|
509
|
+
: undefined;
|
|
510
|
+
const port = resolveProviderInstrumentationPort(
|
|
511
|
+
ports as Parameters<typeof resolveProviderInstrumentationPort>[0],
|
|
512
|
+
);
|
|
513
|
+
if (!port) return undefined;
|
|
514
|
+
|
|
515
|
+
const useCasesEnabled = port.isWatcherEnabled?.("useCases") ?? true;
|
|
516
|
+
const errorsEnabled = port.isWatcherEnabled?.("errors") ?? true;
|
|
517
|
+
if (!useCasesEnabled && !errorsEnabled) return undefined;
|
|
518
|
+
|
|
519
|
+
const requestId = getInstrumentationRequestId(args.ctx);
|
|
520
|
+
const trace = createChildTraceContext(
|
|
521
|
+
getInstrumentationTrace(args.ctx) ?? {},
|
|
522
|
+
);
|
|
523
|
+
|
|
524
|
+
const record = (event: ProviderInstrumentationEventInput) => {
|
|
525
|
+
try {
|
|
526
|
+
port.record(event);
|
|
527
|
+
} catch {
|
|
528
|
+
// Instrumentation sinks must never affect use-case behavior.
|
|
529
|
+
}
|
|
530
|
+
};
|
|
531
|
+
|
|
532
|
+
const recordPhase = (
|
|
533
|
+
phase: "start" | "end" | "error",
|
|
534
|
+
durationMs?: number,
|
|
535
|
+
error?: unknown,
|
|
536
|
+
) => {
|
|
537
|
+
if (useCasesEnabled) {
|
|
538
|
+
record({
|
|
539
|
+
type: "usecase",
|
|
540
|
+
requestId,
|
|
541
|
+
traceId: trace.traceId,
|
|
542
|
+
spanId: trace.spanId,
|
|
543
|
+
parentSpanId: trace.parentSpanId,
|
|
544
|
+
traceparent: trace.traceparent,
|
|
545
|
+
name: args.name,
|
|
546
|
+
kind: args.kind,
|
|
547
|
+
phase,
|
|
548
|
+
durationMs,
|
|
549
|
+
error: phase === "error" ? getRunErrorMessage(error) : undefined,
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
if (phase === "error" && errorsEnabled) {
|
|
554
|
+
record({
|
|
555
|
+
type: "error",
|
|
556
|
+
requestId,
|
|
557
|
+
traceId: trace.traceId,
|
|
558
|
+
spanId: trace.spanId,
|
|
559
|
+
parentSpanId: trace.parentSpanId,
|
|
560
|
+
traceparent: trace.traceparent,
|
|
561
|
+
message: getRunErrorMessage(error),
|
|
562
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
563
|
+
useCaseName: args.name,
|
|
564
|
+
owner: "route",
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
|
|
569
|
+
recordPhase("start");
|
|
570
|
+
|
|
571
|
+
return {
|
|
572
|
+
end: (durationMs) => recordPhase("end", durationMs),
|
|
573
|
+
error: (durationMs, error) => recordPhase("error", durationMs, error),
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
|
|
426
577
|
/**
|
|
427
578
|
* Internal configuration for the use case builder
|
|
428
579
|
*/
|
|
@@ -464,6 +615,7 @@ class UseCaseBuilder<
|
|
|
464
615
|
input: true,
|
|
465
616
|
output: true,
|
|
466
617
|
},
|
|
618
|
+
private readonly instrumented: boolean = true,
|
|
467
619
|
) {}
|
|
468
620
|
|
|
469
621
|
/**
|
|
@@ -479,6 +631,7 @@ class UseCaseBuilder<
|
|
|
479
631
|
},
|
|
480
632
|
this.onRun,
|
|
481
633
|
this.validation,
|
|
634
|
+
this.instrumented,
|
|
482
635
|
);
|
|
483
636
|
}
|
|
484
637
|
|
|
@@ -495,6 +648,7 @@ class UseCaseBuilder<
|
|
|
495
648
|
},
|
|
496
649
|
this.onRun,
|
|
497
650
|
this.validation,
|
|
651
|
+
this.instrumented,
|
|
498
652
|
);
|
|
499
653
|
}
|
|
500
654
|
|
|
@@ -511,6 +665,7 @@ class UseCaseBuilder<
|
|
|
511
665
|
},
|
|
512
666
|
this.onRun,
|
|
513
667
|
this.validation,
|
|
668
|
+
this.instrumented,
|
|
514
669
|
);
|
|
515
670
|
}
|
|
516
671
|
|
|
@@ -544,6 +699,7 @@ class UseCaseBuilder<
|
|
|
544
699
|
const useCaseName = this.config.name;
|
|
545
700
|
const useCaseKind = this.config.kind;
|
|
546
701
|
const onRun = this.onRun;
|
|
702
|
+
const instrumented = this.instrumented;
|
|
547
703
|
const inputSchema = this.config.input as Extract<
|
|
548
704
|
InputSchema,
|
|
549
705
|
StandardSchemaV1
|
|
@@ -558,7 +714,7 @@ class UseCaseBuilder<
|
|
|
558
714
|
this.config.emits,
|
|
559
715
|
);
|
|
560
716
|
|
|
561
|
-
const
|
|
717
|
+
const execute = async (
|
|
562
718
|
args: InputSchema extends StandardSchemaV1
|
|
563
719
|
? OutputSchema extends StandardSchemaV1
|
|
564
720
|
? {
|
|
@@ -567,8 +723,16 @@ class UseCaseBuilder<
|
|
|
567
723
|
}
|
|
568
724
|
: never
|
|
569
725
|
: never,
|
|
726
|
+
parseInput: boolean,
|
|
570
727
|
) => {
|
|
571
728
|
const startedAt = Date.now();
|
|
729
|
+
const instrumentation = instrumented
|
|
730
|
+
? startUseCaseRunInstrumentation({
|
|
731
|
+
ctx: args.ctx,
|
|
732
|
+
name: useCaseName,
|
|
733
|
+
kind: useCaseKind,
|
|
734
|
+
})
|
|
735
|
+
: undefined;
|
|
572
736
|
onRun?.({
|
|
573
737
|
name: useCaseName,
|
|
574
738
|
kind: useCaseKind,
|
|
@@ -577,9 +741,10 @@ class UseCaseBuilder<
|
|
|
577
741
|
});
|
|
578
742
|
|
|
579
743
|
try {
|
|
580
|
-
const parsedInput =
|
|
581
|
-
|
|
582
|
-
|
|
744
|
+
const parsedInput =
|
|
745
|
+
parseInput && validation.input
|
|
746
|
+
? await parseSchema(inputSchema, args.input, useCaseName, "input")
|
|
747
|
+
: (args.input as SchemaOutput<InputSchema>);
|
|
583
748
|
|
|
584
749
|
const rawResult = await fn({
|
|
585
750
|
ctx: args.ctx,
|
|
@@ -591,21 +756,25 @@ class UseCaseBuilder<
|
|
|
591
756
|
? await parseSchema(outputSchema, rawResult, useCaseName, "output")
|
|
592
757
|
: (rawResult as SchemaOutput<OutputSchema>);
|
|
593
758
|
|
|
759
|
+
const durationMs = Date.now() - startedAt;
|
|
760
|
+
instrumentation?.end(durationMs);
|
|
594
761
|
onRun?.({
|
|
595
762
|
name: useCaseName,
|
|
596
763
|
kind: useCaseKind,
|
|
597
764
|
phase: "end",
|
|
598
|
-
durationMs
|
|
765
|
+
durationMs,
|
|
599
766
|
ctx: args.ctx,
|
|
600
767
|
});
|
|
601
768
|
|
|
602
769
|
return result;
|
|
603
770
|
} catch (err) {
|
|
771
|
+
const durationMs = Date.now() - startedAt;
|
|
772
|
+
instrumentation?.error(durationMs, err);
|
|
604
773
|
onRun?.({
|
|
605
774
|
name: useCaseName,
|
|
606
775
|
kind: useCaseKind,
|
|
607
776
|
phase: "error",
|
|
608
|
-
durationMs
|
|
777
|
+
durationMs,
|
|
609
778
|
error: err,
|
|
610
779
|
ctx: args.ctx,
|
|
611
780
|
});
|
|
@@ -613,18 +782,29 @@ class UseCaseBuilder<
|
|
|
613
782
|
}
|
|
614
783
|
};
|
|
615
784
|
|
|
785
|
+
type RunArgs = Parameters<typeof execute>[0];
|
|
786
|
+
|
|
616
787
|
// Type assertion required to satisfy the conditional return type.
|
|
617
788
|
// The runtime checks above ensure input/output schemas are set.
|
|
618
789
|
// The conditional types ensure type safety at compile time - run() returns
|
|
619
790
|
// UseCaseDef only when both InputSchema and OutputSchema are StandardSchemaV1.
|
|
620
|
-
|
|
791
|
+
const def = {
|
|
621
792
|
name: this.config.name,
|
|
622
793
|
kind: this.config.kind,
|
|
623
794
|
inputSchema: this.config.input,
|
|
624
795
|
outputSchema: this.config.output,
|
|
625
796
|
emits: this.config.emits,
|
|
626
|
-
run:
|
|
627
|
-
}
|
|
797
|
+
run: (args: RunArgs) => execute(args, true),
|
|
798
|
+
};
|
|
799
|
+
|
|
800
|
+
// The trusted run path skips only the input parse. It is non-enumerable so
|
|
801
|
+
// serialization and object spreads keep treating use cases as plain data.
|
|
802
|
+
Object.defineProperty(def, USE_CASE_TRUSTED_RUN, {
|
|
803
|
+
value: (args: RunArgs) => execute(args, false),
|
|
804
|
+
enumerable: false,
|
|
805
|
+
});
|
|
806
|
+
|
|
807
|
+
return def as unknown as InputSchema extends StandardSchemaV1
|
|
628
808
|
? OutputSchema extends StandardSchemaV1
|
|
629
809
|
? UseCaseDef<Ctx, Name, Kind, InputSchema, OutputSchema, Emits>
|
|
630
810
|
: never
|
|
@@ -769,6 +949,7 @@ export function createUseCase<Ctx>(
|
|
|
769
949
|
): UseCaseBuilderRoot<Ctx> {
|
|
770
950
|
const onRun = options?.onRun;
|
|
771
951
|
const validation = normalizeValidationOptions(options?.validate);
|
|
952
|
+
const instrumented = options?.instrumentation !== false;
|
|
772
953
|
return {
|
|
773
954
|
command<Name extends string>(name: Name) {
|
|
774
955
|
return new UseCaseBuilder<
|
|
@@ -786,6 +967,7 @@ export function createUseCase<Ctx>(
|
|
|
786
967
|
},
|
|
787
968
|
onRun,
|
|
788
969
|
validation,
|
|
970
|
+
instrumented,
|
|
789
971
|
);
|
|
790
972
|
},
|
|
791
973
|
query<Name extends string>(name: Name) {
|
|
@@ -804,6 +986,7 @@ export function createUseCase<Ctx>(
|
|
|
804
986
|
},
|
|
805
987
|
onRun,
|
|
806
988
|
validation,
|
|
989
|
+
instrumented,
|
|
807
990
|
);
|
|
808
991
|
},
|
|
809
992
|
};
|