@classytic/arc 2.18.4 → 2.18.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.
Files changed (158) hide show
  1. package/dist/{BaseController-B-uXzf6I.mjs → BaseController-Dy6EQHjM.mjs} +7 -7
  2. package/dist/{QueryCache-Dsyv2mLS.d.mts → QueryCache-TRfXau3W.d.mts} +1 -1
  3. package/dist/{ResourceRegistry-CWmOggxS.mjs → ResourceRegistry-5fKZwhK_.mjs} +1 -1
  4. package/dist/{pipeline-D4sqiokR.mjs → actionPermissions-h7DYDNMg.mjs} +28 -5
  5. package/dist/audit/index.d.mts +1 -1
  6. package/dist/auth/index.d.mts +4 -4
  7. package/dist/auth/index.mjs +252 -5
  8. package/dist/auth/redis-session.d.mts +1 -1
  9. package/dist/betterAuthOpenApi-CV1lxpRX.mjs +2 -0
  10. package/dist/{buildHandler-Cvrc2p7r.mjs → buildHandler-B0qvAguf.mjs} +1 -1
  11. package/dist/cache/index.d.mts +3 -3
  12. package/dist/cache/index.mjs +3 -3
  13. package/dist/{caching-C0DdKiYB.mjs → caching-_NJeDd1_.mjs} +1 -1
  14. package/dist/cli/commands/describe.d.mts +1 -1
  15. package/dist/cli/commands/describe.mjs +2 -2
  16. package/dist/cli/commands/docs.mjs +2 -2
  17. package/dist/cli/commands/generate.d.mts +2 -2
  18. package/dist/cli/commands/generate.mjs +1 -1
  19. package/dist/cli/commands/init.d.mts +2 -2
  20. package/dist/cli/commands/init.mjs +1 -1
  21. package/dist/cli/commands/introspect.mjs +1 -1
  22. package/dist/cli/index.d.mts +2 -2
  23. package/dist/cli/index.mjs +2 -2
  24. package/dist/context/index.mjs +1 -1
  25. package/dist/core/index.d.mts +3 -3
  26. package/dist/core/index.mjs +4 -4
  27. package/dist/{core-C88uIwd3.mjs → core-ZnQBa5rh.mjs} +55 -56
  28. package/dist/{createActionRouter-DGCCp-kP.mjs → createActionRouter-CagItpxI.mjs} +6 -7
  29. package/dist/{createAggregationRouter-Ca77b8iK.mjs → createAggregationRouter-DVKroXhC.mjs} +4 -4
  30. package/dist/{createApp-J1iPXY9p.mjs → createApp--703hQE1.mjs} +14 -14
  31. package/dist/docs/index.d.mts +2 -2
  32. package/dist/docs/index.mjs +2 -2
  33. package/dist/{elevation-BzhyVWfn.mjs → elevation-COpYKt2h.mjs} +2 -2
  34. package/dist/{errorHandler-Bua97SEt.mjs → errorHandler-Dxf6P_kV.mjs} +2 -2
  35. package/dist/{eventPlugin-Bw4bUDEO.mjs → eventPlugin-DJG2D7sy.mjs} +106 -5
  36. package/dist/{eventPlugin-C1W1CRbf.d.mts → eventPlugin-DbBFd3x_.d.mts} +1 -1
  37. package/dist/events/index.d.mts +3 -3
  38. package/dist/events/index.mjs +189 -5
  39. package/dist/events/transports/redis-stream-entry.d.mts +1 -1
  40. package/dist/events/transports/redis.d.mts +1 -1
  41. package/dist/factory/index.d.mts +1 -1
  42. package/dist/factory/index.mjs +3 -3
  43. package/dist/{fastify-augmentation-BdCl_eNo.d.mts → fastify-augmentation-Cxb0ROIw.d.mts} +2 -2
  44. package/dist/{fields-CKLrhyOb.d.mts → fields-C7ahdGYf.d.mts} +1 -1
  45. package/dist/{generate-BaxDdmJ8.mjs → generate-Brans3fW.mjs} +1 -1
  46. package/dist/hooks/index.d.mts +1 -1
  47. package/dist/hooks/index.mjs +1 -1
  48. package/dist/idempotency/index.d.mts +2 -2
  49. package/dist/idempotency/index.mjs +1 -1
  50. package/dist/idempotency/redis.d.mts +1 -1
  51. package/dist/{index-QYma8mdC.d.mts → index-CHNQIhcb.d.mts} +5 -6
  52. package/dist/{index-vcWUGkwf.d.mts → index-CRKiiP5o.d.mts} +3 -3
  53. package/dist/{index-Cvo1u9n6.d.mts → index-Dh0_RSTd.d.mts} +3 -3
  54. package/dist/index.d.mts +5 -5
  55. package/dist/index.mjs +7 -7
  56. package/dist/{init-DSsdRfk9.mjs → init-Bqpt1Hxf.mjs} +274 -130
  57. package/dist/integrations/event-gateway.d.mts +2 -2
  58. package/dist/integrations/event-gateway.mjs +1 -1
  59. package/dist/integrations/index.d.mts +3 -3
  60. package/dist/integrations/mcp/index.d.mts +4 -4
  61. package/dist/integrations/mcp/index.mjs +1 -1
  62. package/dist/integrations/mcp/testing.d.mts +1 -1
  63. package/dist/integrations/mcp/testing.mjs +1 -1
  64. package/dist/integrations/streamline.mjs +7 -3
  65. package/dist/integrations/websocket-pushref-redis.d.mts +1 -1
  66. package/dist/integrations/websocket-redis.d.mts +1 -1
  67. package/dist/integrations/websocket.d.mts +3 -3
  68. package/dist/{loadResources-CwXt9MCh.mjs → loadResources-B8UmpITt.mjs} +1 -1
  69. package/dist/{loadResourcesFromEntry-XHNeUWpu.mjs → loadResourcesFromEntry-BTlFEx05.mjs} +1 -1
  70. package/dist/{mcpPlugin-CzKdt3B8.mjs → mcpPlugin-D1wuRD2c.mjs} +10 -11
  71. package/dist/{memory-TdTHCS9-.mjs → memory-CLXA2VeJ.mjs} +1 -1
  72. package/dist/{metrics-Da2EUPi9.mjs → metrics-fdxI5mn_.mjs} +1 -1
  73. package/dist/middleware/index.d.mts +1 -1
  74. package/dist/middleware/index.mjs +2 -2
  75. package/dist/{openapi-ButnRyOM.mjs → openapi-xVJibapr.mjs} +5 -5
  76. package/dist/permissions/index.d.mts +3 -3
  77. package/dist/permissions/index.mjs +2 -2
  78. package/dist/{permissions-3uzwkbQt.mjs → permissions-BPB1xqGf.mjs} +4 -4
  79. package/dist/{pipe-9Tl-OAus.mjs → pipe-BOLmGIxa.mjs} +1 -1
  80. package/dist/pipeline/index.d.mts +1 -1
  81. package/dist/pipeline/index.mjs +1 -1
  82. package/dist/plugins/index.d.mts +6 -7
  83. package/dist/plugins/index.mjs +12 -12
  84. package/dist/plugins/response-cache.mjs +1 -1
  85. package/dist/plugins/tracing-entry.d.mts +1 -1
  86. package/dist/plugins/tracing-entry.mjs +1 -1
  87. package/dist/presets/filesUpload.d.mts +4 -4
  88. package/dist/presets/filesUpload.mjs +4 -4
  89. package/dist/presets/index.d.mts +1 -1
  90. package/dist/presets/index.mjs +1 -1
  91. package/dist/presets/multiTenant.d.mts +1 -1
  92. package/dist/presets/multiTenant.mjs +2 -2
  93. package/dist/presets/search.d.mts +2 -2
  94. package/dist/presets/search.mjs +1 -1
  95. package/dist/{presets-CF79RHEo.mjs → presets-BtyFwTO4.mjs} +2 -2
  96. package/dist/{queryCachePlugin-CnAeFqju.mjs → queryCachePlugin-emHb0CuX.mjs} +4 -4
  97. package/dist/{queryCachePlugin-Bd2tYgh5.d.mts → queryCachePlugin-xzFyKAjT.d.mts} +2 -2
  98. package/dist/{redis-3hqH_Qk_.d.mts → redis-C3W0qbz8.d.mts} +1 -1
  99. package/dist/{redis-stream-BtEUtjxZ.d.mts → redis-stream-DsP1vqZB.d.mts} +1 -1
  100. package/dist/{rateLimit-yKvxWAky.mjs → registerRoute-CPmdkZGu.mjs} +109 -2
  101. package/dist/registry/index.d.mts +1 -1
  102. package/dist/registry/index.mjs +2 -2
  103. package/dist/{registry-Br15xdGM.mjs → registry-Bm9LjWKs.mjs} +1 -1
  104. package/dist/{replyHelpers-DXHVxrrj.mjs → replyHelpers-67tRawQZ.mjs} +1 -1
  105. package/dist/{schemaIR-CE6USIRi.mjs → schemaIR-D1MJwqmp.mjs} +1 -1
  106. package/dist/schemas/index.d.mts +64 -65
  107. package/dist/scope/index.d.mts +2 -2
  108. package/dist/scope/index.mjs +3 -3
  109. package/dist/{sse-BrY1W6U8.mjs → sse-CfUjwjDk.mjs} +7 -4
  110. package/dist/streaming-BQcW6_Kq.mjs +162 -0
  111. package/dist/testing/index.d.mts +7 -7
  112. package/dist/testing/index.mjs +3 -3
  113. package/dist/testing/storageContract.d.mts +1 -1
  114. package/dist/types/index.d.mts +5 -5
  115. package/dist/types/storage.d.mts +1 -1
  116. package/dist/{types-WVlAVp8T.d.mts → types-CmkknLzI.d.mts} +10 -10
  117. package/dist/{types-BWBcb88c.d.mts → types-D60PFwfG.d.mts} +1 -1
  118. package/dist/{types-Bi0r0vjG.mjs → types-bHblZ9YN.mjs} +1 -1
  119. package/dist/utils/index.d.mts +42 -4
  120. package/dist/utils/index.mjs +6 -5
  121. package/dist/{utils-xAQeDyU_.mjs → utils-C6QQ9-hd.mjs} +1415 -1524
  122. package/dist/{validate-0__MuUsK.mjs → validate-CRcaWzp2.mjs} +1 -1
  123. package/dist/{versioning-BSEDGXKC.d.mts → versioning-D_eBCfNr.d.mts} +8 -1
  124. package/dist/{versioning-C0K8KQLx.mjs → versioning-Dk-71iIz.mjs} +1 -1
  125. package/dist/{websocket-BFBT5rH-.d.mts → websocket-MlYlrYq0.d.mts} +1 -1
  126. package/package.json +36 -30
  127. package/dist/EventTransport-7LPXLEUX.mjs +0 -103
  128. package/dist/actionPermissions-CX9QIMTd.mjs +0 -24
  129. package/dist/betterAuthOpenApi-DAAhMZff.mjs +0 -251
  130. package/dist/defineEvent-DC981g-o.mjs +0 -188
  131. package/dist/registerRoute-BEYn0ylk.mjs +0 -108
  132. /package/dist/{EventTransport-CaaXM5Y1.d.mts → EventTransport-IEn7Tn-Q.d.mts} +0 -0
  133. /package/dist/{HookSystem-BfCpWbwM.mjs → HookSystem-C1vB_Gc9.mjs} +0 -0
  134. /package/dist/{constants-TrJVIJl0.mjs → constants-gaEeMlz-.mjs} +0 -0
  135. /package/dist/{elevation-DW90z5bT.d.mts → elevation-xGUBq6p_.d.mts} +0 -0
  136. /package/dist/{errorHandler-_Lp2k9M3.d.mts → errorHandler-BtUUDPEa.d.mts} +0 -0
  137. /package/dist/{errors-DZOemeGa.d.mts → errors-DOHkjQlD.d.mts} +0 -0
  138. /package/dist/{errors-j4aJm1Wg.mjs → errors-DkO8Nk6-.mjs} +0 -0
  139. /package/dist/{externalPaths-DLle0R07.d.mts → externalPaths-BE6wFpYv.d.mts} +0 -0
  140. /package/dist/{generate-Dmk8cfvX.d.mts → generate-BnsL9GBm.d.mts} +0 -0
  141. /package/dist/{init-BS4Daqnv.d.mts → init-BPEu8cs-.d.mts} +0 -0
  142. /package/dist/{interface-DL7LlWS5.d.mts → interface-C1_WLTMK.d.mts} +0 -0
  143. /package/dist/{interface-CsrGR8LF.d.mts → interface-Uk8ONJv7.d.mts} +0 -0
  144. /package/dist/{keys-B3yyBEyH.mjs → keys-Cd316u_y.mjs} +0 -0
  145. /package/dist/{multipartBody-709YcXi1.mjs → multipartBody-CHEQSZ6G.mjs} +0 -0
  146. /package/dist/{pluralize-BxdUl2P4.mjs → pluralize-DccFV9R7.mjs} +0 -0
  147. /package/dist/{preloadResources-B-j-iqo-.mjs → preloadResources-CHw3_oA_.mjs} +0 -0
  148. /package/dist/{pushref-registry-Dqclzjy7.d.mts → pushref-registry-DnCqL3aa.d.mts} +0 -0
  149. /package/dist/{requestContext-DDLS3NVU.mjs → requestContext-BZKOr13H.mjs} +0 -0
  150. /package/dist/{chunk-BpYLSNr0.mjs → rolldown-runtime-8H4AJuhK.mjs} +0 -0
  151. /package/dist/{schemaConverter-DatAaVNj.mjs → schemaConverter-U0MnO9vd.mjs} +0 -0
  152. /package/dist/{sessionManager-CyHpYXoB.d.mts → sessionManager-BXG-HGwG.d.mts} +0 -0
  153. /package/dist/{storage-C5q8fuEt.d.mts → storage-Co_PQpeQ.d.mts} +0 -0
  154. /package/dist/{store-helpers-DjSYI2uP.mjs → store-helpers-DY6xq4sM.mjs} +0 -0
  155. /package/dist/{tracing-Bnb1-YVd.d.mts → tracing-D8jlGXP7.d.mts} +0 -0
  156. /package/dist/{typeGuards-CcFZXgU7.mjs → typeGuards-C9KXUly6.mjs} +0 -0
  157. /package/dist/{types-BJwJN2Pg.d.mts → types-LNebCoJx.d.mts} +0 -0
  158. /package/dist/{types-D57iXYb8.mjs → types-XTApa8b6.mjs} +0 -0
