@beignet/core 0.0.3 → 0.0.5
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 +159 -0
- package/README.md +792 -50
- 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 +12 -14
- package/dist/jobs/index.d.ts.map +1 -1
- package/dist/jobs/index.js +13 -13
- 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 +15 -6
- package/dist/outbox/index.d.ts.map +1 -1
- package/dist/outbox/index.js +60 -16
- 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 +45 -4
- 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 +49 -10
- package/dist/server/hooks/auth.d.ts.map +1 -1
- package/dist/server/hooks/auth.js +77 -37
- 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 +61 -35
- package/dist/server/http.d.ts.map +1 -1
- package/dist/server/http.js +1 -20
- package/dist/server/http.js.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 +105 -33
- package/dist/server/server.d.ts.map +1 -1
- package/dist/server/server.js +434 -118
- 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 +607 -5
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +426 -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 +1 -1
- package/dist/uploads/client.d.ts.map +1 -1
- package/dist/uploads/index.d.ts +2 -2
- package/dist/uploads/index.d.ts.map +1 -1
- package/dist/uploads/index.js +1 -1
- package/dist/uploads/index.js.map +1 -1
- package/package.json +24 -2
- 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 +14 -24
- 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 +84 -19
- 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 +86 -7
- 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 +141 -51
- 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 +14 -7
- 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 +78 -51
- package/src/server/index.ts +62 -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 +886 -238
- 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 +1142 -6
- package/src/tracing/index.ts +176 -0
- package/src/uploads/client.ts +1 -1
- package/src/uploads/index.ts +7 -3
- 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
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unbound port placeholders for deferred `definePorts(...)` keys.
|
|
3
|
+
*
|
|
4
|
+
* Ports declared as deferred boot as marked placeholders. Any method call on
|
|
5
|
+
* a placeholder throws a descriptive error, and `createServer(...)` scans
|
|
6
|
+
* final ports after provider startup so a missing provider fails boot instead
|
|
7
|
+
* of failing on first use.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const UNBOUND_PORT_MARKER = Symbol.for("beignet.unboundPort");
|
|
11
|
+
|
|
12
|
+
function unboundPortMessage(portName: string): string {
|
|
13
|
+
return (
|
|
14
|
+
`Port "${portName}" is not bound. "${portName}" is declared as deferred ` +
|
|
15
|
+
"in definePorts(...). Register a provider that contributes it " +
|
|
16
|
+
"(server/providers.ts) or bind it in infra/app-ports.ts."
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Create a marked placeholder for a deferred port.
|
|
22
|
+
*
|
|
23
|
+
* Property access returns a function that throws, so calling any method on an
|
|
24
|
+
* unbound port produces a descriptive error naming the port.
|
|
25
|
+
*/
|
|
26
|
+
export function createUnboundPort(portName: string): unknown {
|
|
27
|
+
return new Proxy(
|
|
28
|
+
{},
|
|
29
|
+
{
|
|
30
|
+
get(_target, property) {
|
|
31
|
+
if (property === UNBOUND_PORT_MARKER) return true;
|
|
32
|
+
if (property === Symbol.toStringTag) {
|
|
33
|
+
return `UnboundPort(${portName})`;
|
|
34
|
+
}
|
|
35
|
+
// Keep unbound ports safe to `await` and JSON-serialize.
|
|
36
|
+
if (property === "then" || property === "toJSON") return undefined;
|
|
37
|
+
if (typeof property === "symbol") return undefined;
|
|
38
|
+
if (property === "toString") {
|
|
39
|
+
return () => `[unbound port "${portName}"]`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return () => {
|
|
43
|
+
throw new Error(unboundPortMessage(portName));
|
|
44
|
+
};
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Check whether a value is an unbound port placeholder created for a deferred
|
|
52
|
+
* `definePorts(...)` key.
|
|
53
|
+
*/
|
|
54
|
+
export function isUnboundPort(value: unknown): boolean {
|
|
55
|
+
if (value === null || typeof value !== "object") return false;
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
return (
|
|
59
|
+
(value as Record<PropertyKey, unknown>)[UNBOUND_PORT_MARKER] === true
|
|
60
|
+
);
|
|
61
|
+
} catch {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import { parseEventPayload } from "../events";
|
|
2
|
-
import type {
|
|
1
|
+
import { parseEventPayload } from "../events/index.js";
|
|
2
|
+
import type {
|
|
3
|
+
DomainEventDef,
|
|
4
|
+
EventBusPort,
|
|
5
|
+
InferEventPayload,
|
|
6
|
+
} from "./events.js";
|
|
3
7
|
|
|
4
8
|
type MaybePromise<T> = T | Promise<T>;
|
|
5
9
|
|
package/src/providers/index.ts
CHANGED
|
@@ -13,6 +13,7 @@ export {
|
|
|
13
13
|
isProviderInstrumentation,
|
|
14
14
|
isProviderInstrumentationPort,
|
|
15
15
|
type JobProviderInstrumentationEvent,
|
|
16
|
+
type OutboxProviderInstrumentationEvent,
|
|
16
17
|
type ProviderCustomInstrumentationEventInput,
|
|
17
18
|
type ProviderInstrumentation,
|
|
18
19
|
type ProviderInstrumentationEvent,
|
|
@@ -26,15 +27,27 @@ export {
|
|
|
26
27
|
resolveProviderInstrumentationPort,
|
|
27
28
|
type ScheduleProviderInstrumentationEvent,
|
|
28
29
|
type UseCaseProviderInstrumentationEvent,
|
|
29
|
-
} from "./instrumentation";
|
|
30
|
+
} from "./instrumentation.js";
|
|
30
31
|
export {
|
|
32
|
+
type ProviderPackageMetadata,
|
|
33
|
+
type ProviderPackageMetadataIssue,
|
|
34
|
+
type ProviderPackageMetadataParseResult,
|
|
35
|
+
type ProviderPackagePortMetadata,
|
|
36
|
+
type ProviderPackageRegistrationMetadata,
|
|
37
|
+
type ProviderPackageRegistrationSeverity,
|
|
38
|
+
parseProviderPackageMetadata,
|
|
39
|
+
} from "./metadata.js";
|
|
40
|
+
export {
|
|
41
|
+
type AnyServiceProvider,
|
|
31
42
|
createProvider,
|
|
32
43
|
type InferOutput,
|
|
44
|
+
type InferProviderPorts,
|
|
33
45
|
type MaybePromise,
|
|
34
46
|
type ProvidedPortsOf,
|
|
35
|
-
type ProvidedPortsOfList,
|
|
36
47
|
type ProviderConfigDef,
|
|
37
48
|
type ProviderLifecycleContext,
|
|
49
|
+
type ProviderServiceContextFactory,
|
|
38
50
|
type ProviderSetupResult,
|
|
39
51
|
type ServiceProvider,
|
|
40
|
-
|
|
52
|
+
type ServiceProviderMetadata,
|
|
53
|
+
} from "./provider.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Redactor, redactValue } from "../ports/redaction";
|
|
1
|
+
import { type Redactor, redactValue } from "../ports/redaction.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Logical provider watcher name used to toggle groups of instrumentation
|
|
@@ -68,6 +68,10 @@ export interface RequestProviderInstrumentationEvent
|
|
|
68
68
|
* Matched contract name, when known.
|
|
69
69
|
*/
|
|
70
70
|
contractName?: string;
|
|
71
|
+
/**
|
|
72
|
+
* Which layer produced the response.
|
|
73
|
+
*/
|
|
74
|
+
responseOwner?: "route" | "framework" | "transport" | "unknown";
|
|
71
75
|
/**
|
|
72
76
|
* Response status code.
|
|
73
77
|
*/
|
|
@@ -104,6 +108,19 @@ export interface ErrorProviderInstrumentationEvent
|
|
|
104
108
|
* Use case associated with the error.
|
|
105
109
|
*/
|
|
106
110
|
useCaseName?: string;
|
|
111
|
+
/**
|
|
112
|
+
* Which layer owns the error.
|
|
113
|
+
*/
|
|
114
|
+
owner?:
|
|
115
|
+
| "route"
|
|
116
|
+
| "framework"
|
|
117
|
+
| "provider"
|
|
118
|
+
| "job"
|
|
119
|
+
| "schedule"
|
|
120
|
+
| "outbox"
|
|
121
|
+
| "client"
|
|
122
|
+
| "devtools"
|
|
123
|
+
| "unknown";
|
|
107
124
|
}
|
|
108
125
|
|
|
109
126
|
/**
|
|
@@ -169,7 +186,31 @@ export interface JobProviderInstrumentationEvent
|
|
|
169
186
|
}
|
|
170
187
|
|
|
171
188
|
/**
|
|
172
|
-
*
|
|
189
|
+
* Durable outbox delivery instrumentation.
|
|
190
|
+
*/
|
|
191
|
+
export interface OutboxProviderInstrumentationEvent
|
|
192
|
+
extends BaseProviderInstrumentationEvent {
|
|
193
|
+
type: "outbox";
|
|
194
|
+
/**
|
|
195
|
+
* Durable outbox message ID.
|
|
196
|
+
*/
|
|
197
|
+
messageId: string;
|
|
198
|
+
/**
|
|
199
|
+
* Message kind.
|
|
200
|
+
*/
|
|
201
|
+
messageKind: "event" | "job";
|
|
202
|
+
/**
|
|
203
|
+
* Event or job name stored in the outbox message.
|
|
204
|
+
*/
|
|
205
|
+
messageName: string;
|
|
206
|
+
/**
|
|
207
|
+
* Delivery lifecycle status.
|
|
208
|
+
*/
|
|
209
|
+
status: "delivered" | "retryScheduled" | "deadLettered";
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Schedule instrumentation.
|
|
173
214
|
*/
|
|
174
215
|
export interface ScheduleProviderInstrumentationEvent
|
|
175
216
|
extends BaseProviderInstrumentationEvent {
|
|
@@ -237,6 +278,7 @@ export type ProviderInstrumentationEvent =
|
|
|
237
278
|
| UseCaseProviderInstrumentationEvent
|
|
238
279
|
| EventBusProviderInstrumentationEvent
|
|
239
280
|
| JobProviderInstrumentationEvent
|
|
281
|
+
| OutboxProviderInstrumentationEvent
|
|
240
282
|
| ScheduleProviderInstrumentationEvent
|
|
241
283
|
| ProviderLifecycleInstrumentationEvent
|
|
242
284
|
| CustomProviderInstrumentationEvent;
|
|
@@ -316,6 +358,10 @@ export interface ProviderInstrumentation {
|
|
|
316
358
|
|
|
317
359
|
/**
|
|
318
360
|
* Values accepted by `createProviderInstrumentation(...)`.
|
|
361
|
+
*
|
|
362
|
+
* Plain ports objects are accepted so callers can pass `ctx.ports` (or a
|
|
363
|
+
* provider's `ports` argument) directly; the resolver reads
|
|
364
|
+
* `ports.instrumentation`, then `ports.devtools`.
|
|
319
365
|
*/
|
|
320
366
|
export type ProviderInstrumentationTarget =
|
|
321
367
|
| ProviderInstrumentationPort
|
|
@@ -324,6 +370,7 @@ export type ProviderInstrumentationTarget =
|
|
|
324
370
|
devtools?: ProviderInstrumentationPort | ProviderInstrumentation;
|
|
325
371
|
instrumentation?: ProviderInstrumentationPort | ProviderInstrumentation;
|
|
326
372
|
}
|
|
373
|
+
| Record<string, unknown>
|
|
327
374
|
| undefined;
|
|
328
375
|
|
|
329
376
|
function isObject(value: unknown): value is Record<string, unknown> {
|
|
@@ -332,12 +379,19 @@ function isObject(value: unknown): value is Record<string, unknown> {
|
|
|
332
379
|
|
|
333
380
|
/**
|
|
334
381
|
* Return whether a value is a provider instrumentation helper.
|
|
382
|
+
*
|
|
383
|
+
* Checks key presence with `in` before reading so probing proxy-backed
|
|
384
|
+
* objects, such as test-context port guards that throw on unknown reads,
|
|
385
|
+
* stays safe.
|
|
335
386
|
*/
|
|
336
387
|
export function isProviderInstrumentation(
|
|
337
388
|
value: unknown,
|
|
338
389
|
): value is ProviderInstrumentation {
|
|
339
390
|
return (
|
|
340
391
|
isObject(value) &&
|
|
392
|
+
"record" in value &&
|
|
393
|
+
"custom" in value &&
|
|
394
|
+
"isEnabled" in value &&
|
|
341
395
|
typeof value.record === "function" &&
|
|
342
396
|
typeof value.custom === "function" &&
|
|
343
397
|
typeof value.isEnabled === "function"
|
|
@@ -346,11 +400,16 @@ export function isProviderInstrumentation(
|
|
|
346
400
|
|
|
347
401
|
/**
|
|
348
402
|
* Return whether a value is a provider instrumentation port.
|
|
403
|
+
*
|
|
404
|
+
* Checks key presence with `in` before reading so probing proxy-backed
|
|
405
|
+
* objects stays safe.
|
|
349
406
|
*/
|
|
350
407
|
export function isProviderInstrumentationPort(
|
|
351
408
|
value: unknown,
|
|
352
409
|
): value is ProviderInstrumentationPort {
|
|
353
|
-
return
|
|
410
|
+
return (
|
|
411
|
+
isObject(value) && "record" in value && typeof value.record === "function"
|
|
412
|
+
);
|
|
354
413
|
}
|
|
355
414
|
|
|
356
415
|
function resolveProviderInstrumentationValue(
|
|
@@ -376,8 +435,12 @@ export function resolveProviderInstrumentationPort(
|
|
|
376
435
|
if (!isObject(target)) return undefined;
|
|
377
436
|
|
|
378
437
|
return (
|
|
379
|
-
resolveProviderInstrumentationValue(
|
|
380
|
-
|
|
438
|
+
resolveProviderInstrumentationValue(
|
|
439
|
+
"instrumentation" in target ? target.instrumentation : undefined,
|
|
440
|
+
) ??
|
|
441
|
+
resolveProviderInstrumentationValue(
|
|
442
|
+
"devtools" in target ? target.devtools : undefined,
|
|
443
|
+
)
|
|
381
444
|
);
|
|
382
445
|
}
|
|
383
446
|
|
|
@@ -393,6 +456,18 @@ function withProviderDetails(providerName: string, details: unknown): unknown {
|
|
|
393
456
|
return { providerName, value: details };
|
|
394
457
|
}
|
|
395
458
|
|
|
459
|
+
function withInstrumentationProviderDetails(
|
|
460
|
+
event: ProviderInstrumentationEventInput,
|
|
461
|
+
providerName: string,
|
|
462
|
+
): ProviderInstrumentationEventInput {
|
|
463
|
+
if (event.type === "provider") return event;
|
|
464
|
+
|
|
465
|
+
return {
|
|
466
|
+
...event,
|
|
467
|
+
details: withProviderDetails(providerName, event.details),
|
|
468
|
+
} as ProviderInstrumentationEventInput;
|
|
469
|
+
}
|
|
470
|
+
|
|
396
471
|
/**
|
|
397
472
|
* Create a provider instrumentation helper that handles watcher checks,
|
|
398
473
|
* default watcher assignment, redaction, and sink failures.
|
|
@@ -423,12 +498,16 @@ export function createProviderInstrumentation(
|
|
|
423
498
|
options.watcher && event.watcher === undefined
|
|
424
499
|
? { ...event, watcher: options.watcher }
|
|
425
500
|
: event;
|
|
501
|
+
const eventWithProvider = withInstrumentationProviderDetails(
|
|
502
|
+
eventWithWatcher,
|
|
503
|
+
options.providerName,
|
|
504
|
+
);
|
|
426
505
|
|
|
427
506
|
let redacted: ProviderInstrumentationEventInput;
|
|
428
507
|
try {
|
|
429
508
|
redacted = options.redact
|
|
430
|
-
? options.redact(redactValue(
|
|
431
|
-
: redactValue(
|
|
509
|
+
? options.redact(redactValue(eventWithProvider))
|
|
510
|
+
: redactValue(eventWithProvider);
|
|
432
511
|
} catch {
|
|
433
512
|
return undefined;
|
|
434
513
|
}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static provider package metadata declared in package.json under
|
|
3
|
+
* `beignet.provider`.
|
|
4
|
+
*
|
|
5
|
+
* This metadata is for docs and tooling. It must stay side-effect-free and
|
|
6
|
+
* does not change provider setup, ordering, or runtime port merging behavior.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export type ProviderPackagePortMetadata = {
|
|
10
|
+
name: string;
|
|
11
|
+
type: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type ProviderPackageRegistrationSeverity = "warning" | "hint";
|
|
15
|
+
|
|
16
|
+
export type ProviderPackageRegistrationMetadata = {
|
|
17
|
+
required?: boolean;
|
|
18
|
+
severity?: ProviderPackageRegistrationSeverity;
|
|
19
|
+
tokens?: readonly string[];
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export type ProviderPackageMetadata = {
|
|
23
|
+
displayName?: string;
|
|
24
|
+
ports?: readonly string[];
|
|
25
|
+
appPorts?: readonly ProviderPackagePortMetadata[];
|
|
26
|
+
env?: readonly string[];
|
|
27
|
+
requiredEnv?: readonly string[];
|
|
28
|
+
registration?: ProviderPackageRegistrationMetadata;
|
|
29
|
+
watchers?: readonly string[];
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export type ProviderPackageMetadataIssue = {
|
|
33
|
+
path: string;
|
|
34
|
+
message: string;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export type ProviderPackageMetadataParseResult =
|
|
38
|
+
| { success: true; metadata: ProviderPackageMetadata }
|
|
39
|
+
| { success: false; issues: readonly ProviderPackageMetadataIssue[] };
|
|
40
|
+
|
|
41
|
+
export function parseProviderPackageMetadata(
|
|
42
|
+
input: unknown,
|
|
43
|
+
): ProviderPackageMetadataParseResult {
|
|
44
|
+
if (!isRecord(input)) {
|
|
45
|
+
return {
|
|
46
|
+
success: false,
|
|
47
|
+
issues: [
|
|
48
|
+
{
|
|
49
|
+
path: "beignet.provider",
|
|
50
|
+
message: "must be an object",
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const issues: ProviderPackageMetadataIssue[] = [];
|
|
57
|
+
const metadata: ProviderPackageMetadata = {};
|
|
58
|
+
|
|
59
|
+
if (input.displayName !== undefined) {
|
|
60
|
+
if (typeof input.displayName !== "string") {
|
|
61
|
+
issues.push({
|
|
62
|
+
path: "beignet.provider.displayName",
|
|
63
|
+
message: "must be a string",
|
|
64
|
+
});
|
|
65
|
+
} else {
|
|
66
|
+
metadata.displayName = input.displayName;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const ports = parseStringArray(input.ports, "beignet.provider.ports", issues);
|
|
71
|
+
if (ports !== undefined) metadata.ports = ports;
|
|
72
|
+
|
|
73
|
+
const env = parseStringArray(input.env, "beignet.provider.env", issues);
|
|
74
|
+
if (env !== undefined) metadata.env = env;
|
|
75
|
+
|
|
76
|
+
const requiredEnv = parseStringArray(
|
|
77
|
+
input.requiredEnv,
|
|
78
|
+
"beignet.provider.requiredEnv",
|
|
79
|
+
issues,
|
|
80
|
+
);
|
|
81
|
+
if (requiredEnv !== undefined) {
|
|
82
|
+
metadata.requiredEnv = requiredEnv;
|
|
83
|
+
const envSet = new Set(env ?? []);
|
|
84
|
+
for (const envVar of requiredEnv) {
|
|
85
|
+
if (!envSet.has(envVar)) {
|
|
86
|
+
issues.push({
|
|
87
|
+
path: "beignet.provider.requiredEnv",
|
|
88
|
+
message: `${envVar} must also be listed in beignet.provider.env`,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const watchers = parseStringArray(
|
|
95
|
+
input.watchers,
|
|
96
|
+
"beignet.provider.watchers",
|
|
97
|
+
issues,
|
|
98
|
+
);
|
|
99
|
+
if (watchers !== undefined) metadata.watchers = watchers;
|
|
100
|
+
|
|
101
|
+
const appPorts = parseAppPorts(input.appPorts, issues);
|
|
102
|
+
if (appPorts !== undefined) metadata.appPorts = appPorts;
|
|
103
|
+
|
|
104
|
+
const registration = parseRegistration(input.registration, issues);
|
|
105
|
+
if (registration !== undefined) metadata.registration = registration;
|
|
106
|
+
|
|
107
|
+
if (issues.length > 0) {
|
|
108
|
+
return { success: false, issues };
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return { success: true, metadata };
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function parseStringArray(
|
|
115
|
+
value: unknown,
|
|
116
|
+
path: string,
|
|
117
|
+
issues: ProviderPackageMetadataIssue[],
|
|
118
|
+
): string[] | undefined {
|
|
119
|
+
if (value === undefined) return undefined;
|
|
120
|
+
if (!Array.isArray(value)) {
|
|
121
|
+
issues.push({ path, message: "must be an array of strings" });
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const parsed: string[] = [];
|
|
126
|
+
for (const [index, entry] of value.entries()) {
|
|
127
|
+
if (typeof entry !== "string") {
|
|
128
|
+
issues.push({
|
|
129
|
+
path: `${path}[${index}]`,
|
|
130
|
+
message: "must be a string",
|
|
131
|
+
});
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
parsed.push(entry);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return parsed;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function parseAppPorts(
|
|
141
|
+
value: unknown,
|
|
142
|
+
issues: ProviderPackageMetadataIssue[],
|
|
143
|
+
): ProviderPackagePortMetadata[] | undefined {
|
|
144
|
+
if (value === undefined) return undefined;
|
|
145
|
+
const path = "beignet.provider.appPorts";
|
|
146
|
+
if (!Array.isArray(value)) {
|
|
147
|
+
issues.push({ path, message: "must be an array of port metadata objects" });
|
|
148
|
+
return undefined;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const parsed: ProviderPackagePortMetadata[] = [];
|
|
152
|
+
for (const [index, entry] of value.entries()) {
|
|
153
|
+
const entryPath = `${path}[${index}]`;
|
|
154
|
+
if (!isRecord(entry)) {
|
|
155
|
+
issues.push({ path: entryPath, message: "must be an object" });
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
if (typeof entry.name !== "string") {
|
|
159
|
+
issues.push({ path: `${entryPath}.name`, message: "must be a string" });
|
|
160
|
+
}
|
|
161
|
+
if (typeof entry.type !== "string") {
|
|
162
|
+
issues.push({ path: `${entryPath}.type`, message: "must be a string" });
|
|
163
|
+
}
|
|
164
|
+
if (typeof entry.name === "string" && typeof entry.type === "string") {
|
|
165
|
+
parsed.push({ name: entry.name, type: entry.type });
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return parsed;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function parseRegistration(
|
|
173
|
+
value: unknown,
|
|
174
|
+
issues: ProviderPackageMetadataIssue[],
|
|
175
|
+
): ProviderPackageRegistrationMetadata | undefined {
|
|
176
|
+
if (value === undefined) return undefined;
|
|
177
|
+
const path = "beignet.provider.registration";
|
|
178
|
+
if (!isRecord(value)) {
|
|
179
|
+
issues.push({ path, message: "must be an object" });
|
|
180
|
+
return undefined;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const registration: ProviderPackageRegistrationMetadata = {};
|
|
184
|
+
if (value.required !== undefined) {
|
|
185
|
+
if (typeof value.required !== "boolean") {
|
|
186
|
+
issues.push({ path: `${path}.required`, message: "must be a boolean" });
|
|
187
|
+
} else {
|
|
188
|
+
registration.required = value.required;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (value.severity !== undefined) {
|
|
193
|
+
if (value.severity !== "warning" && value.severity !== "hint") {
|
|
194
|
+
issues.push({
|
|
195
|
+
path: `${path}.severity`,
|
|
196
|
+
message: 'must be "warning" or "hint"',
|
|
197
|
+
});
|
|
198
|
+
} else {
|
|
199
|
+
registration.severity = value.severity;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (registration.required === true && registration.severity === "hint") {
|
|
204
|
+
issues.push({
|
|
205
|
+
path: `${path}.severity`,
|
|
206
|
+
message: 'must not be "hint" when registration is required',
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const tokens = parseStringArray(value.tokens, `${path}.tokens`, issues);
|
|
211
|
+
if (tokens !== undefined) registration.tokens = tokens;
|
|
212
|
+
|
|
213
|
+
if ((tokens?.length ?? 0) === 0) {
|
|
214
|
+
if (registration.required === true) {
|
|
215
|
+
issues.push({
|
|
216
|
+
path: `${path}.tokens`,
|
|
217
|
+
message:
|
|
218
|
+
"must include at least one token when registration is required",
|
|
219
|
+
});
|
|
220
|
+
} else if (registration.severity !== undefined) {
|
|
221
|
+
issues.push({
|
|
222
|
+
path: `${path}.tokens`,
|
|
223
|
+
message:
|
|
224
|
+
"must include at least one token when registration severity is set",
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return registration;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
233
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
234
|
+
}
|