@classytic/arc 2.41.0 → 2.43.0
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/dist/{EventTransport-CbUKDzZZ.d.mts → EventTransport-CiicKz2Z.d.mts} +1 -1
- package/dist/{EventTransport-n7qO5Cz3.mjs → EventTransport-tzA7CAB4.mjs} +22 -17
- package/dist/{HookSystem-CxvZBo77.mjs → HookSystem-B6UaKRbF.mjs} +2 -2
- package/dist/{QueryCache-DFA-QrU9.d.mts → QueryCache--5uAuYPW.d.mts} +7 -3
- package/dist/{ResourceRegistry-Cu7uTJp9.mjs → ResourceRegistry-CuCARu2B.mjs} +44 -13
- package/dist/actionPermissions-BotX1YOa.mjs +776 -0
- package/dist/audit/index.d.mts +43 -5
- package/dist/audit/index.mjs +48 -26
- package/dist/auth/audit.mjs +1 -1
- package/dist/auth/index.d.mts +43 -13
- package/dist/auth/index.mjs +130 -155
- package/dist/auth/redis-session.mjs +1 -1
- package/dist/{authorizationDecision-2YY_Kaj1.mjs → authorizationDecision-DQYrkl5f.mjs} +7 -102
- package/dist/{base-CxrV1LmG.d.mts → base-CZyixEQR.d.mts} +27 -5
- package/dist/boundedMap-BULzfXYU.mjs +57 -0
- package/dist/{buildHandler-CUhjGHGZ.mjs → buildHandler-CRQ8EcX5.mjs} +4 -4
- package/dist/cache/index.d.mts +22 -34
- package/dist/cache/index.mjs +4 -4
- package/dist/{caching-DsWDjIxx.mjs → caching-Cc2M1DwO.mjs} +3 -3
- package/dist/claimed-B10RTfkM.mjs +8 -0
- package/dist/cleanup/index.d.mts +6 -10
- package/dist/cleanup/index.mjs +27 -73
- package/dist/cli/commands/describe.d.mts +4 -2
- package/dist/cli/commands/describe.mjs +7 -4
- package/dist/cli/commands/docs.mjs +3 -3
- package/dist/cli/commands/doctor.mjs +1 -1
- package/dist/cli/commands/generate.mjs +2 -2
- package/dist/cli/commands/init.mjs +2 -2
- package/dist/cli/commands/introspect.mjs +2 -2
- package/dist/cli/index.mjs +3 -3
- package/dist/{constants-BxLgNFF7.mjs → constants-Cu7Mx7_U.mjs} +4 -2
- package/dist/context/index.d.mts +2 -5
- package/dist/context/index.mjs +18 -38
- package/dist/core/index.d.mts +3 -3
- package/dist/core/index.mjs +8 -8
- package/dist/{core-iNGqYerO.mjs → core-Cb0LjccA.mjs} +5 -4
- package/dist/{createActionRouter-BBlbPs3k.mjs → createActionRouter-xjqonMRO.mjs} +87 -39
- package/dist/{createAggregationRouter-Dv5SuK2x.mjs → createAggregationRouter-zRYWw_5D.mjs} +11 -8
- package/dist/{preloadResources-Bbp4QJ8V.mjs → createApp-D-953ZAq.mjs} +299 -390
- package/dist/{createMcpServer-CbDWkZ1T.d.mts → createMcpServer-C9cxS8zt.d.mts} +1 -1
- package/dist/{defineAggregation-UyeurGkp.mjs → defineAggregation-Bm8RjMbq.mjs} +1 -1
- package/dist/{defineResource-DzGT-2LP.mjs → defineResource-DIC7JZGU.mjs} +118 -1024
- package/dist/discovery/index.mjs +1 -1
- package/dist/docs/index.d.mts +10 -4
- package/dist/docs/index.mjs +4 -4
- package/dist/{elevation-BXCfVcNG.d.mts → elevation-BW2J3tNj.d.mts} +1 -2
- package/dist/{elevation-BF-vhGxY.mjs → elevation-DG8SrLN-.mjs} +41 -12
- package/dist/encryption/index.mjs +3 -3
- package/dist/{errorHandler-CIMkCOWm.mjs → errorHandler-BnfDviL1.mjs} +26 -5
- package/dist/{errors-C_YhELhe.mjs → errors-CtrywMHP.mjs} +58 -23
- package/dist/{errors-BGdVwP25.d.mts → errors-JYc9vwqE.d.mts} +9 -0
- package/dist/{eventPlugin-B52abJ8W.d.mts → eventPlugin-BtmA4-3P.d.mts} +65 -9
- package/dist/{eventPlugin-CmXaPWLv.mjs → eventPlugin-Q6BhzHzs.mjs} +82 -21
- package/dist/{subscribe-helpers-AVYPgqTl.mjs → eventTypes-Cdhm6ZlV.mjs} +151 -17
- package/dist/events/index.d.mts +33 -8
- package/dist/events/index.mjs +49 -53
- package/dist/events/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis-stream-entry.mjs +139 -157
- package/dist/events/transports/redis.d.mts +1 -1
- package/dist/events/transports/redis.mjs +2 -2
- package/dist/factory/index.d.mts +32 -17
- package/dist/factory/index.mjs +213 -32
- package/dist/{fastify-augmentation-Cq2nHVaW.d.mts → fastify-augmentation-DhUJ-mvo.d.mts} +11 -25
- package/dist/{fields-I_EeRWND.d.mts → fields-BBSpf8pS.d.mts} +1 -1
- package/dist/{fields-BTyPLHK0.mjs → fields-ToPYpMqS.mjs} +1 -1
- package/dist/filter-merge-IpGywvym.mjs +99 -0
- package/dist/{generate-D_YmiCNf.mjs → generate-DRTkLlIl.mjs} +2 -2
- package/dist/{headers-CNECDE6q.mjs → headers-BbkIF6vA.mjs} +2 -2
- package/dist/health-D-Ft6JM6.mjs +22 -0
- package/dist/{health-CxQzbJmr.mjs → health-DqbsG-_w.mjs} +115 -55
- package/dist/hooks/index.d.mts +2 -2
- package/dist/hooks/index.mjs +2 -2
- package/dist/idempotency/index.d.mts +31 -7
- package/dist/idempotency/index.mjs +155 -98
- package/dist/idempotency/redis.d.mts +1 -1
- package/dist/idempotency/redis.mjs +48 -11
- package/dist/{index-BHdZD8zK.d.mts → index-Bxriq3so.d.mts} +84 -21
- package/dist/{preloadResources-CjS2OfpU.d.mts → index-C8zVGYsk.d.mts} +37 -38
- package/dist/{index-D4u76eQW.d.mts → index-CRoPtISf.d.mts} +23 -73
- package/dist/{index-CbJiYrfv.d.mts → index-Chgz3d0i.d.mts} +1 -1
- package/dist/index-JdbZAIsm.d.mts +510 -0
- package/dist/{index-DHbyPo5j.d.mts → index-mqaqZNpe.d.mts} +253 -254
- package/dist/index.d.mts +8 -8
- package/dist/index.mjs +11 -11
- package/dist/{init-Y2MlSN9n.mjs → init-B_oUYDXI.mjs} +1 -1
- package/dist/integrations/event-gateway.d.mts +8 -3
- package/dist/integrations/event-gateway.mjs +4 -4
- package/dist/integrations/index.d.mts +3 -3
- package/dist/integrations/index.mjs +1 -1
- package/dist/integrations/jobs/index.d.mts +1 -1
- package/dist/integrations/jobs/index.mjs +18 -5
- package/dist/integrations/mcp/index.d.mts +72 -59
- package/dist/integrations/mcp/index.mjs +19 -4
- package/dist/integrations/mcp/testing.d.mts +2 -2
- package/dist/integrations/mcp/testing.mjs +2 -2
- package/dist/integrations/streamline.d.mts +78 -136
- package/dist/integrations/streamline.mjs +116 -54
- package/dist/integrations/webhooks.d.mts +60 -120
- package/dist/integrations/webhooks.mjs +36 -80
- package/dist/integrations/websocket-pushref-redis.d.mts +1 -1
- package/dist/integrations/websocket-pushref-redis.mjs +1 -1
- package/dist/integrations/websocket-redis.d.mts +1 -1
- package/dist/integrations/websocket-redis.mjs +1 -1
- package/dist/integrations/websocket.d.mts +3 -3
- package/dist/integrations/websocket.mjs +2 -2
- package/dist/{interface-DEWNOMza.d.mts → interface-C0395yUN.d.mts} +13 -1
- package/dist/{jsonBody-Cq9KYl2Z.mjs → jsonBody-B4YVGcql.mjs} +2 -2
- package/dist/{keys-Cmv4cBRa.mjs → keys-B2KtgMLJ.mjs} +7 -18
- package/dist/{loadResources-CblF7xt2.mjs → loadResources-Dn4lalw2.mjs} +3 -3
- package/dist/{loadResourcesFromEntry-99fIMC3p.mjs → loadResourcesFromEntry-3sLYbuse.mjs} +2 -2
- package/dist/logger/index.d.mts +1 -8
- package/dist/logger/index.mjs +3 -153
- package/dist/logger-DXjfIqjV.mjs +160 -0
- package/dist/{mcpPlugin-xF3Gw-HW.mjs → mcpPlugin-C08HalN5.mjs} +433 -170
- package/dist/{memory-CpDZ9NPw.mjs → memory-9Cp7611C.mjs} +36 -34
- package/dist/{metrics-BaKnq8ag.mjs → metrics-CWI11eRu.mjs} +39 -72
- package/dist/middleware/index.d.mts +2 -2
- package/dist/middleware/index.mjs +3 -3
- package/dist/migrations/index.mjs +2 -2
- package/dist/{module-BkQEesNQ.mjs → module-BSvOQC7E.mjs} +8 -8
- package/dist/multiTenant-cY0FkDiA.d.mts +104 -0
- package/dist/{multipartBody-C92aJ8am.mjs → multipartBody-CXM2a-Dy.mjs} +46 -7
- package/dist/{openapi-C3LFRzPq.mjs → openapi-DT_G4VhY.mjs} +48 -10
- package/dist/outbox-admin/index.d.mts +3 -3
- package/dist/outbox-admin/index.mjs +6 -18
- package/dist/{outbox-module-dsCyLxXH.mjs → outbox-module-Bjgzl6tg.mjs} +203 -33
- package/dist/{outbox-module-BHdUnuuK.d.mts → outbox-module-gZCHoE4H.d.mts} +79 -6
- package/dist/permissions/index.d.mts +5 -4
- package/dist/permissions/index.mjs +8 -6
- package/dist/{permissions-DiHXy8Ck.mjs → permissions-Cm0uYHvd.mjs} +149 -33
- package/dist/{pipe-CBVmUJ-j.mjs → pipe-BqeGT6UO.mjs} +2 -2
- package/dist/pipeline/index.d.mts +2 -2
- package/dist/pipeline/index.mjs +2 -2
- package/dist/plan-FVR6LP59.mjs +565 -0
- package/dist/{BaseController-DYJRZ0EJ.mjs → plugin-BccET1tL.mjs} +1256 -344
- package/dist/plugins/index.d.mts +14 -11
- package/dist/plugins/index.mjs +44 -22
- package/dist/plugins/response-cache.mjs +8 -14
- package/dist/plugins/tracing-entry.mjs +2 -2
- package/dist/{pluralize-2_U6QZQg.mjs → pluralize-CVIOcgMF.mjs} +1 -1
- package/dist/presets/filesUpload.d.mts +2 -2
- package/dist/presets/filesUpload.mjs +5 -5
- package/dist/presets/index.d.mts +26 -31
- package/dist/presets/index.mjs +4 -4
- package/dist/presets/multiTenant.d.mts +2 -107
- package/dist/presets/multiTenant.mjs +22 -162
- package/dist/presets/search.d.mts +2 -2
- package/dist/presets/search.mjs +2 -2
- package/dist/{presets-BdlugYTc.mjs → presets-Cpvj6fGO.mjs} +99 -107
- package/dist/{projection-Uvgp-EEj.mjs → projection-Ce4aQhQk.mjs} +2 -2
- package/dist/{pushref-registry-Dov9l4qE.d.mts → pushref-registry-UxCkoA4C.d.mts} +1 -1
- package/dist/{queryCachePlugin-BzqxconG.d.mts → queryCachePlugin-C2lZjTxk.d.mts} +1 -1
- package/dist/{queryCachePlugin-B5F09bYr.mjs → queryCachePlugin-CFWNH8aT.mjs} +12 -14
- package/dist/{rateLimitKey-CK-EU2L8.mjs → rateLimitKey-C4O-kPm0.mjs} +1 -1
- package/dist/{realtime-FnnD0n3Z.mjs → realtime-DmPE9S54.mjs} +25 -21
- package/dist/redis-stream-BMk-bpQS.d.mts +219 -0
- package/dist/{redis-Bzi1y3F9.d.mts → redis-vLvtcGy_.d.mts} +13 -24
- package/dist/redisShapes-CQksY67q.d.mts +55 -0
- package/dist/registry/index.d.mts +9 -4
- package/dist/registry/index.mjs +4 -4
- package/dist/{registry-D3y8VEJ1.mjs → registry-Bcz9G1bh.mjs} +10 -8
- package/dist/{renewingLease-B3VYh5aU.mjs → renewingLease-qODa7KJQ.mjs} +1 -1
- package/dist/{replyHelpers-DPHsdw-5.mjs → replyHelpers-CG_VtVgS.mjs} +2 -2
- package/dist/{requestContext-cSVKnYPk.mjs → requestContext-Dsu9P1bV.mjs} +1 -1
- package/dist/requirement-CbiLdQ1n.d.mts +22 -0
- package/dist/requirement-KDdoRcOP.mjs +35 -0
- package/dist/resourceRateLimit-Wf6d6FL9.d.mts +30 -0
- package/dist/resourceRateLimit-dSjVr1pk.mjs +180 -0
- package/dist/{rolldown-runtime-DjDuyglE.mjs → rolldown-runtime-D1w9Y1VJ.mjs} +1 -1
- package/dist/routeValidator-D36SW8qt.mjs +70 -0
- package/dist/{runtimeCapabilities-DSA_dH1_.mjs → runtimeCapabilities-0tccjRlj.mjs} +1 -1
- package/dist/{schedules-BktJb3Y3.mjs → schedules-C-OpmHBq.mjs} +46 -37
- package/dist/{schemaConverter-BLCSmNbr.mjs → schemaConverter-BORek3O-.mjs} +2 -2
- package/dist/{schemaIR-K16Bb5BX.mjs → schemaIR-C7Vbp71I.mjs} +2 -2
- package/dist/schemas/index.d.mts +10 -0
- package/dist/schemas/index.mjs +8 -3
- package/dist/scim/index.mjs +2 -2
- package/dist/scope/index.d.mts +2 -2
- package/dist/scope/index.mjs +6 -6
- package/dist/{scope-jSxuBTFM.mjs → scope-DQthe88b.mjs} +4 -4
- package/dist/shutdown-MqA81z_P.mjs +59 -0
- package/dist/{simpleEqualityMatcher-BiOnyflP.mjs → simpleEqualityMatcher-auW8QjXN.mjs} +1 -1
- package/dist/{sse-CH7Slxc1.mjs → sse-CYzQBVFe.mjs} +11 -15
- package/dist/{sseStream-CN-Lh1Tu.mjs → sseStream-B5_Afiqn.mjs} +2 -2
- package/dist/{store-helpers-9DX9-1j_.mjs → store-helpers-BOzk-CuX.mjs} +1 -1
- package/dist/{streaming-dvppnxsr.mjs → streaming-DjTQhZrN.mjs} +1 -1
- package/dist/subscriberIdentity-CW39uA8G.mjs +28 -0
- package/dist/tenancy--ed9eH_z.mjs +43 -0
- package/dist/tenantPreparation-BKon6Yox.mjs +67 -0
- package/dist/testing/cleanupStoreContract.mjs +1 -1
- package/dist/testing/index.d.mts +193 -175
- package/dist/testing/index.mjs +286 -212
- package/dist/testing/outboxStoreContract.mjs +137 -2
- package/dist/testing/requiredPorts.d.mts +17 -0
- package/dist/testing/requiredPorts.mjs +65 -0
- package/dist/testing/storageContract.mjs +1 -1
- package/dist/timing-qczZ0YC-.mjs +46 -0
- package/dist/{transactionContext-DCWMI6hV.mjs → transactionContext-DjFkrNG6.mjs} +1 -1
- package/dist/{typeGuards-D7tHFdH6.mjs → typeGuards-CySF12G-.mjs} +1 -1
- package/dist/types/index.d.mts +4 -4
- package/dist/types/index.mjs +1 -1
- package/dist/types/storage.mjs +1 -1
- package/dist/{types-CWQn9-IC.d.mts → types-B4Aq4Sdj.d.mts} +22 -9
- package/dist/{types-DfVDvkdP.d.mts → types-BJ-2XqVF.d.mts} +189 -204
- package/dist/{types-CDy3-zw1.mjs → types-Bk9NOgOC.mjs} +4 -4
- package/dist/usage/index.d.mts +2 -3
- package/dist/usage/index.mjs +5 -5
- package/dist/{userHelpers-DDMOZ_Pm.mjs → userHelpers-aklawRaK.mjs} +1 -1
- package/dist/utils/index.d.mts +84 -223
- package/dist/utils/index.mjs +13 -12
- package/dist/{utils-B-zj_b__.mjs → utils-ec1oTo1n.mjs} +315 -404
- package/dist/{validate-R0G_JrnK.mjs → validate-9yzHC1e2.mjs} +6 -14
- package/dist/{versioning-D6JIK8Tk.d.mts → versioning-Bsb51gGT.d.mts} +28 -13
- package/dist/{versioning-DuVWcu-F.mjs → versioning-fhhWHV74.mjs} +4 -4
- package/dist/{websocket-BOXVggMf.d.mts → websocket-Cs4awVyD.d.mts} +1 -1
- package/dist/{workScope-BhsWde4k.mjs → workScope-zpPyge4t.mjs} +2 -2
- package/package.json +578 -574
- package/skills/arc/SKILL.md +13 -4
- package/skills/arc/references/auth.md +8 -5
- package/skills/arc/references/integrations.md +1 -1
- package/skills/arc/references/mcp.md +8 -6
- package/skills/arc/references/multi-tenancy.md +19 -14
- package/skills/arc/references/production.md +27 -10
- package/dist/actionPermissions-DPwPWPOV.mjs +0 -350
- package/dist/index-CFfLKMH4.d.mts +0 -290
- package/dist/interface-BIpgzbZl.mjs +0 -17
- package/dist/redis-stream-BPKscsTB.d.mts +0 -260
- package/dist/registerRoute-DRsSHPSM.mjs +0 -364
- package/dist/sync/changelog.d.mts +0 -3
- package/dist/sync/changelog.mjs +0 -3
package/dist/discovery/index.mjs
CHANGED
package/dist/docs/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import {
|
|
2
|
+
import { o as RegistryEntry } from "../index-mqaqZNpe.mjs";
|
|
3
3
|
import { t as ExternalOpenApiPaths } from "../externalPaths-CmGOxOtD.mjs";
|
|
4
4
|
import { FastifyPluginAsync } from "fastify";
|
|
5
5
|
//#region src/docs/openapi/types.d.ts
|
|
@@ -86,6 +86,14 @@ interface Operation {
|
|
|
86
86
|
type: string;
|
|
87
87
|
name: string;
|
|
88
88
|
}>;
|
|
89
|
+
/** Idempotency-key fence: every call (`required`) or the listed actions (`requiredActions`). */
|
|
90
|
+
"x-arc-idempotency"?: {
|
|
91
|
+
required?: true;
|
|
92
|
+
requiredActions?: readonly string[];
|
|
93
|
+
dedup?: "handler";
|
|
94
|
+
owner?: string;
|
|
95
|
+
handlerDedup?: Readonly<Record<string, string>>;
|
|
96
|
+
};
|
|
89
97
|
}
|
|
90
98
|
interface Parameter {
|
|
91
99
|
name: string;
|
|
@@ -137,7 +145,6 @@ interface SecurityScheme {
|
|
|
137
145
|
}
|
|
138
146
|
//#endregion
|
|
139
147
|
//#region src/docs/openapi/index.d.ts
|
|
140
|
-
declare const openApiPlugin: FastifyPluginAsync<OpenApiOptions>;
|
|
141
148
|
/**
|
|
142
149
|
* Build OpenAPI spec from registry resources.
|
|
143
150
|
* Shared by HTTP docs endpoint and CLI export command.
|
|
@@ -166,7 +173,6 @@ interface ScalarOptions {
|
|
|
166
173
|
/** Favicon URL */
|
|
167
174
|
favicon?: string;
|
|
168
175
|
}
|
|
169
|
-
declare const scalarPlugin: FastifyPluginAsync<ScalarOptions>;
|
|
170
176
|
declare const _default$1: FastifyPluginAsync<ScalarOptions>;
|
|
171
177
|
//#endregion
|
|
172
|
-
export { type ExternalOpenApiPaths, type OpenApiBuildOptions, type OpenApiOptions, type OpenApiSpec, type ScalarOptions, buildOpenApiSpec, _default as openApiPlugin,
|
|
178
|
+
export { type ExternalOpenApiPaths, type OpenApiBuildOptions, type OpenApiOptions, type OpenApiSpec, type ScalarOptions, buildOpenApiSpec, _default as openApiPlugin, _default$1 as scalarPlugin };
|
package/dist/docs/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { n as getUserRoles } from "../userHelpers-
|
|
3
|
-
import { n as
|
|
1
|
+
/*! @classytic/arc v2.43.0 | MIT | https://classytic.com */
|
|
2
|
+
import { n as getUserRoles } from "../userHelpers-aklawRaK.mjs";
|
|
3
|
+
import { n as openapi_default, t as buildOpenApiSpec } from "../openapi-DT_G4VhY.mjs";
|
|
4
4
|
import fp from "fastify-plugin";
|
|
5
5
|
//#region src/docs/scalar.ts
|
|
6
6
|
const scalarPlugin = async (fastify, opts = {}) => {
|
|
@@ -54,4 +54,4 @@ var scalar_default = fp(scalarPlugin, {
|
|
|
54
54
|
fastify: "5.x"
|
|
55
55
|
});
|
|
56
56
|
//#endregion
|
|
57
|
-
export { buildOpenApiSpec, openapi_default as openApiPlugin,
|
|
57
|
+
export { buildOpenApiSpec, openapi_default as openApiPlugin, scalar_default as scalarPlugin };
|
|
@@ -17,7 +17,6 @@ interface ElevationEvent {
|
|
|
17
17
|
request: FastifyRequest;
|
|
18
18
|
timestamp: Date;
|
|
19
19
|
}
|
|
20
|
-
declare const elevationPlugin: FastifyPluginAsync<ElevationOptions>;
|
|
21
20
|
declare const _default: FastifyPluginAsync<ElevationOptions>;
|
|
22
21
|
//#endregion
|
|
23
|
-
export {
|
|
22
|
+
export { ElevationOptions as n, _default as r, ElevationEvent as t };
|
|
@@ -1,10 +1,41 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { t as __exportAll } from "./rolldown-runtime-
|
|
3
|
-
import { arcLog } from "./logger
|
|
4
|
-
import { n as requireSingleHeaderValue } from "./headers-
|
|
5
|
-
import { n as getUserRoles } from "./userHelpers-
|
|
1
|
+
/*! @classytic/arc v2.43.0 | MIT | https://classytic.com */
|
|
2
|
+
import { t as __exportAll } from "./rolldown-runtime-D1w9Y1VJ.mjs";
|
|
3
|
+
import { t as arcLog } from "./logger-DXjfIqjV.mjs";
|
|
4
|
+
import { n as requireSingleHeaderValue } from "./headers-BbkIF6vA.mjs";
|
|
5
|
+
import { n as getUserRoles } from "./userHelpers-aklawRaK.mjs";
|
|
6
|
+
import { ARC_ERROR_CODES } from "@classytic/repo-core/errors";
|
|
6
7
|
import fp from "fastify-plugin";
|
|
7
8
|
//#region src/scope/elevation.ts
|
|
9
|
+
/**
|
|
10
|
+
* Elevation Plugin — Explicit Platform Admin Access
|
|
11
|
+
*
|
|
12
|
+
* Opt-in Fastify plugin that allows platform admins to explicitly
|
|
13
|
+
* elevate their scope via the `x-arc-scope: platform` header.
|
|
14
|
+
*
|
|
15
|
+
* Without this header, a superadmin is treated as a normal user.
|
|
16
|
+
* This prevents implicit bypass and enables audit logging.
|
|
17
|
+
*
|
|
18
|
+
* ## Lifecycle
|
|
19
|
+
*
|
|
20
|
+
* Elevation wraps `fastify.authenticate` so it always runs AFTER
|
|
21
|
+
* authentication has set `request.user`. This avoids the `onRequest`
|
|
22
|
+
* timing issue where `request.user` doesn't exist yet.
|
|
23
|
+
*
|
|
24
|
+
* Flow: `authenticate()` → user is set → `elevation check` → scope is set
|
|
25
|
+
*
|
|
26
|
+
* Inspired by Stripe Connect's `Stripe-Account` header.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* const app = await createApp({
|
|
31
|
+
* auth: { type: 'betterAuth', betterAuth: adapter },
|
|
32
|
+
* elevation: {
|
|
33
|
+
* platformRoles: ['superadmin'],
|
|
34
|
+
* onElevation: (event) => auditLog.write(event),
|
|
35
|
+
* },
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
8
39
|
var elevation_exports = /* @__PURE__ */ __exportAll({
|
|
9
40
|
default: () => elevation_default,
|
|
10
41
|
elevationPlugin: () => elevationPlugin
|
|
@@ -25,10 +56,9 @@ const elevationPlugin = async (fastify, opts = {}) => {
|
|
|
25
56
|
if (!user) {
|
|
26
57
|
log.debug("Elevation requested but no user after auth");
|
|
27
58
|
reply.code(401).send({
|
|
28
|
-
|
|
29
|
-
error: "Unauthorized",
|
|
59
|
+
code: ARC_ERROR_CODES.ELEVATION_AUTH_REQUIRED,
|
|
30
60
|
message: "Authentication required for platform elevation",
|
|
31
|
-
|
|
61
|
+
status: 401
|
|
32
62
|
});
|
|
33
63
|
return;
|
|
34
64
|
}
|
|
@@ -40,10 +70,9 @@ const elevationPlugin = async (fastify, opts = {}) => {
|
|
|
40
70
|
required: platformRoles
|
|
41
71
|
});
|
|
42
72
|
reply.code(403).send({
|
|
43
|
-
|
|
44
|
-
error: "Forbidden",
|
|
73
|
+
code: ARC_ERROR_CODES.ELEVATION_FORBIDDEN,
|
|
45
74
|
message: "Insufficient privileges for platform elevation",
|
|
46
|
-
|
|
75
|
+
status: 403
|
|
47
76
|
});
|
|
48
77
|
return;
|
|
49
78
|
}
|
|
@@ -95,4 +124,4 @@ var elevation_default = fp(elevationPlugin, {
|
|
|
95
124
|
fastify: "5.x"
|
|
96
125
|
});
|
|
97
126
|
//#endregion
|
|
98
|
-
export {
|
|
127
|
+
export { elevation_exports as n, elevation_default as t };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { t as ArcError } from "../errors-
|
|
3
|
-
import { t as parseJsonBody } from "../jsonBody-
|
|
1
|
+
/*! @classytic/arc v2.43.0 | MIT | https://classytic.com */
|
|
2
|
+
import { t as ArcError } from "../errors-CtrywMHP.mjs";
|
|
3
|
+
import { t as parseJsonBody } from "../jsonBody-B4YVGcql.mjs";
|
|
4
4
|
import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
|
|
5
5
|
import fp from "fastify-plugin";
|
|
6
6
|
//#region src/encryption/fieldCipher.ts
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { t as __exportAll } from "./rolldown-runtime-
|
|
3
|
-
import { m as statusToArcCode, p as isArcError } from "./errors-
|
|
4
|
-
import { isProductionEnv } from "@classytic/primitives/environment";
|
|
1
|
+
/*! @classytic/arc v2.43.0 | MIT | https://classytic.com */
|
|
2
|
+
import { t as __exportAll } from "./rolldown-runtime-D1w9Y1VJ.mjs";
|
|
3
|
+
import { m as statusToArcCode, p as isArcError } from "./errors-CtrywMHP.mjs";
|
|
5
4
|
import { isHttpError, toErrorContract } from "@classytic/repo-core/errors";
|
|
5
|
+
import { isProductionEnv } from "@classytic/primitives/environment";
|
|
6
6
|
import fp from "fastify-plugin";
|
|
7
7
|
//#region src/plugins/errorHandler.ts
|
|
8
8
|
/**
|
|
@@ -154,10 +154,15 @@ async function errorHandlerPluginFn(fastify, options = {}) {
|
|
|
154
154
|
};
|
|
155
155
|
const status = wire.status ?? 500;
|
|
156
156
|
if (status >= 500 && wire.code === "arc.internal_error" && !exposeInternalMessages) wire.message = "Internal Server Error";
|
|
157
|
-
|
|
157
|
+
const deliberateUnavailable = status === 503 && wire.code !== "arc.internal_error";
|
|
158
|
+
if (status >= 500 && !deliberateUnavailable) request.log.error({
|
|
158
159
|
err: error,
|
|
159
160
|
status
|
|
160
161
|
}, "Server error");
|
|
162
|
+
else if (deliberateUnavailable) request.log.warn({
|
|
163
|
+
code: wire.code,
|
|
164
|
+
status
|
|
165
|
+
}, "Service unavailable");
|
|
161
166
|
else if (status >= 400) request.log.warn({
|
|
162
167
|
err: error,
|
|
163
168
|
status
|
|
@@ -166,10 +171,26 @@ async function errorHandlerPluginFn(fastify, options = {}) {
|
|
|
166
171
|
const causeLevel = status >= 500 ? "error" : "warn";
|
|
167
172
|
request.log[causeLevel]({ cause: error.cause }, "Error cause chain");
|
|
168
173
|
}
|
|
174
|
+
if (status === 429 || status === 503) {
|
|
175
|
+
const retryAfter = retryAfterSeconds(error);
|
|
176
|
+
if (retryAfter !== void 0) reply.header("retry-after", String(retryAfter));
|
|
177
|
+
}
|
|
169
178
|
return reply.status(status).send(wire);
|
|
170
179
|
});
|
|
171
180
|
}
|
|
172
181
|
/**
|
|
182
|
+
* Seconds to put in `Retry-After`, read from the thrown error's own
|
|
183
|
+
* `retryAfter` property (the convention `RateLimitError` set). Whole seconds,
|
|
184
|
+
* never below 1 — `0` would tell every client to retry immediately, which is
|
|
185
|
+
* the stampede the header exists to prevent.
|
|
186
|
+
*/
|
|
187
|
+
function retryAfterSeconds(error) {
|
|
188
|
+
if (!error || typeof error !== "object") return void 0;
|
|
189
|
+
const value = error.retryAfter;
|
|
190
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) return void 0;
|
|
191
|
+
return Math.max(1, Math.ceil(value));
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
173
194
|
* Is `code` a caller-defined DOMAIN error code that is safe to surface on the
|
|
174
195
|
* wire, as opposed to a framework/runtime code that must never leak?
|
|
175
196
|
*
|
|
@@ -1,6 +1,26 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
1
|
+
/*! @classytic/arc v2.43.0 | MIT | https://classytic.com */
|
|
2
|
+
import { ARC_ERROR_CODES } from "@classytic/repo-core/errors";
|
|
2
3
|
//#region src/utils/errors.ts
|
|
3
4
|
/**
|
|
5
|
+
* Arc error hierarchy.
|
|
6
|
+
*
|
|
7
|
+
* Throw an `ArcError` (or one of its subclasses) anywhere in a controller
|
|
8
|
+
* or middleware. Arc's global error handler catches it and serializes to
|
|
9
|
+
* the canonical `ErrorContract` wire shape via repo-core's
|
|
10
|
+
* `toErrorContract(err)` — one contract across the org.
|
|
11
|
+
*
|
|
12
|
+
* `ArcError` implements the {@link HttpError} contract from
|
|
13
|
+
* `@classytic/repo-core/errors`, so any host that already speaks that
|
|
14
|
+
* contract (mongokit, sqlitekit, streamline, prismakit) catches and
|
|
15
|
+
* serializes arc errors with the same code path it uses for its own.
|
|
16
|
+
*
|
|
17
|
+
* **Codes are catalogued in `@classytic/repo-core/errors`** (`ARC_ERROR_CODES`,
|
|
18
|
+
* `ARC_REASON_CODES`) so client SDKs read the wire vocabulary without
|
|
19
|
+
* depending on arc. Emit from those constants; `tests/utils/error-code-catalog.test.ts`
|
|
20
|
+
* fails on an uncatalogued `arc.*` literal. Domain packages use their own
|
|
21
|
+
* namespace (`commerce.cart.locked`).
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
4
24
|
* Base Arc Error. Implements the canonical `HttpError` contract — `status`
|
|
5
25
|
* mirrors `statusCode` and `meta` mirrors `details`, so consumers reading
|
|
6
26
|
* either name see the same value without adapter glue.
|
|
@@ -13,7 +33,7 @@ var ArcError = class extends Error {
|
|
|
13
33
|
cause;
|
|
14
34
|
constructor(message, options = {}) {
|
|
15
35
|
super(message, options.cause ? { cause: options.cause } : void 0);
|
|
16
|
-
this.code = options.code ??
|
|
36
|
+
this.code = options.code ?? ARC_ERROR_CODES.ERROR;
|
|
17
37
|
this.statusCode = options.statusCode ?? 500;
|
|
18
38
|
this.details = options.details;
|
|
19
39
|
this.cause = options.cause;
|
|
@@ -32,7 +52,7 @@ var NotFoundError = class extends ArcError {
|
|
|
32
52
|
constructor(resource, identifier) {
|
|
33
53
|
const message = identifier ? `${resource} with identifier '${identifier}' not found` : `${resource} not found`;
|
|
34
54
|
super(message, {
|
|
35
|
-
code:
|
|
55
|
+
code: ARC_ERROR_CODES.NOT_FOUND,
|
|
36
56
|
statusCode: 404,
|
|
37
57
|
details: {
|
|
38
58
|
resource,
|
|
@@ -46,18 +66,29 @@ var ValidationError = class extends ArcError {
|
|
|
46
66
|
errors;
|
|
47
67
|
constructor(message, errors = []) {
|
|
48
68
|
super(message, {
|
|
49
|
-
code:
|
|
69
|
+
code: ARC_ERROR_CODES.VALIDATION_ERROR,
|
|
50
70
|
statusCode: 400,
|
|
51
71
|
details: { errors }
|
|
52
72
|
});
|
|
53
73
|
this.name = "ValidationError";
|
|
54
74
|
this.errors = errors;
|
|
55
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* `HttpError.validationErrors` — what `toErrorContract` turns into the wire's
|
|
78
|
+
* `details[]`, the one place clients (arc-next `fieldErrors`) read field errors.
|
|
79
|
+
*/
|
|
80
|
+
get validationErrors() {
|
|
81
|
+
return this.errors.map((e) => ({
|
|
82
|
+
path: e.field,
|
|
83
|
+
validator: "validation_error",
|
|
84
|
+
error: e.message
|
|
85
|
+
}));
|
|
86
|
+
}
|
|
56
87
|
};
|
|
57
88
|
var UnauthorizedError = class extends ArcError {
|
|
58
89
|
constructor(message = "Authentication required") {
|
|
59
90
|
super(message, {
|
|
60
|
-
code:
|
|
91
|
+
code: ARC_ERROR_CODES.UNAUTHORIZED,
|
|
61
92
|
statusCode: 401
|
|
62
93
|
});
|
|
63
94
|
this.name = "UnauthorizedError";
|
|
@@ -66,7 +97,7 @@ var UnauthorizedError = class extends ArcError {
|
|
|
66
97
|
var ForbiddenError = class extends ArcError {
|
|
67
98
|
constructor(message = "Access denied") {
|
|
68
99
|
super(message, {
|
|
69
|
-
code:
|
|
100
|
+
code: ARC_ERROR_CODES.FORBIDDEN,
|
|
70
101
|
statusCode: 403
|
|
71
102
|
});
|
|
72
103
|
this.name = "ForbiddenError";
|
|
@@ -75,7 +106,7 @@ var ForbiddenError = class extends ArcError {
|
|
|
75
106
|
var ConflictError = class extends ArcError {
|
|
76
107
|
constructor(message, field) {
|
|
77
108
|
super(message, {
|
|
78
|
-
code:
|
|
109
|
+
code: ARC_ERROR_CODES.CONFLICT,
|
|
79
110
|
statusCode: 409,
|
|
80
111
|
...field ? { details: { field } } : {}
|
|
81
112
|
});
|
|
@@ -86,7 +117,7 @@ var OrgRequiredError = class extends ArcError {
|
|
|
86
117
|
organizations;
|
|
87
118
|
constructor(message, organizations) {
|
|
88
119
|
super(message, {
|
|
89
|
-
code:
|
|
120
|
+
code: ARC_ERROR_CODES.ORG_SELECTION_REQUIRED,
|
|
90
121
|
statusCode: 403,
|
|
91
122
|
...organizations ? { details: { organizations } } : {}
|
|
92
123
|
});
|
|
@@ -97,7 +128,7 @@ var OrgRequiredError = class extends ArcError {
|
|
|
97
128
|
var OrgAccessDeniedError = class extends ArcError {
|
|
98
129
|
constructor(orgId) {
|
|
99
130
|
super("Organization access denied", {
|
|
100
|
-
code:
|
|
131
|
+
code: ARC_ERROR_CODES.ORG_ACCESS_DENIED,
|
|
101
132
|
statusCode: 403,
|
|
102
133
|
...orgId ? { details: { organizationId: orgId } } : {}
|
|
103
134
|
});
|
|
@@ -108,7 +139,7 @@ var RateLimitError = class extends ArcError {
|
|
|
108
139
|
retryAfter;
|
|
109
140
|
constructor(message = "Too many requests", retryAfter) {
|
|
110
141
|
super(message, {
|
|
111
|
-
code:
|
|
142
|
+
code: ARC_ERROR_CODES.RATE_LIMITED,
|
|
112
143
|
statusCode: 429,
|
|
113
144
|
...retryAfter ? { details: { retryAfter } } : {}
|
|
114
145
|
});
|
|
@@ -119,7 +150,7 @@ var RateLimitError = class extends ArcError {
|
|
|
119
150
|
var ServiceUnavailableError = class extends ArcError {
|
|
120
151
|
constructor(message = "Service temporarily unavailable") {
|
|
121
152
|
super(message, {
|
|
122
|
-
code:
|
|
153
|
+
code: ARC_ERROR_CODES.SERVICE_UNAVAILABLE,
|
|
123
154
|
statusCode: 503
|
|
124
155
|
});
|
|
125
156
|
this.name = "ServiceUnavailableError";
|
|
@@ -130,21 +161,25 @@ var ServiceUnavailableError = class extends ArcError {
|
|
|
130
161
|
* and the global error handler when no explicit code is supplied.
|
|
131
162
|
*/
|
|
132
163
|
const STATUS_CODE_MAP = {
|
|
133
|
-
400:
|
|
134
|
-
401:
|
|
135
|
-
403:
|
|
136
|
-
404:
|
|
137
|
-
409:
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
164
|
+
400: ARC_ERROR_CODES.BAD_REQUEST,
|
|
165
|
+
401: ARC_ERROR_CODES.UNAUTHORIZED,
|
|
166
|
+
403: ARC_ERROR_CODES.FORBIDDEN,
|
|
167
|
+
404: ARC_ERROR_CODES.NOT_FOUND,
|
|
168
|
+
409: ARC_ERROR_CODES.CONFLICT,
|
|
169
|
+
412: ARC_ERROR_CODES.PRECONDITION_FAILED,
|
|
170
|
+
413: ARC_ERROR_CODES.PAYLOAD_TOO_LARGE,
|
|
171
|
+
415: ARC_ERROR_CODES.UNSUPPORTED_MEDIA_TYPE,
|
|
172
|
+
422: ARC_ERROR_CODES.UNPROCESSABLE_ENTITY,
|
|
173
|
+
429: ARC_ERROR_CODES.RATE_LIMITED,
|
|
174
|
+
500: ARC_ERROR_CODES.INTERNAL_ERROR,
|
|
175
|
+
501: ARC_ERROR_CODES.NOT_IMPLEMENTED,
|
|
176
|
+
502: ARC_ERROR_CODES.BAD_GATEWAY,
|
|
177
|
+
503: ARC_ERROR_CODES.SERVICE_UNAVAILABLE,
|
|
178
|
+
504: ARC_ERROR_CODES.GATEWAY_TIMEOUT
|
|
144
179
|
};
|
|
145
180
|
/** Status → canonical arc code, falling back to `arc.error`. */
|
|
146
181
|
function statusToArcCode(status) {
|
|
147
|
-
return STATUS_CODE_MAP[status] ??
|
|
182
|
+
return STATUS_CODE_MAP[status] ?? ARC_ERROR_CODES.ERROR;
|
|
148
183
|
}
|
|
149
184
|
/**
|
|
150
185
|
* Quick `ArcError` constructor when the bundled subclasses don't fit.
|
|
@@ -36,6 +36,15 @@ declare class ValidationError extends ArcError {
|
|
|
36
36
|
field: string;
|
|
37
37
|
message: string;
|
|
38
38
|
}>);
|
|
39
|
+
/**
|
|
40
|
+
* `HttpError.validationErrors` — what `toErrorContract` turns into the wire's
|
|
41
|
+
* `details[]`, the one place clients (arc-next `fieldErrors`) read field errors.
|
|
42
|
+
*/
|
|
43
|
+
get validationErrors(): Array<{
|
|
44
|
+
path: string;
|
|
45
|
+
validator: string;
|
|
46
|
+
error: string;
|
|
47
|
+
}>;
|
|
39
48
|
}
|
|
40
49
|
declare class UnauthorizedError extends ArcError {
|
|
41
50
|
constructor(message?: string);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
|
|
2
|
-
import { a as EventTransport, i as EventLogger, n as DomainEvent, r as EventHandler, s as MemoryEventTransportOptions } from "./EventTransport-
|
|
3
|
-
import { FastifyPluginAsync } from "fastify";
|
|
2
|
+
import { a as EventTransport, i as EventLogger, n as DomainEvent, r as EventHandler, s as MemoryEventTransportOptions } from "./EventTransport-CiicKz2Z.mjs";
|
|
3
|
+
import { FastifyInstance, FastifyPluginAsync } from "fastify";
|
|
4
|
+
import { EventDurability, FactExpectation } from "@classytic/primitives/durable-events";
|
|
4
5
|
//#region src/events/defineEvent.d.ts
|
|
5
6
|
interface EventSchema {
|
|
6
7
|
type: "object";
|
|
@@ -11,26 +12,68 @@ interface EventSchema {
|
|
|
11
12
|
required?: string[];
|
|
12
13
|
[key: string]: unknown;
|
|
13
14
|
}
|
|
14
|
-
|
|
15
|
+
/** A zod (v4) schema — the one way to author an event payload. Structural: arc never imports zod for it. */
|
|
16
|
+
interface ZodPayloadSchema {
|
|
17
|
+
readonly _zod: {
|
|
18
|
+
readonly output: unknown;
|
|
19
|
+
};
|
|
20
|
+
safeParse(value: unknown): {
|
|
21
|
+
success: boolean;
|
|
22
|
+
error?: {
|
|
23
|
+
issues: ReadonlyArray<{
|
|
24
|
+
path: ReadonlyArray<PropertyKey>;
|
|
25
|
+
message: string;
|
|
26
|
+
}>;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Whether the event books money or moves stock. `'durable'` needs `occurrence` (aggregate id plus
|
|
32
|
+
* step): `.create()` derives a fixed id from it, and `fastify.events.publish` refuses the type —
|
|
33
|
+
* it is written to the outbox in its unit of work. Undeclared reads as not yet classified.
|
|
34
|
+
*/
|
|
35
|
+
type EventDurabilityInput<T> = {
|
|
36
|
+
durability?: "ephemeral";
|
|
37
|
+
occurrence?: never;
|
|
38
|
+
produces?: never;
|
|
39
|
+
} | {
|
|
40
|
+
durability: "durable";
|
|
41
|
+
occurrence(payload: T): string;
|
|
42
|
+
produces?: readonly FactExpectation<T>[];
|
|
43
|
+
};
|
|
44
|
+
interface EventDefinitionBase {
|
|
15
45
|
/** Event type name (e.g., 'order.created') */
|
|
16
46
|
name: string;
|
|
17
|
-
/**
|
|
47
|
+
/**
|
|
48
|
+
* The payload as a zod schema — preferred. arc derives the JSON Schema (registry, AsyncAPI,
|
|
49
|
+
* contract snapshots) and the payload TYPE from it, and validates with it.
|
|
50
|
+
*/
|
|
51
|
+
payload?: ZodPayloadSchema;
|
|
52
|
+
/** Raw JSON Schema, for definitions that do not use zod (kernels with no zod dependency). */
|
|
18
53
|
schema?: EventSchema;
|
|
19
54
|
/** Event version for schema evolution (default: 1) */
|
|
20
55
|
version?: number;
|
|
21
56
|
/** Human-readable description */
|
|
22
57
|
description?: string;
|
|
23
58
|
}
|
|
59
|
+
type EventDefinitionInput<T = unknown> = EventDefinitionBase & EventDurabilityInput<T>;
|
|
24
60
|
interface EventDefinitionOutput<T = unknown> {
|
|
25
61
|
/** Event type name */
|
|
26
62
|
readonly name: string;
|
|
27
|
-
/** JSON Schema for payload validation */
|
|
63
|
+
/** JSON Schema for payload validation — generated from `payload` when that was given. */
|
|
28
64
|
readonly schema?: EventSchema;
|
|
65
|
+
/** The zod schema the payload was declared with, when it was — the registry validates with it. */
|
|
66
|
+
readonly payloadSchema?: ZodPayloadSchema;
|
|
29
67
|
/** Event version */
|
|
30
68
|
readonly version: number;
|
|
31
69
|
/** Human-readable description */
|
|
32
70
|
readonly description?: string;
|
|
33
|
-
/**
|
|
71
|
+
/** `undefined` = not yet classified. */
|
|
72
|
+
readonly durability?: EventDurability;
|
|
73
|
+
/** Present on a durable definition: the occurrence its fixed id derives from. */
|
|
74
|
+
occurrence?(payload: T): string;
|
|
75
|
+
readonly produces?: readonly FactExpectation<T>[];
|
|
76
|
+
/** Create a DomainEvent with this type + auto-generated metadata (a fixed id when durable) */
|
|
34
77
|
create(payload: T, meta?: Partial<DomainEvent["meta"]>): DomainEvent<T>;
|
|
35
78
|
}
|
|
36
79
|
interface ValidationResult {
|
|
@@ -72,6 +115,7 @@ interface EventRegistry {
|
|
|
72
115
|
version: number;
|
|
73
116
|
description?: string;
|
|
74
117
|
schema?: EventSchema;
|
|
118
|
+
durability?: EventDurability;
|
|
75
119
|
}>;
|
|
76
120
|
/**
|
|
77
121
|
* Validate a payload against a registered event's schema.
|
|
@@ -94,7 +138,11 @@ interface EventRegistry {
|
|
|
94
138
|
*
|
|
95
139
|
* const event = OrderCreated.create({ orderId: '123' });
|
|
96
140
|
*/
|
|
97
|
-
declare function defineEvent<
|
|
141
|
+
declare function defineEvent<S extends ZodPayloadSchema>(input: EventDefinitionInput<S["_zod"]["output"]> & {
|
|
142
|
+
payload: S;
|
|
143
|
+
schema?: never;
|
|
144
|
+
}): EventDefinitionOutput<S["_zod"]["output"]>;
|
|
145
|
+
declare function defineEvent<T = unknown>(input: EventDefinitionInput<T>): EventDefinitionOutput<T>;
|
|
98
146
|
/**
|
|
99
147
|
* Create an event registry for cataloging and validating events.
|
|
100
148
|
*
|
|
@@ -161,8 +209,8 @@ interface RetryOptions {
|
|
|
161
209
|
*/
|
|
162
210
|
onDead?: (event: DomainEvent, errors: Error[]) => void | Promise<void>;
|
|
163
211
|
/**
|
|
164
|
-
* What to do when
|
|
165
|
-
*
|
|
212
|
+
* What to do when retries are exhausted and no durable sink took the event —
|
|
213
|
+
* `transport.deadLetter()` / `deadLetter` failed, or neither is wired.
|
|
166
214
|
*
|
|
167
215
|
* - `'rethrow'` (default) — the wrapper throws, so the transport treats
|
|
168
216
|
* the handler as failed: an at-least-once transport (Redis Streams,
|
|
@@ -278,6 +326,9 @@ interface EventPluginOptions {
|
|
|
278
326
|
* silently drop events while requests continue succeeding. Pair with the
|
|
279
327
|
* `onPublishError` callback to monitor failures, or use `wal` for
|
|
280
328
|
* at-least-once delivery guarantees.
|
|
329
|
+
*
|
|
330
|
+
* Never applies to a type the `registry` declares `durability: 'durable'`: the facade
|
|
331
|
+
* refuses it with `NonDurablePublishError` (it belongs in the outbox).
|
|
281
332
|
*/
|
|
282
333
|
failOpen?: boolean;
|
|
283
334
|
/**
|
|
@@ -383,6 +434,11 @@ declare module "fastify" {
|
|
|
383
434
|
transportName: string;
|
|
384
435
|
/** Event registry for introspection (undefined when no registry configured) */
|
|
385
436
|
registry?: EventRegistry;
|
|
437
|
+
/**
|
|
438
|
+
* Watch every event that reaches the transport — a live publish or an outbox relay.
|
|
439
|
+
* Read-only: a listener cannot change or stop delivery, and one that throws is ignored.
|
|
440
|
+
*/
|
|
441
|
+
observe: (listener: (event: DomainEvent) => void) => () => void;
|
|
386
442
|
};
|
|
387
443
|
}
|
|
388
444
|
}
|