@@ -1,58 +1,18 @@
1
- import { s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS } from "./constants-TrJVIJl0.mjs";
1
+ import { s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS } from "./constants-gaEeMlz-.mjs";
2
2
  import { arcLog } from "./logger/index.mjs";
3
- import { r as ForbiddenError } from "./errors-j4aJm1Wg.mjs";
4
- import { b as isElevated, n as PUBLIC_SCOPE, x as isMember } from "./types-Bi0r0vjG.mjs";
5
- import { N as assertValidConfig, f as getDefaultCrudSchemas, i as pipeUIMessageStreamToReply, r as isReadableStream } from "./utils-xAQeDyU_.mjs";
6
- import { d as DEFAULT_FIELD_WRITE_DENIAL_POLICY, t as BaseController } from "./BaseController-B-uXzf6I.mjs";
7
- import { a as resolveRoutePreHandlers, c as buildArcDecorator, i as buildPreHandlerChain, n as resolveRouterPluginMw, o as buildAuthMiddleware, r as selectPluginMw, t as buildRateLimitConfig } from "./rateLimit-yKvxWAky.mjs";
8
- import { F as applyFieldWritePermissions, L as resolveEffectiveRoles } from "./permissions-3uzwkbQt.mjs";
9
- import { t as getUserRoles } from "./types-D57iXYb8.mjs";
10
- import { r as buildCrudPermissionMw, t as tryRegisterRoute } from "./registerRoute-BEYn0ylk.mjs";
11
- import { t as applyPresets } from "./presets-CF79RHEo.mjs";
12
- import { n as convertRouteSchema, t as convertOpenApiSchemas } from "./schemaConverter-DatAaVNj.mjs";
13
- import { t as hasEvents } from "./typeGuards-CcFZXgU7.mjs";
14
- import { a as createFastifyHandler, i as createCrudHandlers, n as buildPipelineHandler, o as createRequestContext, r as resolvePipelineSteps, u as buildRequestScopeProjection } from "./pipeline-D4sqiokR.mjs";
15
- import { t as pluralize } from "./pluralize-BxdUl2P4.mjs";
16
- import { t as resolveActionPermission } from "./actionPermissions-CX9QIMTd.mjs";
17
- //#region src/core/middlewares/fieldWrite.ts
18
- /**
19
- * Build a preHandler that enforces field-write permissions on the request body.
20
- *
21
- * Auto-CRUD's create/update routes get this for free via `BodySanitizer.sanitize()`
22
- * inside `BaseController`. Custom routes (`config.routes`, presets, action endpoints)
23
- * never went through that path — so a host that declared
24
- * `fields: { role: fields.writableBy(['admin']) }` and a custom
25
- * `POST /users/promote` happily accepted `{ role: 'admin' }` from any caller.
26
- *
27
- * This preHandler closes that gap. It applies ONLY the `applyFieldWritePermissions`
28
- * step — no `SYSTEM_FIELDS` strip, no `fieldRules` strip — because custom-route
29
- * bodies don't necessarily mirror the resource's adapter shape, and we'd
30
- * generate surprising 403s by enforcing rules tied to that shape.
31
- *
32
- * Returns `null` when the resource has no field permissions configured — the
33
- * caller should then skip wiring it into the preHandler chain.
34
- */
35
- function buildFieldWritePreHandler(fieldPermissions, policy = DEFAULT_FIELD_WRITE_DENIAL_POLICY) {
36
- if (!fieldPermissions || Object.keys(fieldPermissions).length === 0) return null;
37
- return async (request, _reply) => {
38
- const body = request.body;
39
- if (!body || typeof body !== "object" || Array.isArray(body)) return;
40
- const scope = request.scope ?? PUBLIC_SCOPE;
41
- if (isElevated(scope)) return;
42
- const { body: filtered, deniedFields } = applyFieldWritePermissions(body, fieldPermissions, resolveEffectiveRoles(getUserRoles(request.user), isMember(scope) ? scope.orgRoles : []));
43
- if (deniedFields.length > 0 && policy === "reject") throw new ForbiddenError(`Not permitted to write field${deniedFields.length === 1 ? "" : "s"}: ${deniedFields.join(", ")}`);
44
- request.body = filtered;
45
- };
46
- }
47
- /**
48
- * True for HTTP methods that carry a request body and should run the
49
- * field-write preHandler. GET/DELETE/HEAD/OPTIONS skip enforcement.
50
- */
51
- function methodCarriesBody(method) {
52
- const m = method.toUpperCase();
53
- return m === "POST" || m === "PUT" || m === "PATCH";
54
- }
55
- //#endregion
3
+ import { r as ForbiddenError } from "./errors-DkO8Nk6-.mjs";
4
+ import { b as isElevated, n as PUBLIC_SCOPE, x as isMember } from "./types-bHblZ9YN.mjs";
5
+ import { p as assertValidConfig, x as getDefaultCrudSchemas } from "./utils-C6QQ9-hd.mjs";
6
+ import { d as DEFAULT_FIELD_WRITE_DENIAL_POLICY, t as BaseController } from "./BaseController-Dy6EQHjM.mjs";
7
+ import { F as applyFieldWritePermissions, L as resolveEffectiveRoles } from "./permissions-BPB1xqGf.mjs";
8
+ import { t as getUserRoles } from "./types-XTApa8b6.mjs";
9
+ import { n as convertRouteSchema, t as convertOpenApiSchemas } from "./schemaConverter-U0MnO9vd.mjs";
10
+ import { i as pipeUIMessageStreamToReply, r as isReadableStream } from "./streaming-BQcW6_Kq.mjs";
11
+ import { a as createCrudHandlers, d as buildRequestScopeProjection, i as resolvePipelineSteps, o as createFastifyHandler, r as buildPipelineHandler, s as createRequestContext, t as resolveActionPermission } from "./actionPermissions-h7DYDNMg.mjs";
12
+ import { c as resolveRoutePreHandlers, d as buildArcDecorator, i as selectPluginMw, l as buildAuthMiddleware, n as buildRateLimitConfig, o as buildCrudPermissionMw, r as resolveRouterPluginMw, s as buildPreHandlerChain, t as tryRegisterRoute } from "./registerRoute-CPmdkZGu.mjs";
13
+ import { t as applyPresets } from "./presets-BtyFwTO4.mjs";
14
+ import { t as hasEvents } from "./typeGuards-C9KXUly6.mjs";
15
+ import { t as pluralize } from "./pluralize-DccFV9R7.mjs";
56
16
  //#region src/core/aggregation/defineAggregation.ts
