@classytic/arc 2.8.0 → 2.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -1
- package/dist/{BaseController-CpMfCXdn.mjs → BaseController-DAGGc5Xn.mjs} +76 -25
- package/dist/{EventTransport-n1KBxC_N.d.mts → EventTransport-CinyO7zQ.d.mts} +37 -1
- package/dist/{ResourceRegistry-BOtJuRCs.mjs → ResourceRegistry-Dq3_zBQP.mjs} +17 -5
- package/dist/adapters/index.d.mts +2 -2
- package/dist/adapters/index.mjs +1 -1
- package/dist/{adapters-BxGgSHjj.mjs → adapters-BBqAVvPK.mjs} +11 -0
- package/dist/audit/index.d.mts +1 -1
- package/dist/audit/index.mjs +1 -1
- package/dist/audit/mongodb.d.mts +1 -1
- package/dist/audit/mongodb.mjs +1 -1
- package/dist/auth/index.d.mts +4 -4
- package/dist/auth/index.mjs +3 -3
- package/dist/auth/redis-session.d.mts +1 -1
- package/dist/{betterAuthOpenApi-CHCIuA-p.mjs → betterAuthOpenApi-C5lDyRH2.mjs} +1 -1
- package/dist/cache/index.d.mts +2 -2
- package/dist/cli/commands/describe.mjs +1 -1
- package/dist/cli/commands/docs.mjs +2 -2
- package/dist/cli/commands/generate.mjs +1 -1
- package/dist/cli/commands/init.mjs +10 -10
- package/dist/cli/commands/introspect.mjs +3 -3
- package/dist/core/index.d.mts +3 -3
- package/dist/core/index.mjs +5 -5
- package/dist/{core-BfrfxNqO.mjs → core-DKSwNSXf.mjs} +1 -1
- package/dist/{createActionRouter-CbkIAaGh.mjs → createActionRouter-Df1BuawX.mjs} +87 -21
- package/dist/{createApp-Cy8eUNKQ.mjs → createApp-BOYjBgdI.mjs} +16 -7
- package/dist/{defineResource-CovBXvTB.mjs → defineResource-Bb_Bdhtw.mjs} +60 -33
- package/dist/docs/index.d.mts +2 -2
- package/dist/docs/index.mjs +1 -1
- package/dist/dynamic/index.d.mts +2 -2
- package/dist/dynamic/index.mjs +1 -1
- package/dist/{errorHandler-BeN-ERN7.d.mts → errorHandler-CdZDavNH.d.mts} +2 -2
- package/dist/{errorHandler-BW08lEiy.mjs → errorHandler-mzqk4cGl.mjs} +1 -1
- package/dist/{eventPlugin-CAOWMQS8.d.mts → eventPlugin-CVxlE6De.d.mts} +1 -1
- package/dist/{eventPlugin-x4jo3sG0.mjs → eventPlugin-D91S2YF4.mjs} +19 -1
- package/dist/events/index.d.mts +399 -28
- package/dist/events/index.mjs +345 -29
- package/dist/events/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis-stream-entry.mjs +3 -1
- package/dist/events/transports/redis.d.mts +1 -1
- package/dist/factory/index.d.mts +1 -1
- package/dist/factory/index.mjs +2 -152
- package/dist/hooks/index.d.mts +1 -1
- package/dist/idempotency/index.d.mts +3 -3
- package/dist/idempotency/mongodb.d.mts +1 -1
- package/dist/idempotency/mongodb.mjs +18 -6
- package/dist/idempotency/redis.d.mts +1 -1
- package/dist/idempotency/redis.mjs +10 -1
- package/dist/{index-BpMhrFgn.d.mts → index-BgmMdpm8.d.mts} +1 -1
- package/dist/{index-CBru2y5Y.d.mts → index-CSkeivBx.d.mts} +3 -3
- package/dist/{index-qct60lnl.d.mts → index-CpTSDqmD.d.mts} +60 -6
- package/dist/index.d.mts +8 -8
- package/dist/index.mjs +7 -7
- package/dist/integrations/event-gateway.d.mts +1 -1
- package/dist/integrations/event-gateway.mjs +1 -1
- package/dist/integrations/index.d.mts +1 -1
- package/dist/integrations/mcp/index.d.mts +2 -2
- package/dist/integrations/mcp/index.mjs +1 -1
- package/dist/integrations/mcp/testing.d.mts +1 -1
- package/dist/integrations/mcp/testing.mjs +1 -1
- package/dist/{interface-IJqN3pXK.d.mts → interface-BVuMfeVv.d.mts} +596 -125
- package/dist/loadResources-Bksk8ydA.mjs +154 -0
- package/dist/{mongodb-B1eVtFhw.d.mts → mongodb-B8U2xaLj.d.mts} +1 -1
- package/dist/{mongodb-NShVZDMr.d.mts → mongodb-X7LbEjTN.d.mts} +10 -1
- package/dist/{openapi-AYLVjqVe.mjs → openapi-CYCuekCn.mjs} +50 -3
- package/dist/org/index.d.mts +2 -2
- package/dist/permissions/index.d.mts +3 -3
- package/dist/plugins/index.d.mts +5 -5
- package/dist/plugins/index.mjs +8 -8
- package/dist/plugins/tracing-entry.d.mts +1 -1
- package/dist/plugins/tracing-entry.mjs +1 -1
- package/dist/policies/index.d.mts +1 -1
- package/dist/presets/index.d.mts +3 -3
- package/dist/presets/index.mjs +1 -1
- package/dist/presets/multiTenant.d.mts +1 -1
- package/dist/{presets-BFrGvvjL.mjs → presets-C2xgzW6x.mjs} +10 -18
- package/dist/{queryCachePlugin-BCFVXnxK.d.mts → queryCachePlugin-CnTZZTC5.d.mts} +1 -1
- package/dist/{redis-stream-CF1lrKVk.d.mts → redis-stream-D54N5oXs.d.mts} +1 -1
- package/dist/{redis-Bunu3qWg.d.mts → redis-z3sFr1UP.d.mts} +1 -1
- package/dist/registry/index.d.mts +1 -1
- package/dist/registry/index.mjs +1 -1
- package/dist/{resourceToTools-C_1SMiCz.mjs → resourceToTools-O_HwWXFa.mjs} +194 -64
- package/dist/rpc/index.d.mts +1 -1
- package/dist/rpc/index.mjs +1 -1
- package/dist/scope/index.d.mts +2 -2
- package/dist/testing/index.d.mts +2 -2
- package/dist/testing/index.mjs +1 -1
- package/dist/types/index.d.mts +5 -5
- package/dist/{types-gUxAIZHp.d.mts → types-Bg2X42_m.d.mts} +30 -9
- package/dist/{types-BoaZHr-2.d.mts → types-CVC4HOKi.d.mts} +1 -1
- package/dist/{types-Ct0PUUSp.d.mts → types-CcG4avic.d.mts} +1 -1
- package/dist/utils/index.d.mts +43 -17
- package/dist/utils/index.mjs +5 -5
- package/dist/{utils-B-l6410F.mjs → utils-yYT3HDXt.mjs} +65 -13
- package/package.json +10 -9
- package/skills/arc/SKILL.md +79 -6
- /package/dist/{caching-CHH-iHs3.mjs → caching-CjybdRwx.mjs} +0 -0
- /package/dist/{circuitBreaker-BGVoB1hD.d.mts → circuitBreaker-CvXkjfrW.d.mts} +0 -0
- /package/dist/{circuitBreaker-l18oRgL5.mjs → circuitBreaker-cmi5XDv5.mjs} +0 -0
- /package/dist/{elevation-UJO3-NvX.d.mts → elevation-s5ykdNHr.d.mts} +0 -0
- /package/dist/{errors-Cg58SLNi.mjs → errors-BF2bIOIS.mjs} +0 -0
- /package/dist/{errors-BI8kEKsO.d.mts → errors-Bmn3eZT6.d.mts} +0 -0
- /package/dist/{externalPaths-BQ8QijNH.d.mts → externalPaths-Bapitwvd.d.mts} +0 -0
- /package/dist/{fields-DoeDgh2b.d.mts → fields-DC4So2M2.d.mts} +0 -0
- /package/dist/{interface-CkkWm5uR.d.mts → interface-B-pe8fhj.d.mts} +0 -0
- /package/dist/{interface-bpoLKKqx.d.mts → interface-DplgQO2e.d.mts} +0 -0
- /package/dist/{metrics-DuhiSEZI.mjs → metrics-TuOmguhi.mjs} +0 -0
- /package/dist/{mongodb-5Ff3w8jy.mjs → mongodb-B5O6xaW1.mjs} +0 -0
- /package/dist/{pluralize-BneOJkpi.mjs → pluralize-A0tWEl1K.mjs} +0 -0
- /package/dist/{replyHelpers-CXtJDAZ0.mjs → replyHelpers-BLojtuvR.mjs} +0 -0
- /package/dist/{requestContext-xHIKedG6.mjs → requestContext-DYvHl113.mjs} +0 -0
- /package/dist/{schemaConverter-Y5EejTnJ.mjs → schemaConverter-OxfCshus.mjs} +0 -0
- /package/dist/{sessionManager-BkzVU8h2.d.mts → sessionManager-D-oNWHz3.d.mts} +0 -0
- /package/dist/{sse-CD5Hghpu.mjs → sse-CJpt7LGI.mjs} +0 -0
- /package/dist/{tracing-xqXzWeaf.d.mts → tracing-DxjKk7eW.d.mts} +0 -0
- /package/dist/{types-CN6JvmYz.d.mts → types-C72d3NDn.d.mts} +0 -0
- /package/dist/{versioning-CPU_5Xfs.mjs → versioning-Cm8qoFDg.mjs} +0 -0
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
|
|
2
2
|
import { n as normalizePermissionResult, t as applyPermissionResult } from "./applyPermissionResult-D6GPMsvh.mjs";
|
|
3
|
+
import { a as toJsonSchema } from "./schemaConverter-OxfCshus.mjs";
|
|
3
4
|
//#region src/core/createActionRouter.ts
|
|
4
|
-
var createActionRouter_exports = /* @__PURE__ */ __exportAll({
|
|
5
|
+
var createActionRouter_exports = /* @__PURE__ */ __exportAll({
|
|
6
|
+
buildActionBodySchema: () => buildActionBodySchema,
|
|
7
|
+
createActionRouter: () => createActionRouter
|
|
8
|
+
});
|
|
5
9
|
/**
|
|
6
10
|
* Create action-based state transition endpoint
|
|
7
11
|
*
|
|
@@ -18,20 +22,7 @@ function createActionRouter(fastify, config) {
|
|
|
18
22
|
fastify.log.warn("[createActionRouter] No actions defined, skipping route creation");
|
|
19
23
|
return;
|
|
20
24
|
}
|
|
21
|
-
const
|
|
22
|
-
type: "string",
|
|
23
|
-
enum: actionEnum,
|
|
24
|
-
description: `Action to perform: ${actionEnum.join(" | ")}`
|
|
25
|
-
} };
|
|
26
|
-
Object.entries(actionSchemas).forEach(([actionName, schema]) => {
|
|
27
|
-
if (schema && typeof schema === "object") Object.entries(schema).forEach(([propName, propSchema]) => {
|
|
28
|
-
const schemaObj = propSchema;
|
|
29
|
-
bodyProperties[propName] = {
|
|
30
|
-
...schemaObj,
|
|
31
|
-
description: `${schemaObj.description || ""} (for ${actionName} action)`.trim()
|
|
32
|
-
};
|
|
33
|
-
});
|
|
34
|
-
});
|
|
25
|
+
const bodySchema = buildActionBodySchema(actionEnum, actionSchemas);
|
|
35
26
|
const routeSchema = {
|
|
36
27
|
tags: tag ? [tag] : void 0,
|
|
37
28
|
summary: `Perform action (${actionEnum.join("/")})`,
|
|
@@ -44,11 +35,7 @@ function createActionRouter(fastify, config) {
|
|
|
44
35
|
} },
|
|
45
36
|
required: ["id"]
|
|
46
37
|
},
|
|
47
|
-
body:
|
|
48
|
-
type: "object",
|
|
49
|
-
properties: bodyProperties,
|
|
50
|
-
required: ["action"]
|
|
51
|
-
}
|
|
38
|
+
body: bodySchema
|
|
52
39
|
};
|
|
53
40
|
const preHandler = [];
|
|
54
41
|
const hasPublicActions = Object.entries(actionPermissions).some(([, p]) => p?._isPublic) || globalAuth && globalAuth?._isPublic;
|
|
@@ -167,6 +154,85 @@ function createActionRouter(fastify, config) {
|
|
|
167
154
|
}, "[createActionRouter] Registered action endpoint: POST /:id/action");
|
|
168
155
|
}
|
|
169
156
|
/**
|
|
157
|
+
* Build a discriminated body schema for the unified action endpoint.
|
|
158
|
+
*
|
|
159
|
+
* Produces a schema of the form:
|
|
160
|
+
* ```json
|
|
161
|
+
* {
|
|
162
|
+
* "type": "object",
|
|
163
|
+
* "required": ["action"],
|
|
164
|
+
* "oneOf": [
|
|
165
|
+
* { "properties": { "action": { "const": "dispatch" }, "carrier": {...} }, "required": ["action", "carrier"] },
|
|
166
|
+
* { "properties": { "action": { "const": "approve" } }, "required": ["action"] }
|
|
167
|
+
* ]
|
|
168
|
+
* }
|
|
169
|
+
* ```
|
|
170
|
+
*
|
|
171
|
+
* AJV validates this natively, so an action call missing required fields is
|
|
172
|
+
* rejected with HTTP 400 before the handler ever runs.
|
|
173
|
+
*
|
|
174
|
+
* Exported so OpenAPI generation and MCP tool generation can reuse the same
|
|
175
|
+
* schema shape (single source of truth).
|
|
176
|
+
*/
|
|
177
|
+
function buildActionBodySchema(actionEnum, actionSchemas = {}) {
|
|
178
|
+
const branches = [];
|
|
179
|
+
for (const actionName of actionEnum) {
|
|
180
|
+
const raw = actionSchemas[actionName];
|
|
181
|
+
const { properties, required } = normalizeActionSchema(raw);
|
|
182
|
+
const branchProperties = {
|
|
183
|
+
action: {
|
|
184
|
+
type: "string",
|
|
185
|
+
const: actionName
|
|
186
|
+
},
|
|
187
|
+
...properties
|
|
188
|
+
};
|
|
189
|
+
const branchRequired = ["action", ...required.filter((r) => r !== "action")];
|
|
190
|
+
branches.push({
|
|
191
|
+
type: "object",
|
|
192
|
+
properties: branchProperties,
|
|
193
|
+
required: branchRequired
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
return {
|
|
197
|
+
type: "object",
|
|
198
|
+
required: ["action"],
|
|
199
|
+
oneOf: branches
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Normalize the accepted schema shapes into `{ properties, required }`.
|
|
204
|
+
*
|
|
205
|
+
* Handles:
|
|
206
|
+
* 1. Full JSON Schema object (has `type: 'object'` + `properties`)
|
|
207
|
+
* 2. Zod v4 schema (has `_zod` marker) — converted via `toJsonSchema`
|
|
208
|
+
* 3. Legacy field map (`{ fieldName: { type: 'string' } }`) — every field required
|
|
209
|
+
* unless its schema has `nullable: true` or sentinel `required: false`
|
|
210
|
+
*/
|
|
211
|
+
function normalizeActionSchema(raw) {
|
|
212
|
+
if (!raw || typeof raw !== "object") return {
|
|
213
|
+
properties: {},
|
|
214
|
+
required: []
|
|
215
|
+
};
|
|
216
|
+
const converted = toJsonSchema(raw);
|
|
217
|
+
if (converted && typeof converted === "object" && (converted.type === "object" || "properties" in converted)) return {
|
|
218
|
+
properties: converted.properties ?? {},
|
|
219
|
+
required: Array.isArray(converted.required) ? converted.required : []
|
|
220
|
+
};
|
|
221
|
+
const properties = {};
|
|
222
|
+
const required = [];
|
|
223
|
+
for (const [fieldName, fieldSchema] of Object.entries(raw)) {
|
|
224
|
+
if (fieldName === "type" || fieldName === "properties" || fieldName === "required") continue;
|
|
225
|
+
if (!fieldSchema || typeof fieldSchema !== "object") continue;
|
|
226
|
+
const fs = fieldSchema;
|
|
227
|
+
properties[fieldName] = fs;
|
|
228
|
+
if (fs.required !== false) required.push(fieldName);
|
|
229
|
+
}
|
|
230
|
+
return {
|
|
231
|
+
properties,
|
|
232
|
+
required
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
170
236
|
* Build description with action details
|
|
171
237
|
* Uses _roles metadata from PermissionCheck functions for OpenAPI docs
|
|
172
238
|
*/
|
|
@@ -180,4 +246,4 @@ function buildActionDescription(actions, actionPermissions) {
|
|
|
180
246
|
return lines.join("\n");
|
|
181
247
|
}
|
|
182
248
|
//#endregion
|
|
183
|
-
export {
|
|
249
|
+
export { createActionRouter as n, createActionRouter_exports as r, buildActionBodySchema as t };
|
|
@@ -207,7 +207,7 @@ async function registerArcCore(fastify, config, trackPlugin) {
|
|
|
207
207
|
await fastify.register(arcCorePlugin, { emitEvents: config.arcPlugins?.emitEvents !== false });
|
|
208
208
|
trackPlugin("arc-core");
|
|
209
209
|
if (config.arcPlugins?.events !== false) {
|
|
210
|
-
const { default: eventPlugin } = await import("./eventPlugin-
|
|
210
|
+
const { default: eventPlugin } = await import("./eventPlugin-D91S2YF4.mjs").then((n) => n.n);
|
|
211
211
|
const eventOpts = typeof config.arcPlugins?.events === "object" ? config.arcPlugins.events : {};
|
|
212
212
|
await fastify.register(eventPlugin, {
|
|
213
213
|
...eventOpts,
|
|
@@ -243,7 +243,7 @@ async function registerArcPlugins(fastify, config, trackPlugin, modules) {
|
|
|
243
243
|
trackPlugin("arc-graceful-shutdown");
|
|
244
244
|
}
|
|
245
245
|
if (config.arcPlugins?.caching) {
|
|
246
|
-
const { default: cachingPlugin } = await import("./caching-
|
|
246
|
+
const { default: cachingPlugin } = await import("./caching-CjybdRwx.mjs").then((n) => n.r);
|
|
247
247
|
const opts = config.arcPlugins.caching === true ? {} : config.arcPlugins.caching;
|
|
248
248
|
await fastify.register(cachingPlugin, opts);
|
|
249
249
|
trackPlugin("arc-caching", opts);
|
|
@@ -260,19 +260,19 @@ async function registerArcPlugins(fastify, config, trackPlugin, modules) {
|
|
|
260
260
|
}
|
|
261
261
|
if (config.arcPlugins?.sse) if (config.arcPlugins?.events === false) fastify.log.warn("SSE plugin requires events plugin (arcPlugins.events). SSE disabled.");
|
|
262
262
|
else {
|
|
263
|
-
const { default: ssePlugin } = await import("./sse-
|
|
263
|
+
const { default: ssePlugin } = await import("./sse-CJpt7LGI.mjs").then((n) => n.r);
|
|
264
264
|
const opts = config.arcPlugins.sse === true ? {} : config.arcPlugins.sse;
|
|
265
265
|
await fastify.register(ssePlugin, opts);
|
|
266
266
|
trackPlugin("arc-sse", opts);
|
|
267
267
|
}
|
|
268
268
|
if (config.arcPlugins?.metrics) {
|
|
269
|
-
const { default: metricsPlugin } = await import("./metrics-
|
|
269
|
+
const { default: metricsPlugin } = await import("./metrics-TuOmguhi.mjs").then((n) => n.r);
|
|
270
270
|
const opts = config.arcPlugins.metrics === true ? {} : config.arcPlugins.metrics;
|
|
271
271
|
await fastify.register(metricsPlugin, opts);
|
|
272
272
|
trackPlugin("arc-metrics", opts);
|
|
273
273
|
}
|
|
274
274
|
if (config.arcPlugins?.versioning) {
|
|
275
|
-
const { default: versioningPlugin } = await import("./versioning-
|
|
275
|
+
const { default: versioningPlugin } = await import("./versioning-Cm8qoFDg.mjs").then((n) => n.r);
|
|
276
276
|
await fastify.register(versioningPlugin, config.arcPlugins.versioning);
|
|
277
277
|
trackPlugin("arc-versioning", config.arcPlugins.versioning);
|
|
278
278
|
}
|
|
@@ -350,7 +350,7 @@ async function registerElevation(fastify, config, trackPlugin) {
|
|
|
350
350
|
*/
|
|
351
351
|
async function registerErrorHandler(fastify, config, trackPlugin) {
|
|
352
352
|
if (config.errorHandler === false) return;
|
|
353
|
-
const { errorHandlerPlugin } = await import("./errorHandler-
|
|
353
|
+
const { errorHandlerPlugin } = await import("./errorHandler-mzqk4cGl.mjs").then((n) => n.n);
|
|
354
354
|
const errorOpts = typeof config.errorHandler === "object" ? config.errorHandler : { includeStack: config.preset !== "production" };
|
|
355
355
|
await fastify.register(errorHandlerPlugin, errorOpts);
|
|
356
356
|
trackPlugin("arc-error-handler", errorOpts);
|
|
@@ -416,6 +416,15 @@ async function registerResources(fastify, config) {
|
|
|
416
416
|
for (const init of config.bootstrap) await init(fastify);
|
|
417
417
|
fastify.log.debug(`${config.bootstrap.length} bootstrap function(s) executed`);
|
|
418
418
|
}
|
|
419
|
+
if (!config.resources?.length && config.resourceDir) {
|
|
420
|
+
const { loadResources } = await import("./loadResources-Bksk8ydA.mjs").then((n) => n.n);
|
|
421
|
+
const { resolve } = await import("node:path");
|
|
422
|
+
const dir = resolve(config.resourceDir);
|
|
423
|
+
config = {
|
|
424
|
+
...config,
|
|
425
|
+
resources: await loadResources(dir, { logger: fastify.log })
|
|
426
|
+
};
|
|
427
|
+
}
|
|
419
428
|
if (config.resources?.length) {
|
|
420
429
|
const seen = /* @__PURE__ */ new Set();
|
|
421
430
|
for (const resource of config.resources) if (resource.name) {
|
|
@@ -720,7 +729,7 @@ async function createApp(options) {
|
|
|
720
729
|
await registerErrorHandler(fastify, config, trackPlugin);
|
|
721
730
|
await registerResources(fastify, config);
|
|
722
731
|
if (config.replyHelpers) {
|
|
723
|
-
const { replyHelpersPlugin } = await import("./replyHelpers-
|
|
732
|
+
const { replyHelpersPlugin } = await import("./replyHelpers-BLojtuvR.mjs").then((n) => n.n);
|
|
724
733
|
await fastify.register(replyHelpersPlugin);
|
|
725
734
|
}
|
|
726
735
|
if (config.serializeBigInt) fastify.addHook("preSerialization", async (_request, _reply, payload) => {
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS } from "./constants-Cxde4rpC.mjs";
|
|
2
2
|
import { _ as isElevated, n as PUBLIC_SCOPE, v as isMember } from "./types-AOD8fxIw.mjs";
|
|
3
|
-
import { t as BaseController } from "./BaseController-
|
|
3
|
+
import { t as BaseController } from "./BaseController-DAGGc5Xn.mjs";
|
|
4
4
|
import { i as resolveEffectiveRoles, t as applyFieldReadPermissions } from "./fields-ipsbIRPK.mjs";
|
|
5
5
|
import { t as getUserRoles } from "./types-ZUu_h0jp.mjs";
|
|
6
6
|
import { n as normalizePermissionResult, t as applyPermissionResult } from "./applyPermissionResult-D6GPMsvh.mjs";
|
|
7
|
-
import { t as
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
7
|
+
import { n as convertRouteSchema, t as convertOpenApiSchemas } from "./schemaConverter-OxfCshus.mjs";
|
|
8
|
+
import { t as requestContext } from "./requestContext-DYvHl113.mjs";
|
|
9
|
+
import { i as getDefaultCrudSchemas } from "./utils-yYT3HDXt.mjs";
|
|
10
|
+
import { r as ForbiddenError } from "./errors-BF2bIOIS.mjs";
|
|
11
11
|
import { t as hasEvents } from "./typeGuards-CcFZXgU7.mjs";
|
|
12
|
-
import { r as getAvailablePresets, t as applyPresets } from "./presets-
|
|
12
|
+
import { r as getAvailablePresets, t as applyPresets } from "./presets-C2xgzW6x.mjs";
|
|
13
13
|
//#region src/pipeline/pipe.ts
|
|
14
14
|
/**
|
|
15
15
|
* Compose pipeline steps into an ordered array.
|
|
@@ -390,7 +390,7 @@ function buildPermissionMiddleware(permissionCheck, resourceName, action) {
|
|
|
390
390
|
* Create additional routes from preset/custom definitions
|
|
391
391
|
*/
|
|
392
392
|
function createAdditionalRoutes(fastify, routes, controller, options) {
|
|
393
|
-
const { tag, resourceName, arcDecorator, rateLimitConfig, cacheMw, idempotencyMw, pipeline } = options;
|
|
393
|
+
const { tag, resourceName, arcDecorator, rateLimitConfig, cacheMw, idempotencyMw, pipeline, routeGuards } = options;
|
|
394
394
|
for (const route of routes) {
|
|
395
395
|
const opName = route.operation ?? (typeof route.handler === "string" ? route.handler : `${route.method.toLowerCase()}${route.path.replace(/[/:]/g, "_")}`);
|
|
396
396
|
let handler;
|
|
@@ -431,6 +431,7 @@ function createAdditionalRoutes(fastify, routes, controller, options) {
|
|
|
431
431
|
authMw,
|
|
432
432
|
permissionMw,
|
|
433
433
|
pluginMw,
|
|
434
|
+
...routeGuards,
|
|
434
435
|
...customPreHandlers
|
|
435
436
|
].filter(Boolean);
|
|
436
437
|
const isStream = route.streamResponse === true;
|
|
@@ -479,7 +480,7 @@ function createPipelineHandler(controllerMethod, steps, operation, resourceName)
|
|
|
479
480
|
* @param options - Router configuration
|
|
480
481
|
*/
|
|
481
482
|
function createCrudRouter(fastify, controller, options = {}) {
|
|
482
|
-
const { tag = "Resource", schemas = {}, permissions = {}, middlewares = {}, additionalRoutes = [], disableDefaultRoutes = false, disabledRoutes = [], resourceName = "unknown", schemaOptions, rateLimit, pipe: pipeline, fields: fieldPermissions, updateMethod = DEFAULT_UPDATE_METHOD } = options;
|
|
483
|
+
const { tag = "Resource", schemas = {}, permissions = {}, middlewares = {}, routeGuards = [], additionalRoutes = [], disableDefaultRoutes = false, disabledRoutes = [], resourceName = "unknown", schemaOptions, rateLimit, pipe: pipeline, fields: fieldPermissions, updateMethod = DEFAULT_UPDATE_METHOD } = options;
|
|
483
484
|
const rateLimitConfig = buildRateLimitConfig(rateLimit);
|
|
484
485
|
const cacheMw = !(fastify.hasDecorator("queryCache") && controller && typeof controller._cacheConfig !== "undefined" && controller._cacheConfig !== void 0) && fastify.hasDecorator("responseCache") ? fastify.responseCache.middleware : null;
|
|
485
486
|
const idempotencyMw = fastify.hasDecorator("idempotency") ? fastify.idempotency.middleware : null;
|
|
@@ -542,6 +543,7 @@ function createCrudRouter(fastify, controller, options = {}) {
|
|
|
542
543
|
buildAuthMiddleware(fastify, permissions.list),
|
|
543
544
|
buildPermissionMiddleware(permissions.list, resourceName, "list"),
|
|
544
545
|
cacheMw,
|
|
546
|
+
...routeGuards,
|
|
545
547
|
...mw.list
|
|
546
548
|
].filter(Boolean);
|
|
547
549
|
fastify.route({
|
|
@@ -562,6 +564,7 @@ function createCrudRouter(fastify, controller, options = {}) {
|
|
|
562
564
|
buildAuthMiddleware(fastify, permissions.get),
|
|
563
565
|
buildPermissionMiddleware(permissions.get, resourceName, "get"),
|
|
564
566
|
cacheMw,
|
|
567
|
+
...routeGuards,
|
|
565
568
|
...mw.get
|
|
566
569
|
].filter(Boolean);
|
|
567
570
|
fastify.route({
|
|
@@ -583,6 +586,7 @@ function createCrudRouter(fastify, controller, options = {}) {
|
|
|
583
586
|
buildAuthMiddleware(fastify, permissions.create),
|
|
584
587
|
buildPermissionMiddleware(permissions.create, resourceName, "create"),
|
|
585
588
|
idempotencyMw,
|
|
589
|
+
...routeGuards,
|
|
586
590
|
...mw.create
|
|
587
591
|
].filter(Boolean);
|
|
588
592
|
fastify.route({
|
|
@@ -604,6 +608,7 @@ function createCrudRouter(fastify, controller, options = {}) {
|
|
|
604
608
|
buildAuthMiddleware(fastify, permissions.update),
|
|
605
609
|
buildPermissionMiddleware(permissions.update, resourceName, "update"),
|
|
606
610
|
idempotencyMw,
|
|
611
|
+
...routeGuards,
|
|
607
612
|
...mw.update
|
|
608
613
|
].filter(Boolean);
|
|
609
614
|
for (const method of updateMethods) fastify.route({
|
|
@@ -624,6 +629,7 @@ function createCrudRouter(fastify, controller, options = {}) {
|
|
|
624
629
|
arcDecorator,
|
|
625
630
|
buildAuthMiddleware(fastify, permissions.delete),
|
|
626
631
|
buildPermissionMiddleware(permissions.delete, resourceName, "delete"),
|
|
632
|
+
...routeGuards,
|
|
627
633
|
...mw.delete
|
|
628
634
|
].filter(Boolean);
|
|
629
635
|
fastify.route({
|
|
@@ -647,7 +653,8 @@ function createCrudRouter(fastify, controller, options = {}) {
|
|
|
647
653
|
rateLimitConfig,
|
|
648
654
|
cacheMw,
|
|
649
655
|
idempotencyMw,
|
|
650
|
-
pipeline
|
|
656
|
+
pipeline,
|
|
657
|
+
routeGuards
|
|
651
658
|
});
|
|
652
659
|
}
|
|
653
660
|
/**
|
|
@@ -701,10 +708,10 @@ function validateResourceConfig(config, options = {}) {
|
|
|
701
708
|
message: "Adapter must provide a repository",
|
|
702
709
|
suggestion: "Ensure your adapter returns a valid CrudRepository"
|
|
703
710
|
});
|
|
704
|
-
} else if (!config.adapter && !config.
|
|
711
|
+
} else if (!config.adapter && !config.routes?.length) warnings.push({
|
|
705
712
|
field: "config",
|
|
706
|
-
message: "Resource has no adapter and no
|
|
707
|
-
suggestion: "Provide either adapter for CRUD or
|
|
713
|
+
message: "Resource has no adapter and no routes",
|
|
714
|
+
suggestion: "Provide either adapter for CRUD or routes for custom logic"
|
|
708
715
|
});
|
|
709
716
|
if (config.controller && !options.skipControllerCheck && !config.disableDefaultRoutes) {
|
|
710
717
|
const ctrl = config.controller;
|
|
@@ -715,7 +722,7 @@ function validateResourceConfig(config, options = {}) {
|
|
|
715
722
|
suggestion: "Extend BaseController which implements IController interface"
|
|
716
723
|
});
|
|
717
724
|
}
|
|
718
|
-
if (config.controller && config.
|
|
725
|
+
if (config.controller && config.routes) validateRouteHandlers(config.controller, config.routes, errors);
|
|
719
726
|
if (config.permissions) validatePermissionKeys(config, options, errors, warnings);
|
|
720
727
|
if (config.presets && !options.allowUnknownPresets) validatePresets(config.presets, errors, warnings);
|
|
721
728
|
if (config.prefix) {
|
|
@@ -730,18 +737,18 @@ function validateResourceConfig(config, options = {}) {
|
|
|
730
737
|
suggestion: `Change to "${config.prefix.slice(0, -1)}"`
|
|
731
738
|
});
|
|
732
739
|
}
|
|
733
|
-
if (config.
|
|
740
|
+
if (config.routes) validateRoutes(config.routes, errors);
|
|
734
741
|
return {
|
|
735
742
|
valid: errors.length === 0,
|
|
736
743
|
errors,
|
|
737
744
|
warnings
|
|
738
745
|
};
|
|
739
746
|
}
|
|
740
|
-
function
|
|
747
|
+
function validateRouteHandlers(controller, routes, errors) {
|
|
741
748
|
const ctrl = controller;
|
|
742
749
|
for (const route of routes) if (typeof route.handler === "string") {
|
|
743
750
|
if (typeof ctrl[route.handler] !== "function") errors.push({
|
|
744
|
-
field: `
|
|
751
|
+
field: `routes[${route.method} ${route.path}]`,
|
|
745
752
|
message: `Handler "${route.handler}" not found on controller`,
|
|
746
753
|
suggestion: `Add method "${route.handler}" to controller or use a function handler`
|
|
747
754
|
});
|
|
@@ -749,7 +756,7 @@ function validateAdditionalRouteHandlers(controller, routes, errors) {
|
|
|
749
756
|
}
|
|
750
757
|
function validatePermissionKeys(config, options, _errors, warnings) {
|
|
751
758
|
const validKeys = new Set([...CRUD_OPERATIONS, ...options.additionalPermissionKeys ?? []]);
|
|
752
|
-
for (const route of config.
|
|
759
|
+
for (const route of config.routes ?? []) if (typeof route.handler === "string") validKeys.add(route.handler);
|
|
753
760
|
for (const preset of config.presets ?? []) {
|
|
754
761
|
const presetName = typeof preset === "string" ? preset : preset.name;
|
|
755
762
|
if (presetName === "softDelete") {
|
|
@@ -773,7 +780,7 @@ function validatePermissionKeys(config, options, _errors, warnings) {
|
|
|
773
780
|
function validatePresets(presets, errors, warnings) {
|
|
774
781
|
const availablePresets = getAvailablePresets();
|
|
775
782
|
for (const preset of presets) {
|
|
776
|
-
if (typeof preset === "object" && ("middlewares" in preset || "
|
|
783
|
+
if (typeof preset === "object" && ("middlewares" in preset || "routes" in preset)) continue;
|
|
777
784
|
const presetName = typeof preset === "string" ? preset : preset.name;
|
|
778
785
|
if (!availablePresets.includes(presetName)) errors.push({
|
|
779
786
|
field: "presets",
|
|
@@ -798,7 +805,7 @@ function validatePresetOptions(preset, warnings) {
|
|
|
798
805
|
suggestion: validOptions.length > 0 ? `Valid options: ${validOptions.join(", ")}` : `Preset "${preset.name}" has no configurable options`
|
|
799
806
|
});
|
|
800
807
|
}
|
|
801
|
-
function
|
|
808
|
+
function validateRoutes(routes, errors) {
|
|
802
809
|
const validMethods = [
|
|
803
810
|
"GET",
|
|
804
811
|
"POST",
|
|
@@ -811,26 +818,26 @@ function validateAdditionalRoutes(routes, errors) {
|
|
|
811
818
|
const seenRoutes = /* @__PURE__ */ new Set();
|
|
812
819
|
for (const [i, route] of routes.entries()) {
|
|
813
820
|
if (!validMethods.includes(route.method)) errors.push({
|
|
814
|
-
field: `
|
|
821
|
+
field: `routes[${i}].method`,
|
|
815
822
|
message: `Invalid HTTP method "${route.method}"`,
|
|
816
823
|
suggestion: `Valid methods: ${validMethods.join(", ")}`
|
|
817
824
|
});
|
|
818
825
|
if (!route.path) errors.push({
|
|
819
|
-
field: `
|
|
826
|
+
field: `routes[${i}].path`,
|
|
820
827
|
message: "Route path is required"
|
|
821
828
|
});
|
|
822
829
|
else if (!route.path.startsWith("/")) errors.push({
|
|
823
|
-
field: `
|
|
830
|
+
field: `routes[${i}].path`,
|
|
824
831
|
message: `Route path must start with "/" (got "${route.path}")`,
|
|
825
832
|
suggestion: `Change to "/${route.path}"`
|
|
826
833
|
});
|
|
827
834
|
if (!route.handler) errors.push({
|
|
828
|
-
field: `
|
|
835
|
+
field: `routes[${i}].handler`,
|
|
829
836
|
message: "Route handler is required"
|
|
830
837
|
});
|
|
831
838
|
const routeKey = `${route.method} ${route.path}`;
|
|
832
839
|
if (seenRoutes.has(routeKey)) errors.push({
|
|
833
|
-
field: `
|
|
840
|
+
field: `routes[${i}]`,
|
|
834
841
|
message: `Duplicate route "${routeKey}"`
|
|
835
842
|
});
|
|
836
843
|
seenRoutes.add(routeKey);
|
|
@@ -884,11 +891,6 @@ function defineResource(config) {
|
|
|
884
891
|
if (config.permissions) {
|
|
885
892
|
for (const [key, value] of Object.entries(config.permissions)) if (value !== void 0 && typeof value !== "function") throw new Error(`[Arc] Resource '${config.name}': permissions.${key} must be a PermissionCheck function.\nUse allowPublic(), requireAuth(), or requireRoles(['role']) from @classytic/arc/permissions.`);
|
|
886
893
|
}
|
|
887
|
-
for (const route of config.additionalRoutes ?? []) {
|
|
888
|
-
if (typeof route.permissions !== "function") throw new Error(`[Arc] Resource '${config.name}' route ${route.method} ${route.path}: permissions is required and must be a PermissionCheck function.\nUse allowPublic() or requireAuth() from @classytic/arc/permissions.`);
|
|
889
|
-
if (typeof route.wrapHandler !== "boolean") throw new Error(`[Arc] Resource '${config.name}' route ${route.method} ${route.path}: wrapHandler is required.\nSet true for ControllerHandler (context object) or false for FastifyHandler (req, reply).`);
|
|
890
|
-
}
|
|
891
|
-
if (config.routes && config.additionalRoutes) throw new Error(`[Arc] Resource '${config.name}': Cannot use both 'routes' and 'additionalRoutes'.\nUse 'routes' (v2.8) — it replaces 'additionalRoutes'.`);
|
|
892
894
|
for (const route of config.routes ?? []) if (typeof route.permissions !== "function") throw new Error(`[Arc] Resource '${config.name}' route ${route.method} ${route.path}: permissions is required and must be a PermissionCheck function.`);
|
|
893
895
|
if (config.actions) {
|
|
894
896
|
const CRUD_OPS = new Set([
|
|
@@ -1087,7 +1089,18 @@ var ResourceDefinition = class {
|
|
|
1087
1089
|
customSchemas;
|
|
1088
1090
|
permissions;
|
|
1089
1091
|
additionalRoutes;
|
|
1092
|
+
/**
|
|
1093
|
+
* Original v2.8 `routes` declaration — retained for downstream consumers
|
|
1094
|
+
* (OpenAPI, MCP, registry, CLI introspect). Preserves fields dropped during
|
|
1095
|
+
* normalization to `additionalRoutes` (notably `mcp`, `description`,
|
|
1096
|
+
* `annotations`). Undefined when the resource was defined with the legacy
|
|
1097
|
+
* `additionalRoutes` shape.
|
|
1098
|
+
*
|
|
1099
|
+
* Added in 2.8.1 — the source-of-truth fix for "canonical resource manifest".
|
|
1100
|
+
*/
|
|
1101
|
+
routes;
|
|
1090
1102
|
middlewares;
|
|
1103
|
+
routeGuards;
|
|
1091
1104
|
disableDefaultRoutes;
|
|
1092
1105
|
disabledRoutes;
|
|
1093
1106
|
actions;
|
|
@@ -1117,8 +1130,10 @@ var ResourceDefinition = class {
|
|
|
1117
1130
|
this.schemaOptions = config.schemaOptions ?? {};
|
|
1118
1131
|
this.customSchemas = config.customSchemas ?? {};
|
|
1119
1132
|
this.permissions = config.permissions ?? {};
|
|
1120
|
-
this.
|
|
1133
|
+
this.routes = config.routes;
|
|
1134
|
+
this.additionalRoutes = config.routes ? convertRoutesToAdditionalRoutes(config.routes) : [];
|
|
1121
1135
|
this.middlewares = config.middlewares ?? {};
|
|
1136
|
+
this.routeGuards = config.routeGuards;
|
|
1122
1137
|
this.disableDefaultRoutes = config.disableDefaultRoutes ?? false;
|
|
1123
1138
|
this.disabledRoutes = config.disabledRoutes ?? [];
|
|
1124
1139
|
this.actions = config.actions;
|
|
@@ -1272,6 +1287,7 @@ var ResourceDefinition = class {
|
|
|
1272
1287
|
schemas: schemas ?? void 0,
|
|
1273
1288
|
permissions: self.permissions,
|
|
1274
1289
|
middlewares: self.middlewares,
|
|
1290
|
+
routeGuards: self.routeGuards,
|
|
1275
1291
|
additionalRoutes: resolvedRoutes,
|
|
1276
1292
|
disableDefaultRoutes: self.disableDefaultRoutes,
|
|
1277
1293
|
disabledRoutes: self.disabledRoutes,
|
|
@@ -1283,7 +1299,7 @@ var ResourceDefinition = class {
|
|
|
1283
1299
|
fields: self.fields
|
|
1284
1300
|
});
|
|
1285
1301
|
if (self.actions && Object.keys(self.actions).length > 0) {
|
|
1286
|
-
const { createActionRouter } = await import("./createActionRouter-
|
|
1302
|
+
const { createActionRouter } = await import("./createActionRouter-Df1BuawX.mjs").then((n) => n.r);
|
|
1287
1303
|
createActionRouter(instance, normalizeActionsToRouterConfig(self.actions, self.actionPermissions, self.tag));
|
|
1288
1304
|
}
|
|
1289
1305
|
if (self.events && Object.keys(self.events).length > 0) typedInstance.log?.debug?.(`Resource '${self.name}' defined ${Object.keys(self.events).length} events`);
|
|
@@ -1320,7 +1336,17 @@ var ResourceDefinition = class {
|
|
|
1320
1336
|
prefix: this.prefix,
|
|
1321
1337
|
presets: this._appliedPresets,
|
|
1322
1338
|
permissions: this.permissions,
|
|
1323
|
-
|
|
1339
|
+
customRoutes: (this.routes ?? []).map((r) => ({
|
|
1340
|
+
method: r.method,
|
|
1341
|
+
path: r.path,
|
|
1342
|
+
handler: typeof r.handler === "string" ? r.handler : r.handler.name || "anonymous",
|
|
1343
|
+
operation: r.operation,
|
|
1344
|
+
summary: r.summary,
|
|
1345
|
+
description: r.description,
|
|
1346
|
+
permissions: r.permissions,
|
|
1347
|
+
raw: r.raw,
|
|
1348
|
+
schema: r.schema
|
|
1349
|
+
})),
|
|
1324
1350
|
routes: [],
|
|
1325
1351
|
events: Object.keys(this.events)
|
|
1326
1352
|
};
|
|
@@ -1358,7 +1384,8 @@ function convertRoutesToAdditionalRoutes(routes) {
|
|
|
1358
1384
|
preAuth: route.preAuth,
|
|
1359
1385
|
streamResponse: route.streamResponse,
|
|
1360
1386
|
schema: route.schema,
|
|
1361
|
-
mcpHandler: route.mcpHandler
|
|
1387
|
+
mcpHandler: route.mcpHandler,
|
|
1388
|
+
mcp: route.mcp
|
|
1362
1389
|
}));
|
|
1363
1390
|
}
|
|
1364
1391
|
/**
|
package/dist/docs/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { it as RegistryEntry } from "../interface-
|
|
2
|
-
import { t as ExternalOpenApiPaths } from "../externalPaths-
|
|
1
|
+
import { it as RegistryEntry } from "../interface-BVuMfeVv.mjs";
|
|
2
|
+
import { t as ExternalOpenApiPaths } from "../externalPaths-Bapitwvd.mjs";
|
|
3
3
|
import { FastifyPluginAsync } from "fastify";
|
|
4
4
|
|
|
5
5
|
//#region src/docs/openapi.d.ts
|
package/dist/docs/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as getUserRoles } from "../types-ZUu_h0jp.mjs";
|
|
2
|
-
import { n as openApiPlugin, r as openapi_default, t as buildOpenApiSpec } from "../openapi-
|
|
2
|
+
import { n as openApiPlugin, r as openapi_default, t as buildOpenApiSpec } from "../openapi-CYCuekCn.mjs";
|
|
3
3
|
import fp from "fastify-plugin";
|
|
4
4
|
//#region src/docs/scalar.ts
|
|
5
5
|
const scalarPlugin = async (fastify, opts = {}) => {
|
package/dist/dynamic/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { qt as ResourceDefinition, r as DataAdapter } from "../interface-
|
|
2
|
-
import { t as PermissionCheck } from "../types-
|
|
1
|
+
import { qt as ResourceDefinition, r as DataAdapter } from "../interface-BVuMfeVv.mjs";
|
|
2
|
+
import { t as PermissionCheck } from "../types-CVC4HOKi.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/dynamic/ArcDynamicLoader.d.ts
|
|
5
5
|
interface ArcArchitectureSchema {
|
package/dist/dynamic/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as ArcQueryParser } from "../queryParser-CgCtsjti.mjs";
|
|
2
|
-
import { n as defineResource } from "../defineResource-
|
|
2
|
+
import { n as defineResource } from "../defineResource-Bb_Bdhtw.mjs";
|
|
3
3
|
import { C as publicRead, T as readOnly, b as fullPublic, v as adminOnly, w as publicReadAdminWrite, x as ownerWithAdminBypass, y as authenticated } from "../permissions-CH4cNwJi.mjs";
|
|
4
4
|
//#region src/dynamic/ArcDynamicLoader.ts
|
|
5
5
|
const VALID_FIELD_TYPES = new Set([
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as DomainEvent } from "./EventTransport-
|
|
1
|
+
import { t as DomainEvent } from "./EventTransport-CinyO7zQ.mjs";
|
|
2
2
|
import { FastifyInstance, FastifyPluginAsync, FastifyRequest } from "fastify";
|
|
3
3
|
|
|
4
4
|
//#region src/plugins/caching.d.ts
|
|
@@ -180,4 +180,4 @@ interface ErrorHandlerOptions {
|
|
|
180
180
|
declare function errorHandlerPluginFn(fastify: FastifyInstance, options?: ErrorHandlerOptions): Promise<void>;
|
|
181
181
|
declare const errorHandlerPlugin: typeof errorHandlerPluginFn;
|
|
182
182
|
//#endregion
|
|
183
|
-
export {
|
|
183
|
+
export { _default$3 as _, _default as a, MetricsCollector as c, metricsPlugin as d, SSEOptions as f, CachingRule as g, CachingOptions as h, VersioningOptions as i, MetricsOptions as l, ssePlugin as m, ErrorMapper as n, versioningPlugin as o, _default$2 as p, errorHandlerPlugin as r, MetricEntry as s, ErrorHandlerOptions as t, _default$1 as u, cachingPlugin as v };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
|
|
2
|
-
import { p as isArcError } from "./errors-
|
|
2
|
+
import { p as isArcError } from "./errors-BF2bIOIS.mjs";
|
|
3
3
|
import fp from "fastify-plugin";
|
|
4
4
|
//#region src/plugins/errorHandler.ts
|
|
5
5
|
var errorHandler_exports = /* @__PURE__ */ __exportAll({ errorHandlerPlugin: () => errorHandlerPlugin });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as EventTransport, n as EventHandler, r as EventLogger, t as DomainEvent } from "./EventTransport-
|
|
1
|
+
import { i as EventTransport, n as EventHandler, r as EventLogger, t as DomainEvent } from "./EventTransport-CinyO7zQ.mjs";
|
|
2
2
|
import { FastifyPluginAsync } from "fastify";
|
|
3
3
|
|
|
4
4
|
//#region src/events/defineEvent.d.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
|
|
2
|
-
import { t as requestContext } from "./requestContext-
|
|
2
|
+
import { t as requestContext } from "./requestContext-DYvHl113.mjs";
|
|
3
3
|
import fp from "fastify-plugin";
|
|
4
4
|
//#region src/events/EventTransport.ts
|
|
5
5
|
/**
|
|
@@ -33,6 +33,24 @@ var MemoryEventTransport = class {
|
|
|
33
33
|
this.logger.error(`[EventTransport] Handler error for ${event.type}:`, err);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Reference `publishMany` implementation — delegates to `publish()` in order.
|
|
38
|
+
*
|
|
39
|
+
* Production transports (Kafka, Redis pipeline, SQS batch) should override
|
|
40
|
+
* this with a single batched network call. Memory transport has nothing to
|
|
41
|
+
* batch, so we just loop — the loop still returns a proper result map so
|
|
42
|
+
* `EventOutbox.relay` can exercise the batched code path in tests.
|
|
43
|
+
*/
|
|
44
|
+
async publishMany(events) {
|
|
45
|
+
const results = /* @__PURE__ */ new Map();
|
|
46
|
+
for (const event of events) try {
|
|
47
|
+
await this.publish(event);
|
|
48
|
+
results.set(event.meta.id, null);
|
|
49
|
+
} catch (err) {
|
|
50
|
+
results.set(event.meta.id, err instanceof Error ? err : new Error(String(err)));
|
|
51
|
+
}
|
|
52
|
+
return results;
|
|
53
|
+
}
|
|
36
54
|
async subscribe(pattern, handler) {
|
|
37
55
|
if (!this.handlers.has(pattern)) this.handlers.set(pattern, /* @__PURE__ */ new Set());
|
|
38
56
|
this.handlers.get(pattern)?.add(handler);
|