57
17
  /**
58
18
  * Declare a single resource aggregation. Exported configs flow into
@@ -99,6 +59,45 @@ function defineAggregation(config) {
99
59
  return config;
100
60
  }
101
61
  //#endregion
62
+ //#region src/core/middlewares/fieldWrite.ts
63
+ /**
64
+ * Build a preHandler that enforces field-write permissions on the request body.
65
+ *
66
+ * Auto-CRUD's create/update routes get this for free via `BodySanitizer.sanitize()`
67
+ * inside `BaseController`. Custom routes (`config.routes`, presets, action endpoints)
68
+ * never went through that path — so a host that declared
69
+ * `fields: { role: fields.writableBy(['admin']) }` and a custom
70
+ * `POST /users/promote` happily accepted `{ role: 'admin' }` from any caller.
71
+ *
72
+ * This preHandler closes that gap. It applies ONLY the `applyFieldWritePermissions`
73
+ * step — no `SYSTEM_FIELDS` strip, no `fieldRules` strip — because custom-route
74
+ * bodies don't necessarily mirror the resource's adapter shape, and we'd
75
+ * generate surprising 403s by enforcing rules tied to that shape.
76
+ *
77
+ * Returns `null` when the resource has no field permissions configured — the
78
+ * caller should then skip wiring it into the preHandler chain.
79
+ */
80
+ function buildFieldWritePreHandler(fieldPermissions, policy = DEFAULT_FIELD_WRITE_DENIAL_POLICY) {
81
+ if (!fieldPermissions || Object.keys(fieldPermissions).length === 0) return null;
82
+ return async (request, _reply) => {
83
+ const body = request.body;
84
+ if (!body || typeof body !== "object" || Array.isArray(body)) return;
85
+ const scope = request.scope ?? PUBLIC_SCOPE;
86
+ if (isElevated(scope)) return;
87
+ const { body: filtered, deniedFields } = applyFieldWritePermissions(body, fieldPermissions, resolveEffectiveRoles(getUserRoles(request.user), isMember(scope) ? scope.orgRoles : []));
88
+ if (deniedFields.length > 0 && policy === "reject") throw new ForbiddenError(`Not permitted to write field${deniedFields.length === 1 ? "" : "s"}: ${deniedFields.join(", ")}`);
89
+ request.body = filtered;
90
+ };
91
+ }
92
+ /**
93
+ * True for HTTP methods that carry a request body and should run the
94
+ * field-write preHandler. GET/DELETE/HEAD/OPTIONS skip enforcement.
95
+ */
96
+ function methodCarriesBody(method) {
97
+ const m = method.toUpperCase();
98
+ return m === "POST" || m === "PUT" || m === "PATCH";
99
+ }
100
+ //#endregion
102
101
  //#region src/core/createCrudRouter.ts
103
102
  /**
104
103
  * Mount custom routes (from presets or user-defined `routes`) on Fastify.
@@ -1246,7 +1245,7 @@ function buildResourcePlugin(resource) {
1246
1245
  idField: resource.idField
1247
1246
  });
1248
1247
  if (resource.actions && Object.keys(resource.actions).length > 0) {
1249
- const { createActionRouter } = await import("./createActionRouter-DGCCp-kP.mjs").then((n) => n.n);
1248
+ const { createActionRouter } = await import("./createActionRouter-CagItpxI.mjs").then((n) => n.n);
1250
1249
  createActionRouter(typedInstance, {
1251
1250
  ...normalizeActionsToRouterConfig(resource.actions, resource.actionPermissions, resource.tag, resource.permissions, resource.name, typedInstance.log),
1252
1251
  resourceName: resource.name,
@@ -1260,7 +1259,7 @@ function buildResourcePlugin(resource) {
1260
1259
  });
1261
1260
  }
1262
1261
  if (resource.aggregations && Object.keys(resource.aggregations).length > 0) {
1263
- const [{ createAggregationRouter }, { adapterSupportsAggregate, ArcAggregationConfigError }] = await Promise.all([import("./createAggregationRouter-Ca77b8iK.mjs"), import("./validate-0__MuUsK.mjs").then((n) => n.r)]);
1262
+ const [{ createAggregationRouter }, { adapterSupportsAggregate, ArcAggregationConfigError }] = await Promise.all([import("./createAggregationRouter-DVKroXhC.mjs"), import("./validate-CRcaWzp2.mjs").then((n) => n.r)]);
1264
1263
  const repoForAgg = resource.controller?.repository ?? resource.repository;
1265
1264
  if (!adapterSupportsAggregate(repoForAgg)) {
1266
1265
  const undispatchable = Object.entries(resource.aggregations).filter(([, cfg]) => !cfg.materialized).map(([name]) => name);
@@ -1,10 +1,9 @@
1
- import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
2
- import "./constants-TrJVIJl0.mjs";
3
- import { f as createError } from "./errors-j4aJm1Wg.mjs";
4
- import { c as buildArcDecorator, i as buildPreHandlerChain, n as resolveRouterPluginMw, r as selectPluginMw, s as buildAuthMiddlewareForPermissions, t as buildRateLimitConfig } from "./rateLimit-yKvxWAky.mjs";
5
- import { n as buildActionPermissionMw, t as tryRegisterRoute } from "./registerRoute-BEYn0ylk.mjs";
6
- import { l as sendControllerResponse, r as resolvePipelineSteps, t as buildActionPipelineHandler } from "./pipeline-D4sqiokR.mjs";
7
- import { n as schemaIRToJsonSchemaBranch, t as normalizeSchemaIR } from "./schemaIR-CE6USIRi.mjs";
1
+ import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
2
+ import "./constants-gaEeMlz-.mjs";
3
+ import { f as createError } from "./errors-DkO8Nk6-.mjs";
4
+ import { i as resolvePipelineSteps, n as buildActionPipelineHandler, u as sendControllerResponse } from "./actionPermissions-h7DYDNMg.mjs";
5
+ import { a as buildActionPermissionMw, d as buildArcDecorator, i as selectPluginMw, n as buildRateLimitConfig, r as resolveRouterPluginMw, s as buildPreHandlerChain, t as tryRegisterRoute, u as buildAuthMiddlewareForPermissions } from "./registerRoute-CPmdkZGu.mjs";
6
+ import { n as schemaIRToJsonSchemaBranch, t as normalizeSchemaIR } from "./schemaIR-D1MJwqmp.mjs";
8
7
  //#region src/core/createActionRouter.ts
9
8
  var createActionRouter_exports = /* @__PURE__ */ __exportAll({
10
9
  buildActionBodySchema: () => buildActionBodySchema,
@@ -1,7 +1,7 @@
1
- import { f as createError, l as UnauthorizedError, r as ForbiddenError } from "./errors-j4aJm1Wg.mjs";
2
- import { c as buildArcDecorator, i as buildPreHandlerChain, n as resolveRouterPluginMw, o as buildAuthMiddleware, r as selectPluginMw, t as buildRateLimitConfig } from "./rateLimit-yKvxWAky.mjs";
3
- import { n as validateAggregations } from "./validate-0__MuUsK.mjs";
4
- import { t as buildAggregationHandler } from "./buildHandler-Cvrc2p7r.mjs";
1
+ import { f as createError, l as UnauthorizedError, r as ForbiddenError } from "./errors-DkO8Nk6-.mjs";
2
+ import { d as buildArcDecorator, i as selectPluginMw, l as buildAuthMiddleware, n as buildRateLimitConfig, r as resolveRouterPluginMw, s as buildPreHandlerChain } from "./registerRoute-CPmdkZGu.mjs";
3
+ import { n as validateAggregations } from "./validate-CRcaWzp2.mjs";
4
+ import { t as buildAggregationHandler } from "./buildHandler-B0qvAguf.mjs";
5
5
  //#region src/core/aggregation/createAggregationRouter.ts
6
6
  /**
7
7
  * Register one Fastify route per aggregation. No-op when the map is
@@ -1,6 +1,6 @@
1
- import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
1
+ import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
2
2
  import { arcLog } from "./logger/index.mjs";
3
- import { n as PUBLIC_SCOPE } from "./types-Bi0r0vjG.mjs";
3
+ import { n as PUBLIC_SCOPE } from "./types-bHblZ9YN.mjs";
4
4
  import Fastify from "fastify";
5
5
  import qs from "qs";
6
6
  //#region src/factory/presets.ts
@@ -74,7 +74,7 @@ const productionPreset = {
74
74
  */
75
75
  function devLoggerConfig() {
76
76
  try {
77
- if (typeof import.meta?.resolve === "function") {
77
+ if (typeof import.meta.resolve === "function") {
78
78
  import.meta.resolve("pino-pretty");
79
79
  return {
80
80
  level: "debug",
@@ -202,7 +202,7 @@ async function registerArcCore(fastify, config, trackPlugin) {
202
202
  await fastify.register(arcCorePlugin, { emitEvents: config.arcPlugins?.emitEvents !== false });
203
203
  trackPlugin("arc-core");
204
204
  if (config.arcPlugins?.events !== false) {
205
- const { default: eventPlugin } = await import("./eventPlugin-Bw4bUDEO.mjs").then((n) => n.n);
205
+ const { default: eventPlugin } = await import("./eventPlugin-DJG2D7sy.mjs").then((n) => n.n);
206
206
  const eventOpts = typeof config.arcPlugins?.events === "object" ? config.arcPlugins.events : {};
207
207
  await fastify.register(eventPlugin, {
208
208
  ...eventOpts,
@@ -239,15 +239,15 @@ async function registerArcPlugins(fastify, config, trackPlugin, modules) {
239
239
  trackPlugin("arc-graceful-shutdown");
240
240
  }
241
241
  if (config.arcPlugins?.caching) {
242
- const { default: cachingPlugin } = await import("./caching-C0DdKiYB.mjs").then((n) => n.r);
242
+ const { default: cachingPlugin } = await import("./caching-_NJeDd1_.mjs").then((n) => n.r);
243
243
  const opts = config.arcPlugins.caching === true ? {} : config.arcPlugins.caching;
244
244
  await fastify.register(cachingPlugin, opts);
245
245
  trackPlugin("arc-caching", opts);
246
246
  }
247
247
  if (config.arcPlugins?.queryCache) {
248
- const { queryCachePlugin } = await import("./queryCachePlugin-CnAeFqju.mjs").then((n) => n.n);
248
+ const { queryCachePlugin } = await import("./queryCachePlugin-emHb0CuX.mjs").then((n) => n.n);
249
249
  const opts = config.arcPlugins.queryCache === true ? {} : config.arcPlugins.queryCache;
250
- const store = config.stores?.queryCache ?? new (await (import("./memory-TdTHCS9-.mjs").then((n) => n.n))).MemoryCacheStore();
250
+ const store = config.stores?.queryCache ?? new (await (import("./memory-CLXA2VeJ.mjs").then((n) => n.n))).MemoryCacheStore();
251
251
  await fastify.register(queryCachePlugin, {
252
252
  store,
253
253
  ...opts
@@ -256,19 +256,19 @@ async function registerArcPlugins(fastify, config, trackPlugin, modules) {
256
256
  }
257
257
  if (config.arcPlugins?.sse) if (config.arcPlugins?.events === false) fastify.log.warn("SSE plugin requires events plugin (arcPlugins.events). SSE disabled.");
258
258
  else {
259
- const { default: ssePlugin } = await import("./sse-BrY1W6U8.mjs").then((n) => n.r);
259
+ const { default: ssePlugin } = await import("./sse-CfUjwjDk.mjs").then((n) => n.r);
260
260
  const opts = config.arcPlugins.sse === true ? {} : config.arcPlugins.sse;
261
261
  await fastify.register(ssePlugin, opts);
262
262
  trackPlugin("arc-sse", opts);
263
263
  }
264
264
  if (config.arcPlugins?.metrics) {
265
- const { default: metricsPlugin } = await import("./metrics-Da2EUPi9.mjs").then((n) => n.r);
265
+ const { default: metricsPlugin } = await import("./metrics-fdxI5mn_.mjs").then((n) => n.r);
266
266
  const opts = config.arcPlugins.metrics === true ? {} : config.arcPlugins.metrics;
267
267
  await fastify.register(metricsPlugin, opts);
268
268
  trackPlugin("arc-metrics", opts);
269
269
  }
270
270
  if (config.arcPlugins?.versioning) {
271
- const { default: versioningPlugin } = await import("./versioning-C0K8KQLx.mjs").then((n) => n.r);
271
+ const { default: versioningPlugin } = await import("./versioning-Dk-71iIz.mjs").then((n) => n.r);
272
272
  await fastify.register(versioningPlugin, config.arcPlugins.versioning);
273
273
  trackPlugin("arc-versioning", config.arcPlugins.versioning);
274
274
  }
@@ -337,7 +337,7 @@ async function registerAuth(fastify, config, trackPlugin) {
337
337
  */
338
338
  async function registerElevation(fastify, config, trackPlugin) {
339
339
  if (!config.elevation) return;
340
- const { elevationPlugin } = await import("./elevation-BzhyVWfn.mjs").then((n) => n.r);
340
+ const { elevationPlugin } = await import("./elevation-COpYKt2h.mjs").then((n) => n.r);
341
341
  await fastify.register(elevationPlugin, config.elevation);
342
342
  trackPlugin("arc-elevation", config.elevation);
343
343
  fastify.log.debug("Elevation plugin enabled");
@@ -347,7 +347,7 @@ async function registerElevation(fastify, config, trackPlugin) {
347
347
  */
348
348
  async function registerErrorHandler(fastify, config, trackPlugin) {
349
349
  if (config.errorHandler === false) return;
350
- const { errorHandlerPlugin } = await import("./errorHandler-Bua97SEt.mjs").then((n) => n.r);
350
+ const { errorHandlerPlugin } = await import("./errorHandler-Dxf6P_kV.mjs").then((n) => n.r);
351
351
  const errorOpts = typeof config.errorHandler === "object" ? config.errorHandler : { includeStack: config.preset !== "production" };
352
352
  await fastify.register(errorHandlerPlugin, errorOpts);
353
353
  trackPlugin("arc-error-handler", errorOpts);
@@ -448,7 +448,7 @@ async function registerResources(fastify, config) {
448
448
  let discoveryPath;
449
449
  let discoveryYieldedZero = false;
450
450
  if (resolvedResources === void 0 && config.resourceDir) {
451
- const { loadResources } = await import("./loadResources-CwXt9MCh.mjs").then((n) => n.n);
451
+ const { loadResources } = await import("./loadResources-B8UmpITt.mjs").then((n) => n.n);
452
452
  const { resolve, dirname } = await import("node:path");
453
453
  const { fileURLToPath } = await import("node:url");
454
454
  const rawDir = config.resourceDir;
@@ -896,7 +896,7 @@ async function createApp(options) {
896
896
  await registerErrorHandler(fastify, config, trackPlugin);
897
897
  await registerResources(fastify, config);
898
898
  if (config.replyHelpers) {
899
- const { replyHelpersPlugin } = await import("./replyHelpers-DXHVxrrj.mjs").then((n) => n.n);
899
+ const { replyHelpersPlugin } = await import("./replyHelpers-67tRawQZ.mjs").then((n) => n.n);
900
900
  await fastify.register(replyHelpersPlugin);
901
901
  }
902
902
  if (config.serializeBigInt) {
@@ -1,5 +1,5 @@
1
- import { p as RegistryEntry } from "../index-QYma8mdC.mjs";
2
- import { t as ExternalOpenApiPaths } from "../externalPaths-DLle0R07.mjs";
1
+ import { p as RegistryEntry } from "../index-CHNQIhcb.mjs";
2
+ import { t as ExternalOpenApiPaths } from "../externalPaths-BE6wFpYv.mjs";
3
3
  import { FastifyPluginAsync } from "fastify";
4
4
 
5
5
  //#region src/docs/openapi/types.d.ts
@@ -1,5 +1,5 @@
1
- import { t as getUserRoles } from "../types-D57iXYb8.mjs";
2
- import { n as openApiPlugin, r as openapi_default, t as buildOpenApiSpec } from "../openapi-ButnRyOM.mjs";
1
+ import { t as getUserRoles } from "../types-XTApa8b6.mjs";
2
+ import { n as openApiPlugin, r as openapi_default, t as buildOpenApiSpec } from "../openapi-xVJibapr.mjs";
3
3
  import fp from "fastify-plugin";
4
4
  //#region src/docs/scalar.ts
5
5
  const scalarPlugin = async (fastify, opts = {}) => {
@@ -1,6 +1,6 @@
1
- import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
1
+ import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
2
2
  import { arcLog } from "./logger/index.mjs";
3
- import { t as getUserRoles } from "./types-D57iXYb8.mjs";
3
+ import { t as getUserRoles } from "./types-XTApa8b6.mjs";
4
4
  import fp from "fastify-plugin";
5
5
  //#region src/scope/elevation.ts
6
6
  var elevation_exports = /* @__PURE__ */ __exportAll({
@@ -1,5 +1,5 @@
1
- import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
2
- import { m as statusToArcCode, p as isArcError } from "./errors-j4aJm1Wg.mjs";
1
+ import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
2
+ import { m as statusToArcCode, p as isArcError } from "./errors-DkO8Nk6-.mjs";
3
3
  import { isHttpError, toErrorContract } from "@classytic/repo-core/errors";
4
4
  import fp from "fastify-plugin";
5
5
  //#region src/plugins/errorHandler.ts
@@ -1,9 +1,110 @@
1
- import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
1
+ import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
2
2
  import { arcLog } from "./logger/index.mjs";
3
- import { d as createDomainError } from "./errors-j4aJm1Wg.mjs";
4
- import { n as requestContext } from "./requestContext-DDLS3NVU.mjs";
5
- import { n as createEvent, t as MemoryEventTransport } from "./EventTransport-7LPXLEUX.mjs";
3
+ import { d as createDomainError } from "./errors-DkO8Nk6-.mjs";
4
+ import { n as requestContext } from "./requestContext-BZKOr13H.mjs";
6
5
  import fp from "fastify-plugin";
6
+ import { createEvent, matchEventPattern } from "@classytic/primitives/events";
7
+ //#region src/events/EventTransport.ts
8
+ /**
9
+ * Internal arc events module — concrete in-memory transport.
10
+ *
11
+ * **Public type contracts moved out (arc 2.12).** `EventMeta`, `DomainEvent`,
12
+ * `EventHandler`, `EventLogger`, `EventTransport`, `DeadLetteredEvent`,
13
+ * `PublishManyResult`, plus the `createEvent` / `createChildEvent` /
14
+ * `matchEventPattern` helpers, are now owned by `@classytic/primitives/events`.
15
+ * Two reasons:
16
+ *
17
+ * 1. The shapes ARE the cross-package contract. arc, arc-next, mongokit's
18
+ * audit-log plugin, future kits and downstream services all share them.
19
+ * Owning them in `primitives` (pure types, zero runtime, zero deps)
20
+ * eliminates the "manually mirror in two places" problem the previous
21
+ * `primitives/src/events.ts` header explicitly called out.
22
+ * 2. Inverting the dependency direction lets future packages (sqlitekit
23
+ * audit, billing services) consume the contract without depending on
24
+ * arc's HTTP-coupled stack.
25
+ *
26
+ * Hosts MUST import the types from primitives directly:
27
+ *
28
+ * ```typescript
29
+ * import type {
30
+ * EventMeta, DomainEvent, EventHandler, EventTransport,
31
+ * DeadLetteredEvent, PublishManyResult,
32
+ * } from '@classytic/primitives/events';
33
+ * import { createEvent, createChildEvent } from '@classytic/primitives/events';
34
+ * ```
35
+ *
36
+ * arc's `events/index.ts` barrel does NOT re-export these — by design, so
37
+ * that consumer code is forced into the canonical import path and the org's
38
+ * "no re-exports" rule holds at every public surface.
39
+ *
40
+ * What stays here:
41
+ * - `MemoryEventTransport` — the in-memory `EventTransport` implementation
42
+ * used as arc's default transport. Its handler-set state is process-local;
43
+ * wrong layer for primitives.
44
+ * - `MemoryEventTransportOptions` — its options shape.
45
+ *
46
+ * Inside arc, files that previously imported types from `./EventTransport.js`
47
+ * keep working: this file re-exports them from primitives for arc's own
48
+ * call sites. That re-export is an internal refactor convenience — the
49
+ * public `events/index.ts` barrel stays clean.
50
+ */
51
+ /**
52
+ * In-memory event transport (default).
53
+ *
54
+ * Events are delivered synchronously within the process. Not suitable for
55
+ * multi-instance deployments — pair with `RedisEventTransport` /
56
+ * `RedisStreamTransport` (subpath imports) for those.
57
+ */
58
+ var MemoryEventTransport = class {
59
+ name = "memory";
60
+ handlers = /* @__PURE__ */ new Map();
61
+ logger;
62
+ constructor(options) {
63
+ this.logger = options?.logger ?? console;
64
+ }
65
+ async publish(event) {
66
+ const allHandlers = /* @__PURE__ */ new Set();
67
+ for (const [pattern, handlers] of this.handlers) if (matchEventPattern(pattern, event.type)) for (const h of handlers) allHandlers.add(h);
68
+ for (const handler of allHandlers) try {
69
+ await handler(event);
70
+ } catch (err) {
71
+ this.logger.error(`[EventTransport] Handler error for ${event.type}:`, err);
72
+ }
73
+ }
74
+ /**
75
+ * Reference `publishMany` implementation — delegates to `publish()` in order.
76
+ *
77
+ * Production transports (Kafka, Redis pipeline, SQS batch) should override
78
+ * this with a single batched network call. Memory transport has nothing to
79
+ * batch, so we just loop — the loop still returns a proper result map so
80
+ * `EventOutbox.relay` can exercise the batched code path in tests.
81
+ */
82
+ async publishMany(events) {
83
+ const results = /* @__PURE__ */ new Map();
84
+ for (const event of events) try {
85
+ await this.publish(event);
86
+ results.set(event.meta.id, null);
87
+ } catch (err) {
88
+ results.set(event.meta.id, err instanceof Error ? err : new Error(String(err)));
89
+ }
90
+ return results;
91
+ }
92
+ async subscribe(pattern, handler) {
93
+ if (!this.handlers.has(pattern)) this.handlers.set(pattern, /* @__PURE__ */ new Set());
94
+ this.handlers.get(pattern)?.add(handler);
95
+ return () => {
96
+ const set = this.handlers.get(pattern);
97
+ if (set) {
98
+ set.delete(handler);
99
+ if (set.size === 0) this.handlers.delete(pattern);
100
+ }
101
+ };
102
+ }
103
+ async close() {
104
+ this.handlers.clear();
105
+ }
106
+ };
107
+ //#endregion
7
108
  //#region src/events/retry.ts
8
109
  /**
9
110
  * Wrap an event handler with retry logic and dead letter support.
@@ -219,4 +320,4 @@ var eventPlugin_default = fp(eventPlugin, {
219
320
  fastify: "5.x"
220
321
  });
221
322
  //#endregion
222
- export { withRetry as i, eventPlugin_exports as n, createDeadLetterPublisher as r, eventPlugin as t };
323
+ export { MemoryEventTransport as a, withRetry as i, eventPlugin_exports as n, createEvent as o, createDeadLetterPublisher as r, eventPlugin as t };
@@ -1,4 +1,4 @@
1
- import { a as EventTransport, i as EventLogger, n as DomainEvent, r as EventHandler } from "./EventTransport-CaaXM5Y1.mjs";
1
+ import { a as EventTransport, i as EventLogger, n as DomainEvent, r as EventHandler } from "./EventTransport-IEn7Tn-Q.mjs";
2
2
  import { FastifyPluginAsync } from "fastify";
3
3
 
4
4
  //#region src/events/defineEvent.d.ts
@@ -1,7 +1,7 @@
1
- import { a as EventTransport, i as EventLogger, n as DomainEvent, o as MemoryEventTransport, r as EventHandler, s as MemoryEventTransportOptions, t as DeadLetteredEvent } from "../EventTransport-CaaXM5Y1.mjs";
2
- import { a as withRetry, c as EventDefinitionOutput, d as EventSchema, f as ValidationResult, i as createDeadLetterPublisher, l as EventRegistry, m as defineEvent, n as eventPlugin, o as CustomValidator, p as createEventRegistry, r as RetryOptions, s as EventDefinitionInput, t as EventPluginOptions, u as EventRegistryOptions } from "../eventPlugin-C1W1CRbf.mjs";
1
+ import { a as EventTransport, i as EventLogger, n as DomainEvent, o as MemoryEventTransport, r as EventHandler, s as MemoryEventTransportOptions, t as DeadLetteredEvent } from "../EventTransport-IEn7Tn-Q.mjs";
2
+ import { a as withRetry, c as EventDefinitionOutput, d as EventSchema, f as ValidationResult, i as createDeadLetterPublisher, l as EventRegistry, m as defineEvent, n as eventPlugin, o as CustomValidator, p as createEventRegistry, r as RetryOptions, s as EventDefinitionInput, t as EventPluginOptions, u as EventRegistryOptions } from "../eventPlugin-DbBFd3x_.mjs";
3
3
  import { RedisEventTransportOptions, RedisLike } from "./transports/redis.mjs";
4
- import { r as RedisStreamTransportOptions, t as RedisStreamLike } from "../redis-stream-BtEUtjxZ.mjs";
4
+ import { r as RedisStreamTransportOptions, t as RedisStreamLike } from "../redis-stream-DsP1vqZB.mjs";
5
5
  import { RepositoryLike } from "@classytic/repo-core/adapter";
6
6
 
7
7
  //#region src/events/eventTypes.d.ts