@classytic/arc 2.31.0 → 2.33.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.
Files changed (194) hide show
  1. package/README.md +1 -1
  2. package/bin/arc.js +58 -17
  3. package/dist/{BaseController-De7GqHck.mjs → BaseController-CaQC5EXX.mjs} +298 -35
  4. package/dist/{EventTransport-2uVV34WU.d.mts → EventTransport-BEVP50ka.d.mts} +16 -0
  5. package/dist/{EventTransport-9mlTgqzE.mjs → EventTransport-tq4CEB-q.mjs} +39 -2
  6. package/dist/{HookSystem-BcmPyq5I.mjs → HookSystem-DqXkMXkB.mjs} +2 -2
  7. package/dist/{ResourceRegistry-qq0mn2s9.mjs → ResourceRegistry-DoALUlOO.mjs} +18 -15
  8. package/dist/{actionPermissions-BE5NwaQk.mjs → actionPermissions-CUeCmpUd.mjs} +1 -1
  9. package/dist/audit/index.d.mts +2 -2
  10. package/dist/audit/index.mjs +2 -2
  11. package/dist/auth/audit.mjs +1 -1
  12. package/dist/auth/index.d.mts +2 -2
  13. package/dist/auth/index.mjs +44 -11
  14. package/dist/auth/redis-session.mjs +1 -1
  15. package/dist/{authorizationDecision-ChvUQGG1.mjs → authorizationDecision-B3mP_QTy.mjs} +2 -2
  16. package/dist/{types-B7XeLEgK.d.mts → base-Csjc2oF-.d.mts} +74 -74
  17. package/dist/{buildHandler-CDrCJzmB.mjs → buildHandler-DLE9xX-V.mjs} +6 -5
  18. package/dist/cache/index.mjs +4 -4
  19. package/dist/{caching-BFHA6Scf.mjs → caching-BcGmvnHh.mjs} +2 -2
  20. package/dist/cleanup/index.d.mts +52 -18
  21. package/dist/cleanup/index.mjs +281 -32
  22. package/dist/cli/commands/describe.d.mts +1 -1
  23. package/dist/cli/commands/describe.mjs +4 -6
  24. package/dist/cli/commands/docs.mjs +3 -3
  25. package/dist/cli/commands/doctor.mjs +1 -1
  26. package/dist/cli/commands/generate.mjs +2 -2
  27. package/dist/cli/commands/init.mjs +2 -2
  28. package/dist/cli/commands/introspect.mjs +2 -2
  29. package/dist/cli/index.mjs +3 -3
  30. package/dist/{constants-D3Dv4LAV.mjs → constants-BxCoxmiN.mjs} +1 -1
  31. package/dist/context/index.mjs +3 -3
  32. package/dist/core/index.d.mts +2 -2
  33. package/dist/core/index.mjs +7 -7
  34. package/dist/{core-BGpIxINN.mjs → core-dxhcHhUD.mjs} +3 -3
  35. package/dist/{createActionRouter-CDXEdasl.mjs → createActionRouter-DVpoA0do.mjs} +14 -11
  36. package/dist/{createAggregationRouter-KrQDzx-k.mjs → createAggregationRouter-B_B48JZ-.mjs} +10 -8
  37. package/dist/{createApp-Df89BEni.mjs → createApp-CLGegqiG.mjs} +287 -62
  38. package/dist/{defineAggregation-DbPPS8RI.mjs → defineAggregation-Nv-DwfOf.mjs} +1 -1
  39. package/dist/{defineResource-Bv6EtN1x.mjs → defineResource-DR9vsUYy.mjs} +318 -35
  40. package/dist/discovery/index.mjs +1 -1
  41. package/dist/docs/index.d.mts +1 -1
  42. package/dist/docs/index.mjs +3 -3
  43. package/dist/{elevation-D2l1mh4g.mjs → elevation-B0tlY8y1.mjs} +4 -4
  44. package/dist/encryption/index.mjs +5 -4
  45. package/dist/{errorHandler-C5NeD6bT.mjs → errorHandler-C7xBqHsI.mjs} +42 -5
  46. package/dist/{errorHandler-CpYUJmPA.d.mts → errorHandler-DI5AN2b5.d.mts} +14 -3
  47. package/dist/{errors-Cj42AntO.mjs → errors-Cd_yy7aW.mjs} +1 -1
  48. package/dist/{eventPlugin-GF5nnBIq.d.mts → eventPlugin-DSNEZWfV.d.mts} +29 -1
  49. package/dist/{eventPlugin-CkffEihm.mjs → eventPlugin-Dar8qRaj.mjs} +68 -11
  50. package/dist/events/index.d.mts +18 -297
  51. package/dist/events/index.mjs +7 -758
  52. package/dist/events/transports/redis-stream-entry.d.mts +1 -1
  53. package/dist/events/transports/redis-stream-entry.mjs +14 -10
  54. package/dist/events/transports/redis.d.mts +1 -1
  55. package/dist/events/transports/redis.mjs +1 -1
  56. package/dist/factory/index.d.mts +20 -5
  57. package/dist/factory/index.mjs +131 -8
  58. package/dist/fastify-augmentation-DVsTAy6X.d.mts +179 -0
  59. package/dist/{fields-CB5Cuzk9.mjs → fields-CojeUkS4.mjs} +6 -11
  60. package/dist/{generate-EcA6ui4i.mjs → generate-DiB0nHPR.mjs} +2 -2
  61. package/dist/{headers-3zvE0rM3.mjs → headers-CveNO9gR.mjs} +2 -2
  62. package/dist/{health-DjZYjM7H.mjs → health-CasG2A28.mjs} +1 -1
  63. package/dist/hooks/index.d.mts +1 -1
  64. package/dist/hooks/index.mjs +2 -2
  65. package/dist/idempotency/index.d.mts +45 -1
  66. package/dist/idempotency/index.mjs +95 -11
  67. package/dist/idempotency/redis.mjs +1 -1
  68. package/dist/{index-CEJNZFtX.d.mts → index-B-DvUzsr.d.mts} +82 -3
  69. package/dist/{index-CpzxqePp.d.mts → index-BcR2bFZQ.d.mts} +707 -373
  70. package/dist/{index-Bc2ox8_U.d.mts → index-Brin0ODU.d.mts} +4 -4
  71. package/dist/{index-CFThn1K9.d.mts → index-C5NnMEKF.d.mts} +70 -4
  72. package/dist/{index-C-481Zf2.d.mts → index-ugr1tQlW.d.mts} +17 -1
  73. package/dist/index.d.mts +6 -6
  74. package/dist/index.mjs +11 -11
  75. package/dist/{init-BEiNZBsJ.mjs → init-mdJ-v4Xp.mjs} +24 -16
  76. package/dist/integrations/event-gateway.d.mts +1 -1
  77. package/dist/integrations/event-gateway.mjs +2 -2
  78. package/dist/integrations/index.d.mts +2 -2
  79. package/dist/integrations/index.mjs +1 -1
  80. package/dist/integrations/jobs/index.d.mts +1 -1
  81. package/dist/integrations/jobs/index.mjs +100 -98
  82. package/dist/integrations/mcp/index.d.mts +12 -3
  83. package/dist/integrations/mcp/index.mjs +2 -2
  84. package/dist/integrations/mcp/testing.d.mts +1 -1
  85. package/dist/integrations/mcp/testing.mjs +2 -2
  86. package/dist/integrations/streamline.mjs +3 -3
  87. package/dist/integrations/webhooks.d.mts +124 -1
  88. package/dist/integrations/webhooks.mjs +180 -2
  89. package/dist/integrations/websocket-pushref-redis.mjs +1 -1
  90. package/dist/integrations/websocket-redis.mjs +1 -1
  91. package/dist/integrations/websocket.mjs +38 -35
  92. package/dist/{interface-DYzM0q-u.mjs → interface-DznJrm9R.mjs} +1 -1
  93. package/dist/{jsonBody-BYbLDi5D.mjs → jsonBody-CfGH-GxO.mjs} +2 -2
  94. package/dist/{keys-C0_pa1tY.mjs → keys-WeKvY1dE.mjs} +1 -1
  95. package/dist/{loadResources-yawi9tAE.mjs → loadResources-Bj-aSsXi.mjs} +4 -3
  96. package/dist/{loadResourcesFromEntry-BAjYZonx.mjs → loadResourcesFromEntry-DwaxNcE2.mjs} +2 -2
  97. package/dist/logger/index.mjs +1 -1
  98. package/dist/{mcpPlugin-B_es0hiF.mjs → mcpPlugin-aJg5TqHi.mjs} +76 -36
  99. package/dist/{memory-DR6wpa9F.mjs → memory-qYSB7rMQ.mjs} +5 -5
  100. package/dist/{metrics-CUdw_wLB.mjs → metrics-D7uchLjN.mjs} +2 -2
  101. package/dist/middleware/index.d.mts +1 -1
  102. package/dist/middleware/index.mjs +3 -3
  103. package/dist/migrations/index.mjs +3 -3
  104. package/dist/{module-0pFJA6YW.mjs → module-CwKsgZXp.mjs} +1 -1
  105. package/dist/{multipartBody-wOgj_fnj.mjs → multipartBody-4w-S3-PU.mjs} +3 -3
  106. package/dist/{openapi-B2L4js1v.mjs → openapi-BN5cQaO2.mjs} +6 -6
  107. package/dist/outbox-admin/index.d.mts +85 -0
  108. package/dist/outbox-admin/index.mjs +115 -0
  109. package/dist/outbox-module-CXB79bvt.mjs +839 -0
  110. package/dist/outbox-module-D-VFq37T.d.mts +368 -0
  111. package/dist/permissions/index.d.mts +3 -3
  112. package/dist/permissions/index.mjs +6 -6
  113. package/dist/{permissions-L--QDAir.mjs → permissions-BAfwgBxc.mjs} +120 -8
  114. package/dist/{pipe-DRDNsI2T.mjs → pipe-BzzoEhHj.mjs} +3 -5
  115. package/dist/pipeline/index.d.mts +1 -1
  116. package/dist/pipeline/index.mjs +2 -2
  117. package/dist/{pipeline-UPQFatit.mjs → pipeline-q69DZzgG.mjs} +17 -15
  118. package/dist/plugins/index.d.mts +6 -6
  119. package/dist/plugins/index.mjs +16 -16
  120. package/dist/plugins/response-cache.mjs +2 -2
  121. package/dist/plugins/tracing-entry.mjs +2 -2
  122. package/dist/{pluralize-O0FZgESl.mjs → pluralize-B7xf8qZF.mjs} +1 -1
  123. package/dist/{preloadResources-Dz6BjzM6.mjs → preloadResources-BkyqeTDz.mjs} +1 -1
  124. package/dist/{preloadResources-CyoJMSiO.d.mts → preloadResources-g07ldtzh.d.mts} +30 -7
  125. package/dist/presets/filesUpload.d.mts +2 -2
  126. package/dist/presets/filesUpload.mjs +6 -6
  127. package/dist/presets/index.d.mts +2 -2
  128. package/dist/presets/index.mjs +2 -2
  129. package/dist/presets/multiTenant.d.mts +1 -1
  130. package/dist/presets/multiTenant.mjs +3 -3
  131. package/dist/presets/search.d.mts +2 -2
  132. package/dist/presets/search.mjs +2 -2
  133. package/dist/{presets-C4-g4_4P.mjs → presets-D-h0uWtP.mjs} +6 -5
  134. package/dist/projection-BKM0Ui-s.mjs +42 -0
  135. package/dist/{queryCachePlugin-BZr8v46E.mjs → queryCachePlugin-DhsZ0ZIc.mjs} +50 -8
  136. package/dist/{rateLimit-CMPY5Qms.mjs → rateLimit-D4-ASwsI.mjs} +2 -2
  137. package/dist/{rateLimitKey-Dn5JNmkj.mjs → rateLimitKey-XngqVNEV.mjs} +1 -1
  138. package/dist/{realtime-C5NoxWFY.mjs → realtime-CTkv3O59.mjs} +10 -10
  139. package/dist/{redis-stream-qN6A-RFv.d.mts → redis-stream-mwLWlfHG.d.mts} +1 -1
  140. package/dist/{registerRoute-CBN84fc7.mjs → registerRoute-DNnd3vkz.mjs} +10 -8
  141. package/dist/registry/index.d.mts +3 -3
  142. package/dist/registry/index.mjs +3 -3
  143. package/dist/{registry-4213U4zb.mjs → registry-CLxCR5LF.mjs} +2 -2
  144. package/dist/{renewingLease-Dll8mGgc.mjs → renewingLease-BnWtbA2U.mjs} +1 -1
  145. package/dist/{replyHelpers-DIiZKGUt.mjs → replyHelpers-BSBVCwL3.mjs} +2 -2
  146. package/dist/{repositoryFilter-f9eAfq_l.mjs → repositoryFilter-DKny7PDn.mjs} +1 -1
  147. package/dist/{requestContext-2TxXOJ7T.mjs → requestContext-uYE35JxI.mjs} +1 -1
  148. package/dist/{rolldown-runtime-CUsjNX9R.mjs → rolldown-runtime-DNg-KNCk.mjs} +1 -1
  149. package/dist/runtimeCapabilities-Dm88DaTW.mjs +49 -0
  150. package/dist/{schedules-DdtlICTf.mjs → schedules-CAcZgia0.mjs} +3 -3
  151. package/dist/{schemaConverter-D--wdJM-.mjs → schemaConverter-XH1RZRyu.mjs} +1 -1
  152. package/dist/{schemaIR-Bm2enbnh.mjs → schemaIR-CDvclAew.mjs} +2 -2
  153. package/dist/schemas/index.mjs +1 -1
  154. package/dist/scim/index.mjs +2 -2
  155. package/dist/scope/index.mjs +5 -5
  156. package/dist/{scope-DHx5Fous.mjs → scope-BaWcqBvr.mjs} +4 -4
  157. package/dist/{simpleEqualityMatcher-DjQJ7FKA.mjs → simpleEqualityMatcher-Se8VrsaP.mjs} +1 -1
  158. package/dist/{sse-CUTo9y0X.mjs → sse-Cf0jUHsh.mjs} +7 -6
  159. package/dist/{sseStream-B_5XcVVd.mjs → sseStream-Bvpi-UXQ.mjs} +2 -2
  160. package/dist/{store-helpers-D1MP_gRG.mjs → store-helpers-B88p99Z2.mjs} +1 -1
  161. package/dist/{streaming-PSZwi8JV.mjs → streaming-DsT1B5zJ.mjs} +1 -1
  162. package/dist/{subscribe-helpers-C0Tb2aUp.mjs → subscribe-helpers-CLIOHsOK.mjs} +2 -2
  163. package/dist/sync/changelog.mjs +1 -1
  164. package/dist/testing/cleanupStoreContract.d.mts +1 -1
  165. package/dist/testing/cleanupStoreContract.mjs +12 -6
  166. package/dist/testing/index.d.mts +52 -13
  167. package/dist/testing/index.mjs +110 -40
  168. package/dist/testing/outboxStoreContract.d.mts +11 -2
  169. package/dist/testing/outboxStoreContract.mjs +110 -21
  170. package/dist/testing/storageContract.mjs +11 -6
  171. package/dist/{transactionContext-dAfBVUrk.mjs → transactionContext-BYtWnwAS.mjs} +1 -1
  172. package/dist/{typeGuards-B0ryPo3I.mjs → typeGuards-jjKJDN13.mjs} +1 -1
  173. package/dist/types/index.d.mts +3 -3
  174. package/dist/types/index.mjs +1 -1
  175. package/dist/types/storage.mjs +1 -1
  176. package/dist/{types-CBgvkp8O.d.mts → types-BcTumAz_.d.mts} +128 -18
  177. package/dist/{types-CwcUQ610.d.mts → types-BfC83KsP.d.mts} +15 -1
  178. package/dist/{types-Cys0ko9Z.mjs → types-CoqIRrkY.mjs} +4 -4
  179. package/dist/{types-C4QE8qnm.d.mts → types-DVLddu2q.d.mts} +144 -1
  180. package/dist/usage/index.d.mts +1 -1
  181. package/dist/usage/index.mjs +0 -0
  182. package/dist/{userHelpers-ChYJ6CdK.mjs → userHelpers-CWF5pbZD.mjs} +1 -1
  183. package/dist/utils/index.d.mts +57 -5
  184. package/dist/utils/index.mjs +12 -11
  185. package/dist/{utils-vL8BrDE2.mjs → utils-h1V_sT-t.mjs} +38 -7
  186. package/dist/{validate-_KbifpHF.mjs → validate-CdQlz52F.mjs} +2 -2
  187. package/dist/{versioning-D_rhHfZm.d.mts → versioning-DEs-_hFi.d.mts} +1 -1
  188. package/dist/{versioning-CHDTor3P.mjs → versioning-rZbyLVD-.mjs} +4 -4
  189. package/package.json +31 -20
  190. package/skills/arc/SKILL.md +96 -4
  191. package/skills/arc/references/api-reference.md +19 -0
  192. package/skills/arc/references/production.md +2 -2
  193. package/dist/fastify-augmentation-zh0_AYHa.d.mts +0 -85
  194. package/dist/projection-BHw6xlOQ.mjs +0 -18
@@ -1,12 +1,12 @@
1
1
 
2
- import { C as RequestContext, Et as ActionDefinition, F as FastifyWithDecorators, H as CrudController, L as RequestWithExtras, Lt as IController, Rt as IControllerResponse, T as CrudRouterOptions, U as ResourceConfig, V as ResourceDefinition, et as RouteSchemaOptions, jt as RouteMcpConfig, tt as ArcFieldRule, ut as AggregationConfig, zt as IRequestContext } from "./index-CpzxqePp.mjs";
3
2
  import { i as RequestScope } from "./types-ChuShpCP.mjs";
4
- import { l as AnyRecord, r as PermissionCheck } from "./types-B7XeLEgK.mjs";
5
- import "./fastify-augmentation-zh0_AYHa.mjs";
3
+ import { l as PermissionCheck, t as AnyRecord } from "./base-Csjc2oF-.mjs";
4
+ import { C as RequestContext, Et as ActionDefinition, F as FastifyWithDecorators, Fn as IControllerResponse, H as CrudController, In as IRequestContext, L as RequestWithExtras, Pn as IController, T as CrudRouterOptions, U as ResourceConfig, V as ResourceDefinition, et as RouteSchemaOptions, jt as RouteMcpConfig, tt as ArcFieldRule, ut as AggregationConfig } from "./index-BcR2bFZQ.mjs";
5
+ import "./fastify-augmentation-DVsTAy6X.mjs";
6
+ import { AggDateBucket, AggMeasure, AggTopN } from "@classytic/repo-core/repository";
6
7
  import { FastifyReply, FastifyRequest, RouteHandlerMethod } from "fastify";
7
8
  import { z } from "zod";
8
9
  import { DataAdapter } from "@classytic/repo-core/adapter";
9
- import { AggDateBucket, AggMeasure, AggTopN } from "@classytic/repo-core/repository";
10
10
  import { LookupSpec } from "@classytic/repo-core/lookup";
11
11
  //#region src/constants.d.ts
12
12
  /**
@@ -1,5 +1,5 @@
1
1
 
2
- import { a as ModuleContribution, h as HealthCheck, n as ArcModuleInput, r as ArcModuleRegistry, t as ArcModule, u as ScheduleDefinition } from "./types-CBgvkp8O.mjs";
2
+ import { _ as HealthCheck, a as ModuleContribution, f as ScheduleDefinition, n as ArcModuleInput, r as ArcModuleRegistry, s as ModuleSetupContext, t as ArcModule } from "./types-BcTumAz_.mjs";
3
3
  import { FastifyInstance } from "fastify";
4
4
  //#region src/factory/module/contributions.d.ts
5
5
  /**
@@ -25,7 +25,67 @@ declare function collectModuleWorkflows(fastify: FastifyInstance, modules: reado
25
25
  * modules. The caller passes the returned definitions to the canonical
26
26
  * schedules plugin; factories must therefore be resolved only once.
27
27
  */
28
- declare function collectModuleScheduledJobs(fastify: FastifyInstance, modules: readonly ArcModule[]): Promise<ScheduleDefinition[]>;
28
+ declare function collectModuleScheduledJobs(fastify: FastifyInstance, modules: readonly ArcModule[],
29
+ /**
30
+ * Optional sink for per-module counts, filled as each arm resolves.
31
+ *
32
+ * Exists so `arc.moduleDescriptors` can report real numbers without
33
+ * resolving the factories a SECOND time — a contribution factory closes over
34
+ * booted engines and may register or allocate, so running it twice is not a
35
+ * free read. One resolution feeds both activation and introspection.
36
+ */
37
+ countsByModule?: Map<string, number>): Promise<ScheduleDefinition[]>;
38
+ //#endregion
39
+ //#region src/factory/module/extend.d.ts
40
+ /**
41
+ * What a caller may add. Every mergeable arm of `ArcModule`, plus `bootstrap`
42
+ * in wrapper form only.
43
+ *
44
+ * `name` is absent on purpose: renaming a module mid-composition breaks the
45
+ * `dependsOn` graph and the registry key its consumers read, and it is the one
46
+ * "extension" that is never additive.
47
+ */
48
+ interface ModuleExtension<TExports = unknown> {
49
+ dependsOn?: readonly string[];
50
+ owns?: readonly string[] | "provided";
51
+ resources?: ArcModule<TExports>["resources"];
52
+ eventHandlers?: ArcModule<TExports>["eventHandlers"];
53
+ scheduledJobs?: ArcModule<TExports>["scheduledJobs"];
54
+ workflows?: ArcModule<TExports>["workflows"];
55
+ healthChecks?: ArcModule<TExports>["healthChecks"];
56
+ errorMappers?: ArcModule<TExports>["errorMappers"];
57
+ plugins?: ArcModule<TExports>["plugins"];
58
+ afterResources?: ArcModule<TExports>["afterResources"];
59
+ onClose?: ArcModule<TExports>["onClose"];
60
+ /**
61
+ * WRAP the module's bootstrap — it is never replaced.
62
+ *
63
+ * Bootstrap returns the module's exports, so two of them cannot be
64
+ * concatenated: one value has to win, and a host silently winning is the gym
65
+ * failure (`{ ...mod, bootstrap }` overwrote the factory's own, so the engine
66
+ * the module published was never created). The wrapper form makes the
67
+ * relationship explicit — call `inner` and decorate its result, or
68
+ * deliberately do not.
69
+ *
70
+ * `inner` is `undefined` when the module has no bootstrap of its own.
71
+ */
72
+ bootstrap?: (inner: ((f: FastifyInstance, c: ModuleSetupContext) => TExports | Promise<TExports>) | undefined) => (f: FastifyInstance, c: ModuleSetupContext) => TExports | Promise<TExports>;
73
+ }
74
+ /**
75
+ * Merge a host's additions onto a module. Nothing the module declared is lost.
76
+ *
77
+ * ```ts
78
+ * return extendModule(createOrderModule({ … }), {
79
+ * eventHandlers: () => hostHandlers(), // appended after the module's
80
+ * dependsOn: ["outbox"], // unioned
81
+ * bootstrap: (inner) => async (f, c) => { // wraps, never replaces
82
+ * const exports = await inner?.(f, c);
83
+ * return decorate(exports);
84
+ * },
85
+ * });
86
+ * ```
87
+ */
88
+ declare function extendModule<TExports = unknown>(mod: ArcModule<TExports>, extension: ModuleExtension<TExports>): ArcModule<TExports>;
29
89
  //#endregion
30
90
  //#region src/factory/module/lifecycle.d.ts
31
91
  /**
@@ -38,7 +98,13 @@ declare function collectModuleScheduledJobs(fastify: FastifyInstance, modules: r
38
98
  * Resolves factory contributions (after bootstraps) so a handler can close over
39
99
  * booted engines rather than a global getter.
40
100
  */
41
- declare function subscribeModuleEventHandlers(fastify: FastifyInstance, modules: readonly ArcModule[]): Promise<Array<() => void | Promise<void>>>;
101
+ declare function subscribeModuleEventHandlers(fastify: FastifyInstance, modules: readonly ArcModule[],
102
+ /**
103
+ * Optional sink for per-module handler counts, filled as each arm resolves.
104
+ * Lets `arc.moduleDescriptors` report real numbers without resolving the
105
+ * factories a SECOND time — see the note on `collectModuleScheduledJobs`.
106
+ */
107
+ countsByModule?: Map<string, number>): Promise<Array<() => void | Promise<void>>>;
42
108
  //#endregion
43
109
  //#region src/factory/module/order.d.ts
44
110
  /**
@@ -221,4 +287,4 @@ declare function lazyModuleExports<TExports = unknown>(fastify: FastifyInstance,
221
287
  declare function lazyRequiredModuleExports<K extends keyof ArcModuleRegistry>(fastify: FastifyInstance, name: K): () => ArcModuleRegistry[K];
222
288
  declare function lazyRequiredModuleExports<TExports = unknown>(fastify: FastifyInstance, name: string): () => TExports;
223
289
  //#endregion
224
- export { lazyModuleExports as a, getModuleState as c, resolveModule as d, orderModules as f, collectModuleWorkflows as g, collectModuleScheduledJobs as h, hasModuleExports as i, hasModule as l, collectModuleHealthChecks as m, getModuleExports as n, lazyRequiredModuleExports as o, subscribeModuleEventHandlers as p, getOptionalModuleExports as r, ModuleState as s, defineModule as t, resolveContribution as u };
290
+ export { collectModuleScheduledJobs as _, lazyModuleExports as a, getModuleState as c, resolveModule as d, orderModules as f, collectModuleHealthChecks as g, extendModule as h, hasModuleExports as i, hasModule as l, ModuleExtension as m, getModuleExports as n, lazyRequiredModuleExports as o, subscribeModuleEventHandlers as p, getOptionalModuleExports as r, ModuleState as s, defineModule as t, resolveContribution as u, collectModuleWorkflows as v };
@@ -1,5 +1,5 @@
1
1
 
2
- import { r as PermissionCheck } from "./types-B7XeLEgK.mjs";
2
+ import { l as PermissionCheck } from "./base-Csjc2oF-.mjs";
3
3
  import { FastifyPluginAsync } from "fastify";
4
4
  //#region src/integrations/jobs/execution.d.ts
5
5
  /**
@@ -165,6 +165,22 @@ interface JobsPluginOptions {
165
165
  } | unknown;
166
166
  /** Job definitions to register */
167
167
  jobs: JobDefinition[];
168
+ /**
169
+ * Which HALF of the queue this process owns. Phase 2 of the topology plan:
170
+ * an API replica that merely registered the plugin should not consume jobs.
171
+ *
172
+ * - `'both'` (default) — queues AND workers; the single-process case.
173
+ * - `'producer'` — queues only: `dispatch()` works, NO worker is
174
+ * constructed, handlers never run here. For API fleets.
175
+ * - `'worker'` — workers AND queues (a worker needs its queue for DLQ +
176
+ * dispatch-from-handler), HTTP dispatch still possible but the point is
177
+ * consumption. For dedicated worker fleets.
178
+ *
179
+ * Repeatable schedules are registered by whichever side constructs
180
+ * WORKERS — a producer-only process must not own schedule reconciliation
181
+ * it cannot execute.
182
+ */
183
+ mode?: "both" | "producer" | "worker";
168
184
  /** URL prefix for job management endpoints (default: '/jobs') */
169
185
  prefix?: string;
170
186
  /**
package/dist/index.d.mts CHANGED
@@ -1,12 +1,12 @@
1
1
 
2
- import { $t as TreeMixin, A as RequestIdOptions, An as BaseControllerOptions, B as defineResource, Bt as RawRouteHandler, C as RequestContext, D as HealthCheck, Dn as ArcGetResult, E as GracefulShutdownOptions, En as ArcDeleteResult, F as FastifyWithDecorators, Ft as ControllerLike, H as CrudController, L as RequestWithExtras, Lt as IController, Mn as ControllerConstructionOptions, N as FastifyRequestExtras, Nn as ListResult, Nt as RateLimitConfig, O as HealthOptions, On as ArcListResult, P as FastifyWithAuth, Q as MiddlewareConfig, Qt as TreeExt, Rt as IControllerResponse, S as QueryParserInterface, T as CrudRouterOptions, Tn as ArcCreateResult, U as ResourceConfig, V as ResourceDefinition, Vt as RouteHandler, Wt as AuthPluginOptions, X as CrudRouteKey, Xt as SoftDeleteExt, Y as PresetResult, Yt as BaseController, Z as CrudSchemas, Zt as SoftDeleteMixin, a as InferAdapterDoc, c as TypedController, ct as AggMeasureShorthand, d as PaginationResult, dt as AggregationDateRangeRequirement, en as SlugExt, et as RouteSchemaOptions, f as IntrospectionData, ft as AggregationIndexHint, g as ArcInternalMetadata, gt as AggregationsMap, h as ResourceMetadata, ht as AggregationRateLimit, i as ValidationResult, in as BaseCrudController, jn as ControllerConfigurableOptions, k as IntrospectionPluginOptions, kn as ArcUpdateResult, l as TypedRepository, lt as AggregationCacheConfig, m as RegistryStats, mt as AggregationMaterializedResult, n as ConfigError, nn as BulkExt, nt as FieldRule, o as InferDocType, ot as EventDefinition, p as RegistryEntry, pt as AggregationMaterializedContext, q as PresetFunction, r as ValidateOptions, rn as BulkMixin, s as InferResourceDoc, st as AggMeasureInput, t as RouteHandlerMethod, tn as SlugMixin, u as TypedResourceConfig, ut as AggregationConfig, w as ServiceContext, y as OwnershipCheck, zt as IRequestContext } from "./index-CpzxqePp.mjs";
3
- import { a as UserBase, d as JWTPayload, i as PermissionContext, l as AnyRecord, m as UserOrganization, n as DataPolicy, r as PermissionCheck, t as AuthorizationDecision, u as ArcRequest } from "./types-B7XeLEgK.mjs";
2
+ import { c as DataPolicy, d as UserBase, l as PermissionCheck, n as ArcRequest, o as UserOrganization, r as JWTPayload, s as AuthorizationDecision, t as AnyRecord, u as PermissionContext } from "./base-Csjc2oF-.mjs";
3
+ import { A as RequestIdOptions, An as WriteVerbKey, B as defineResource, Bt as BaseController, C as RequestContext, Cn as ControllerConstructionOptions, D as HealthCheck, Dn as MutationWriteContext, E as GracefulShutdownOptions, F as FastifyWithDecorators, Fn as IControllerResponse, Ft as AuthPluginOptions, Gt as SlugExt, H as CrudController, Ht as SoftDeleteMixin, In as IRequestContext, Jt as BulkMixin, Kt as SlugMixin, L as RequestWithExtras, Ln as RawRouteHandler, Mn as ControllerLike, N as FastifyRequestExtras, Nt as RateLimitConfig, O as HealthOptions, On as ResourceWrites, P as FastifyWithAuth, Pn as IController, Q as MiddlewareConfig, Rn as RouteHandler, S as QueryParserInterface, Sn as ControllerConfigurableOptions, T as CrudRouterOptions, U as ResourceConfig, Ut as TreeExt, V as ResourceDefinition, Vt as SoftDeleteExt, Wt as TreeMixin, X as CrudRouteKey, Y as PresetResult, Yt as BaseCrudController, Z as CrudSchemas, _n as ArcDeleteResult, a as InferAdapterDoc, bn as ArcUpdateResult, c as TypedController, ct as AggMeasureShorthand, d as PaginationResult, dt as AggregationDateRangeRequirement, et as RouteSchemaOptions, f as IntrospectionData, ft as AggregationIndexHint, g as ArcInternalMetadata, gn as ArcCreateResult, gt as AggregationsMap, h as ResourceMetadata, ht as AggregationRateLimit, i as ValidationResult, k as IntrospectionPluginOptions, kn as WriteContext, l as TypedRepository, lt as AggregationCacheConfig, m as RegistryStats, mt as AggregationMaterializedResult, n as ConfigError, nt as FieldRule, o as InferDocType, ot as EventDefinition, p as RegistryEntry, pt as AggregationMaterializedContext, q as PresetFunction, qt as BulkExt, r as ValidateOptions, s as InferResourceDoc, st as AggMeasureInput, t as RouteHandlerMethod, u as TypedResourceConfig, ut as AggregationConfig, vn as ArcGetResult, w as ServiceContext, wn as ListResult, xn as BaseControllerOptions, y as OwnershipCheck, yn as ArcListResult } from "./index-BcR2bFZQ.mjs";
4
4
  import { a as applyFieldWritePermissions, i as applyFieldReadPermissions, n as FieldPermissionMap, o as fields, t as FieldPermission } from "./fields-I_EeRWND.mjs";
5
- import "./fastify-augmentation-zh0_AYHa.mjs";
6
- import { A as DEFAULT_ID_FIELD, B as MAX_FILTER_DEPTH, D as defineAggregation, F as DEFAULT_UPDATE_METHOD, G as RESERVED_QUERY_PARAMS, H as MAX_SEARCH_LENGTH, I as HOOK_OPERATIONS, K as SYSTEM_FIELDS, L as HOOK_PHASES, M as DEFAULT_MAX_LIMIT, N as DEFAULT_SORT, O as CRUD_OPERATIONS, P as DEFAULT_TENANT_FIELD, R as HookOperation, S as mergeResourceConfig, U as MUTATION_OPERATIONS, V as MAX_REGEX_LENGTH, W as MutationOperation, b as ResourceSeams, j as DEFAULT_LIMIT, k as CrudOperation, p as getControllerScope, v as defineResourceVariants, w as defineAction, x as SeamedResourceConfig, y as AdapterLike, z as HookPhase } from "./index-Bc2ox8_U.mjs";
7
- import { B as anyOf, F as createDynamicPermissionMatrix, G as requireOwnership, H as denyAll, I as createOrgPermissions, L as allOf, M as DynamicPermissionMatrix, N as DynamicPermissionMatrixConfig, W as requireAuth, Y as when, c as publicReadAdminWrite, d as requireOrgMembership, f as requireOrgRole, h as requireTeamMembership, i as ownerWithAdminBypass, l as readOnly, m as requireServiceScope, n as authenticated, o as presets_d_exports, p as requireScopeContext, q as requireRoles, r as fullPublic, s as publicRead, t as adminOnly, u as requireOrgInScope, z as allowPublic } from "./index-CEJNZFtX.mjs";
5
+ import "./fastify-augmentation-DVsTAy6X.mjs";
6
+ import { A as DEFAULT_ID_FIELD, B as MAX_FILTER_DEPTH, D as defineAggregation, F as DEFAULT_UPDATE_METHOD, G as RESERVED_QUERY_PARAMS, H as MAX_SEARCH_LENGTH, I as HOOK_OPERATIONS, K as SYSTEM_FIELDS, L as HOOK_PHASES, M as DEFAULT_MAX_LIMIT, N as DEFAULT_SORT, O as CRUD_OPERATIONS, P as DEFAULT_TENANT_FIELD, R as HookOperation, S as mergeResourceConfig, U as MUTATION_OPERATIONS, V as MAX_REGEX_LENGTH, W as MutationOperation, b as ResourceSeams, j as DEFAULT_LIMIT, k as CrudOperation, p as getControllerScope, v as defineResourceVariants, w as defineAction, x as SeamedResourceConfig, y as AdapterLike, z as HookPhase } from "./index-Brin0ODU.mjs";
7
+ import { $ as requireAuth, C as requireServiceScope, G as createOrgPermissions, H as DynamicPermissionMatrixConfig, J as allowPublic, K as allOf, S as requireScopeContext, V as DynamicPermissionMatrix, W as createDynamicPermissionMatrix, Y as anyOf, Z as denyAll, _ as publicReadAdminWrite, b as requireOrgMembership, d as authenticated, et as requireOwnership, f as fullPublic, g as publicRead, h as presets_d_exports, it as when, nt as requireRoles, p as ownerWithAdminBypass, u as adminOnly, v as readOnly, w as requireTeamMembership, x as requireOrgRole, y as requireOrgInScope } from "./index-B-DvUzsr.mjs";
8
8
  import { a as NotFoundError, d as ValidationError, f as createDomainError, i as ForbiddenError, t as ArcError, u as UnauthorizedError } from "./errors-BGdVwP25.mjs";
9
9
  //#region src/index.d.ts
10
10
  declare const version: string;
11
11
  //#endregion
12
- export { type AdapterLike, type AggMeasureInput, type AggMeasureShorthand, type AggregationCacheConfig, type AggregationConfig, type AggregationDateRangeRequirement, type AggregationIndexHint, type AggregationMaterializedContext, type AggregationMaterializedResult, type AggregationRateLimit, type AggregationsMap, type AnyRecord, type ArcCreateResult, type ArcDeleteResult, ArcError, type ArcGetResult, type ArcInternalMetadata, type ArcListResult, type ArcRequest, type ArcUpdateResult, type AuthPluginOptions, type AuthorizationDecision, BaseController, type BaseControllerOptions, BaseCrudController, type BulkExt, BulkMixin, CRUD_OPERATIONS, type ConfigError, type ControllerConfigurableOptions, type ControllerConstructionOptions, type ControllerLike, type CrudController, type CrudOperation, type CrudRouteKey, type CrudRouterOptions, type CrudSchemas, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, type DataPolicy, type DynamicPermissionMatrix, type DynamicPermissionMatrixConfig, type EventDefinition, type FastifyRequestExtras, type FastifyWithAuth, type FastifyWithDecorators, type FieldPermission, type FieldPermissionMap, type FieldRule, ForbiddenError, type GracefulShutdownOptions, HOOK_OPERATIONS, HOOK_PHASES, type HealthCheck, type HealthOptions, type HookOperation, type HookPhase, type IController, type IControllerResponse, type IRequestContext, type InferAdapterDoc, type InferDocType, type InferResourceDoc, type IntrospectionData, type IntrospectionPluginOptions, type JWTPayload, type ListResult, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, type MiddlewareConfig, type MutationOperation, NotFoundError, type OwnershipCheck, type PaginationResult, type PermissionCheck, type PermissionContext, type PresetFunction, type PresetResult, type QueryParserInterface, RESERVED_QUERY_PARAMS, type RateLimitConfig, type RawRouteHandler, type RegistryEntry, type RegistryStats, type RequestContext, type RequestIdOptions, type RequestWithExtras, type ResourceConfig, ResourceDefinition, type ResourceMetadata, type ResourceSeams, type RouteHandler, type RouteHandlerMethod, type RouteSchemaOptions, SYSTEM_FIELDS, type SeamedResourceConfig, type ServiceContext, type SlugExt, SlugMixin, type SoftDeleteExt, SoftDeleteMixin, type TreeExt, TreeMixin, type TypedController, type TypedRepository, type TypedResourceConfig, UnauthorizedError, type UserBase, type UserOrganization, type ValidateOptions, ValidationError, type ValidationResult, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, authenticated, createDomainError, createDynamicPermissionMatrix, createOrgPermissions, defineAction, defineAggregation, defineResource, defineResourceVariants, denyAll, fields, fullPublic, getControllerScope, mergeResourceConfig, ownerWithAdminBypass, presets_d_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAuth, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, version, when };
12
+ export { type AdapterLike, type AggMeasureInput, type AggMeasureShorthand, type AggregationCacheConfig, type AggregationConfig, type AggregationDateRangeRequirement, type AggregationIndexHint, type AggregationMaterializedContext, type AggregationMaterializedResult, type AggregationRateLimit, type AggregationsMap, type AnyRecord, type ArcCreateResult, type ArcDeleteResult, ArcError, type ArcGetResult, type ArcInternalMetadata, type ArcListResult, type ArcRequest, type ArcUpdateResult, type AuthPluginOptions, type AuthorizationDecision, BaseController, type BaseControllerOptions, BaseCrudController, type BulkExt, BulkMixin, CRUD_OPERATIONS, type ConfigError, type ControllerConfigurableOptions, type ControllerConstructionOptions, type ControllerLike, type CrudController, type CrudOperation, type CrudRouteKey, type CrudRouterOptions, type CrudSchemas, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, type DataPolicy, type DynamicPermissionMatrix, type DynamicPermissionMatrixConfig, type EventDefinition, type FastifyRequestExtras, type FastifyWithAuth, type FastifyWithDecorators, type FieldPermission, type FieldPermissionMap, type FieldRule, ForbiddenError, type GracefulShutdownOptions, HOOK_OPERATIONS, HOOK_PHASES, type HealthCheck, type HealthOptions, type HookOperation, type HookPhase, type IController, type IControllerResponse, type IRequestContext, type InferAdapterDoc, type InferDocType, type InferResourceDoc, type IntrospectionData, type IntrospectionPluginOptions, type JWTPayload, type ListResult, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, type MiddlewareConfig, type MutationOperation, type MutationWriteContext, NotFoundError, type OwnershipCheck, type PaginationResult, type PermissionCheck, type PermissionContext, type PresetFunction, type PresetResult, type QueryParserInterface, RESERVED_QUERY_PARAMS, type RateLimitConfig, type RawRouteHandler, type RegistryEntry, type RegistryStats, type RequestContext, type RequestIdOptions, type RequestWithExtras, type ResourceConfig, ResourceDefinition, type ResourceMetadata, type ResourceSeams, type ResourceWrites, type RouteHandler, type RouteHandlerMethod, type RouteSchemaOptions, SYSTEM_FIELDS, type SeamedResourceConfig, type ServiceContext, type SlugExt, SlugMixin, type SoftDeleteExt, SoftDeleteMixin, type TreeExt, TreeMixin, type TypedController, type TypedRepository, type TypedResourceConfig, UnauthorizedError, type UserBase, type UserOrganization, type ValidateOptions, ValidationError, type ValidationResult, type WriteContext, type WriteVerbKey, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, authenticated, createDomainError, createDynamicPermissionMatrix, createOrgPermissions, defineAction, defineAggregation, defineResource, defineResourceVariants, denyAll, fields, fullPublic, getControllerScope, mergeResourceConfig, ownerWithAdminBypass, presets_d_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAuth, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, version, when };
package/dist/index.mjs CHANGED
@@ -1,14 +1,14 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { a as DEFAULT_SORT, c as HOOK_OPERATIONS, d as MAX_REGEX_LENGTH, f as MAX_SEARCH_LENGTH, h as SYSTEM_FIELDS, i as DEFAULT_MAX_LIMIT, l as HOOK_PHASES, m as RESERVED_QUERY_PARAMS, n as DEFAULT_ID_FIELD, o as DEFAULT_TENANT_FIELD, p as MUTATION_OPERATIONS, r as DEFAULT_LIMIT, s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS, u as MAX_FILTER_DEPTH } from "./constants-D3Dv4LAV.mjs";
3
- import { d as createDomainError, i as NotFoundError, l as UnauthorizedError, r as ForbiddenError, t as ArcError, u as ValidationError } from "./errors-Cj42AntO.mjs";
4
- import { a as BulkMixin, i as SlugMixin, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, t as BaseController } from "./BaseController-De7GqHck.mjs";
5
- import { n as applyFieldWritePermissions, r as fields, t as applyFieldReadPermissions } from "./fields-CB5Cuzk9.mjs";
6
- import { a as ResourceDefinition, t as defineResource } from "./defineResource-Bv6EtN1x.mjs";
7
- import { c as getControllerScope } from "./pipeline-UPQFatit.mjs";
8
- import { t as defineAggregation } from "./defineAggregation-DbPPS8RI.mjs";
9
- import { a as mergeResourceConfig, i as defineResourceVariants, o as defineAction } from "./core-BGpIxINN.mjs";
10
- import { C as requireScopeContext, I as requireAuth, L as requireOwnership, M as anyOf, P as denyAll, S as requireOrgRole, T as requireTeamMembership, V as when, b as requireOrgInScope, c as publicReadAdminWrite, i as ownerWithAdminBypass, j as allowPublic, k as allOf, l as readOnly, n as authenticated, o as presets_exports, r as fullPublic, s as publicRead, t as adminOnly, v as createDynamicPermissionMatrix, w as requireServiceScope, x as requireOrgMembership, y as createOrgPermissions, z as requireRoles } from "./permissions-L--QDAir.mjs";
1
+ /*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
2
+ import { a as DEFAULT_SORT, c as HOOK_OPERATIONS, d as MAX_REGEX_LENGTH, f as MAX_SEARCH_LENGTH, h as SYSTEM_FIELDS, i as DEFAULT_MAX_LIMIT, l as HOOK_PHASES, m as RESERVED_QUERY_PARAMS, n as DEFAULT_ID_FIELD, o as DEFAULT_TENANT_FIELD, p as MUTATION_OPERATIONS, r as DEFAULT_LIMIT, s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS, u as MAX_FILTER_DEPTH } from "./constants-BxCoxmiN.mjs";
3
+ import { d as createDomainError, i as NotFoundError, l as UnauthorizedError, r as ForbiddenError, t as ArcError, u as ValidationError } from "./errors-Cd_yy7aW.mjs";
4
+ import { a as BulkMixin, i as SlugMixin, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, t as BaseController } from "./BaseController-CaQC5EXX.mjs";
5
+ import { n as applyFieldWritePermissions, r as fields, t as applyFieldReadPermissions } from "./fields-CojeUkS4.mjs";
6
+ import { a as ResourceDefinition, t as defineResource } from "./defineResource-DR9vsUYy.mjs";
7
+ import { c as getControllerScope } from "./pipeline-q69DZzgG.mjs";
8
+ import { t as defineAggregation } from "./defineAggregation-Nv-DwfOf.mjs";
9
+ import { a as mergeResourceConfig, i as defineResourceVariants, o as defineAction } from "./core-dxhcHhUD.mjs";
10
+ import { B as requireAuth, C as createOrgPermissions, D as requireScopeContext, E as requireOrgRole, F as allowPublic, G as when, I as anyOf, N as allOf, O as requireServiceScope, R as denyAll, S as createDynamicPermissionMatrix, T as requireOrgMembership, U as requireRoles, V as requireOwnership, a as adminOnly, c as ownerWithAdminBypass, d as publicRead, f as publicReadAdminWrite, k as requireTeamMembership, o as authenticated, p as readOnly, s as fullPublic, u as presets_exports, w as requireOrgInScope } from "./permissions-BAfwgBxc.mjs";
11
11
  //#region src/index.ts
12
- const version = "2.31.0";
12
+ const version = "2.34.0";
13
13
  //#endregion
14
14
  export { ArcError, BaseController, BaseCrudController, BulkMixin, CRUD_OPERATIONS, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, ForbiddenError, HOOK_OPERATIONS, HOOK_PHASES, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, NotFoundError, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, SlugMixin, SoftDeleteMixin, TreeMixin, UnauthorizedError, ValidationError, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, authenticated, createDomainError, createDynamicPermissionMatrix, createOrgPermissions, defineAction, defineAggregation, defineResource, defineResourceVariants, denyAll, fields, fullPublic, getControllerScope, mergeResourceConfig, ownerWithAdminBypass, presets_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAuth, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, version, when };
@@ -1,4 +1,4 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
2
2
  import * as fs from "node:fs/promises";
3
3
  import * as path from "node:path";
4
4
  import { dirname, join } from "node:path";
@@ -30,9 +30,9 @@ import { execSync, spawn } from "node:child_process";
30
30
  */
31
31
  const SCAFFOLD_DEP_VERSIONS = {
32
32
  core: {
33
- "@classytic/arc": "^2.20.0",
34
- "@classytic/primitives": "^0.11.0",
35
- "@classytic/repo-core": "^0.8.0",
33
+ "@classytic/arc": "^2.33.0",
34
+ "@classytic/primitives": "^0.21.0",
35
+ "@classytic/repo-core": "^0.21.0",
36
36
  "@fastify/cors": "^11.2.0",
37
37
  "@fastify/helmet": "^13.0.2",
38
38
  "@fastify/rate-limit": "^10.3.0",
@@ -997,7 +997,7 @@ export async function updateUserProfile(request${ts ? ": FastifyRequest" : ""},
997
997
  delete updates.role;
998
998
  delete updates.organizations;
999
999
 
1000
- const user = await userRepository.Model.findByIdAndUpdate(userId, updates, { new: true });
1000
+ const user = await userRepository.Model.findByIdAndUpdate(userId, updates, { returnDocument: 'after' });
1001
1001
  return reply.send(user);
1002
1002
  } catch (error) {
1003
1003
  request.log.error({ err: error }, 'Update profile error');
@@ -1700,16 +1700,22 @@ function configTemplate(config) {
1700
1700
  * by config/env.${ts ? "ts" : "js"} (imported first in the entry points).
1701
1701
  */
1702
1702
 
1703
+ import { classifyEnv } from '@classytic/primitives/environment';
1703
1704
  import { z } from 'zod';
1704
1705
 
1705
- // Normalize NODE_ENV to the three canonical values the rest of the app
1706
- // reasons about (matches the env loader's prod/dev/test aliasing).
1707
- const NodeEnv = z.preprocess((v) => {
1708
- const s = String(v ?? '').toLowerCase();
1709
- if (s === 'prod' || s === 'production') return 'production';
1710
- if (s === 'test' || s === 'qa') return 'test';
1711
- return 'development';
1712
- }, z.enum(['development', 'production', 'test']));
1706
+ // NODE_ENV normalized to the three canonical values the rest of the app reasons about.
1707
+ //
1708
+ // \`classifyEnv\` is the SHARED classifier (a required arc peer, so it is already installed). It
1709
+ // accepts both spellings of each bucket — \`production\`/\`prod\` and \`test\`/\`qa\` — and trims
1710
+ // surrounding whitespace. Do not replace it with \`process.env.NODE_ENV === 'production'\`
1711
+ // anywhere in this app: that comparison knows only one spelling, and because almost every call
1712
+ // site asks the NEGATIVE question ("not production ⇒ relax"), the miss OPENS the relaxed path on
1713
+ // a real production deployment. That exact shape has shipped stack traces to clients, session
1714
+ // cookies without \`Secure\`, and non-transactional money writes.
1715
+ const NodeEnv = z.preprocess(
1716
+ (v) => classifyEnv(typeof v === 'string' ? v : undefined),
1717
+ z.enum(['development', 'production', 'test']),
1718
+ );
1713
1719
 
1714
1720
  const EnvSchema = z
1715
1721
  .object({
@@ -2379,7 +2385,8 @@ export const requireAdmin = ()${returnType} =>
2379
2385
  export const requireSuperadmin = ()${returnType} =>
2380
2386
  requireRoles(['superadmin']);
2381
2387
  `;
2382
- if (config.tenant === "multi") if (config.auth === "better-auth") content += `
2388
+ if (config.tenant === "multi") {
2389
+ if (config.auth === "better-auth") content += `
2383
2390
  // ============================================================================
2384
2391
  // Better Auth Organization & Team Permission Helpers
2385
2392
  // ============================================================================
@@ -2431,7 +2438,7 @@ export const requireOrgManager = ()${returnType} =>
2431
2438
  export const requireOrgStaff = ()${returnType} =>
2432
2439
  requireOrgMembership();
2433
2440
  `;
2434
- else content += `
2441
+ else content += `
2435
2442
  /**
2436
2443
  * Require organization owner (elevated scope auto-bypasses)
2437
2444
  */
@@ -2450,6 +2457,7 @@ export const requireOrgManager = ()${returnType} =>
2450
2457
  export const requireOrgStaff = ()${returnType} =>
2451
2458
  requireRoles(['owner', 'manager', 'staff', 'admin', 'superadmin']);
2452
2459
  `;
2460
+ }
2453
2461
  content += `
2454
2462
  // ============================================================================
2455
2463
  // Standard Permission Sets
@@ -3016,7 +3024,7 @@ class UserRepository extends Repository${ts ? "<UserDocument>" : ""} {
3016
3024
  return this.Model.findByIdAndUpdate(
3017
3025
  userId,
3018
3026
  { resetPasswordToken: token, resetPasswordExpires: expiresAt },
3019
- { new: true }
3027
+ { returnDocument: 'after' }
3020
3028
  );
3021
3029
  }
3022
3030
  ${config.tenant === "multi" ? `
@@ -1,5 +1,5 @@
1
1
 
2
- import { n as DomainEvent } from "../EventTransport-2uVV34WU.mjs";
2
+ import { n as DomainEvent } from "../EventTransport-BEVP50ka.mjs";
3
3
  import { c as WebSocketClient, l as WebSocketMessage } from "../websocket-BOXVggMf.mjs";
4
4
  import { FastifyPluginAsync, FastifyRequest } from "fastify";
5
5
  //#region src/integrations/event-gateway.d.ts
@@ -1,11 +1,11 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
2
2
  import fp from "fastify-plugin";
3
3
  //#region src/integrations/event-gateway.ts
4
4
  const eventGatewayPluginImpl = async (fastify, opts = {}) => {
5
5
  const { auth = true, orgScoped = false, roomPolicy, maxMessageBytes, maxSubscriptionsPerClient, authenticate } = opts;
6
6
  if (auth && !authenticate && !fastify.hasDecorator("authenticate")) throw new Error("[arc-event-gateway] auth is true but fastify.authenticate is not registered. Register an auth plugin first, provide a custom authenticate function, or set auth: false.");
7
7
  if (opts.sse !== false) {
8
- const { default: ssePlugin } = await import("../sse-CUTo9y0X.mjs").then((n) => n.r);
8
+ const { default: ssePlugin } = await import("../sse-Cf0jUHsh.mjs").then((n) => n.r);
9
9
  await fastify.register(ssePlugin, {
10
10
  path: opts.sse?.path ?? "/events/stream",
11
11
  requireAuth: auth,
@@ -1,8 +1,8 @@
1
1
 
2
2
  import { c as WebSocketClient, l as WebSocketMessage, u as WebSocketPluginOptions } from "../websocket-BOXVggMf.mjs";
3
3
  import { EventGatewayOptions } from "./event-gateway.mjs";
4
- import { a as JobMeta, c as JobsPluginOptions, i as JobDispatcher, l as QueueStats, n as JobDefinition, r as JobDispatchOptions } from "../index-C-481Zf2.mjs";
5
- import { _ as ToolDefinition, c as McpAuthResult, d as McpResourceConfig, f as PromptDefinition, g as ToolContext, h as ToolAnnotations, n as CallToolResult, o as CrudOperation, r as CreateMcpServerConfig, t as BetterAuthHandler, u as McpPluginOptions } from "../types-CwcUQ610.mjs";
4
+ import { a as JobMeta, c as JobsPluginOptions, i as JobDispatcher, l as QueueStats, n as JobDefinition, r as JobDispatchOptions } from "../index-ugr1tQlW.mjs";
5
+ import { _ as ToolDefinition, c as McpAuthResult, d as McpResourceConfig, f as PromptDefinition, g as ToolContext, h as ToolAnnotations, n as CallToolResult, o as CrudOperation, r as CreateMcpServerConfig, t as BetterAuthHandler, u as McpPluginOptions } from "../types-BfC83KsP.mjs";
6
6
  import { StreamlinePluginOptions, WorkflowLike, WorkflowRunLike } from "./streamline.mjs";
7
7
  import { WebhookDeliveryRecord, WebhookManager, WebhookPluginOptions, WebhookStore, WebhookSubscription } from "./webhooks.mjs";
8
8
  export type { BetterAuthHandler, CallToolResult, CreateMcpServerConfig, CrudOperation, EventGatewayOptions, JobDefinition, JobDispatchOptions, JobDispatcher, JobMeta, JobsPluginOptions, McpAuthResult, McpPluginOptions, McpResourceConfig, PromptDefinition, QueueStats, StreamlinePluginOptions, ToolAnnotations, ToolContext, ToolDefinition, WebSocketClient, WebSocketMessage, WebSocketPluginOptions, WebhookDeliveryRecord, WebhookManager, WebhookPluginOptions, WebhookStore, WebhookSubscription, WorkflowLike, WorkflowRunLike };
@@ -1,2 +1,2 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
2
2
  export {};
@@ -1,3 +1,3 @@
1
1
 
2
- import { a as JobMeta, c as JobsPluginOptions, d as ExecuteTimedHandlerOptions, f as TimedHandlerLogger, i as JobDispatcher, l as QueueStats, n as JobDefinition, o as JobRepeatOptions, p as executeTimedHandler, r as JobDispatchOptions, s as JobStatus, t as jobsPlugin, u as defineJob } from "../../index-C-481Zf2.mjs";
2
+ import { a as JobMeta, c as JobsPluginOptions, d as ExecuteTimedHandlerOptions, f as TimedHandlerLogger, i as JobDispatcher, l as QueueStats, n as JobDefinition, o as JobRepeatOptions, p as executeTimedHandler, r as JobDispatchOptions, s as JobStatus, t as jobsPlugin, u as defineJob } from "../../index-ugr1tQlW.mjs";
3
3
  export { type ExecuteTimedHandlerOptions, type JobDefinition, type JobDispatchOptions, type JobDispatcher, type JobMeta, type JobRepeatOptions, type JobStatus, type JobsPluginOptions, type QueueStats, type TimedHandlerLogger, defineJob, executeTimedHandler, jobsPlugin };
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { n as evaluateAndApplyPermission } from "../../authorizationDecision-ChvUQGG1.mjs";
1
+ /*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
2
+ import { n as evaluateAndApplyPermission } from "../../authorizationDecision-B3mP_QTy.mjs";
3
3
  import fp from "fastify-plugin";
4
4
  //#region src/integrations/jobs/execution.ts
5
5
  async function executeTimedHandler(options) {
@@ -134,7 +134,7 @@ var Semaphore = class {
134
134
  }
135
135
  };
136
136
  const jobsPluginImpl = async (fastify, options) => {
137
- const { connection, jobs, prefix = "/jobs", bridgeEvents = true, defaults = {} } = options;
137
+ const { connection, jobs, prefix = "/jobs", bridgeEvents = true, defaults = {}, mode = "both" } = options;
138
138
  let Queue;
139
139
  let Worker;
140
140
  try {
@@ -205,7 +205,7 @@ const jobsPluginImpl = async (fastify, options) => {
205
205
  const queueName = job.name;
206
206
  const queue = new Queue(queueName, { connection });
207
207
  queues.set(queueName, queue);
208
- if (job.repeat) {
208
+ if (job.repeat && mode !== "producer") {
209
209
  const repeatOpts = {
210
210
  ...job.repeat.pattern ? {
211
211
  pattern: job.repeat.pattern,
@@ -227,105 +227,107 @@ const jobsPluginImpl = async (fastify, options) => {
227
227
  dlqQueue = new Queue(dlqName, { connection });
228
228
  dlqQueues.set(dlqName, dlqQueue);
229
229
  }
230
- const jobTimeout = job.timeout ?? defaults.timeout;
231
- const semaphore = job.maxConcurrent != null ? new Semaphore(job.maxConcurrent) : null;
232
- const throttledSet = /* @__PURE__ */ new Set();
233
- throttledJobs.set(queueName, throttledSet);
234
- const worker = new Worker(queueName, async (bullJob) => {
235
- if (semaphore) {
236
- if (semaphore.isFull) throttledSet.add(bullJob.id ?? "");
237
- try {
238
- await semaphore.acquire();
239
- } finally {
240
- throttledSet.delete(bullJob.id ?? "");
230
+ if (mode !== "producer") {
231
+ const jobTimeout = job.timeout ?? defaults.timeout;
232
+ const semaphore = job.maxConcurrent != null ? new Semaphore(job.maxConcurrent) : null;
233
+ const throttledSet = /* @__PURE__ */ new Set();
234
+ throttledJobs.set(queueName, throttledSet);
235
+ const worker = new Worker(queueName, async (bullJob) => {
236
+ if (semaphore) {
237
+ if (semaphore.isFull) throttledSet.add(bullJob.id ?? "");
238
+ try {
239
+ await semaphore.acquire();
240
+ } finally {
241
+ throttledSet.delete(bullJob.id ?? "");
242
+ }
241
243
  }
242
- }
243
- const result = await executeTimedHandler({
244
- label: queueName,
245
- ...bullJob.id !== void 0 ? { jobId: bullJob.id } : {},
246
- ...jobTimeout !== void 0 ? { timeoutMs: jobTimeout } : {},
247
- ...job.cancelGraceMs !== void 0 ? { cancelGraceMs: job.cancelGraceMs } : {},
248
- ...semaphore ? { releaseSlot: () => semaphore.release() } : {},
249
- logger: fastify.log,
250
- run: (signal) => {
251
- const meta = {
252
- jobId: bullJob.id ?? "",
253
- attemptsMade: bullJob.attemptsMade ?? 0,
254
- timestamp: Date.now(),
255
- signal
256
- };
257
- return job.handler(bullJob.data, meta);
244
+ const result = await executeTimedHandler({
245
+ label: queueName,
246
+ ...bullJob.id !== void 0 ? { jobId: bullJob.id } : {},
247
+ ...jobTimeout !== void 0 ? { timeoutMs: jobTimeout } : {},
248
+ ...job.cancelGraceMs !== void 0 ? { cancelGraceMs: job.cancelGraceMs } : {},
249
+ ...semaphore ? { releaseSlot: () => semaphore.release() } : {},
250
+ logger: fastify.log,
251
+ run: (signal) => {
252
+ const meta = {
253
+ jobId: bullJob.id ?? "",
254
+ attemptsMade: bullJob.attemptsMade ?? 0,
255
+ timestamp: Date.now(),
256
+ signal
257
+ };
258
+ return job.handler(bullJob.data, meta);
259
+ }
260
+ });
261
+ if (bridgeEvents && fastify.events?.publish) try {
262
+ await fastify.events.publish(`job.${queueName}.completed`, {
263
+ jobId: bullJob.id,
264
+ data: bullJob.data,
265
+ result
266
+ });
267
+ } catch (err) {
268
+ fastify.log.warn({
269
+ err,
270
+ jobId: bullJob.id
271
+ }, `Failed to publish job.${queueName}.completed event`);
258
272
  }
273
+ return result;
274
+ }, {
275
+ connection,
276
+ concurrency: job.concurrency ?? 1,
277
+ limiter: job.rateLimit ? {
278
+ max: job.rateLimit.max,
279
+ duration: job.rateLimit.duration
280
+ } : void 0
259
281
  });
260
- if (bridgeEvents && fastify.events?.publish) try {
261
- await fastify.events.publish(`job.${queueName}.completed`, {
262
- jobId: bullJob.id,
263
- data: bullJob.data,
264
- result
265
- });
266
- } catch (err) {
267
- fastify.log.warn({
268
- err,
269
- jobId: bullJob.id
270
- }, `Failed to publish job.${queueName}.completed event`);
271
- }
272
- return result;
273
- }, {
274
- connection,
275
- concurrency: job.concurrency ?? 1,
276
- limiter: job.rateLimit ? {
277
- max: job.rateLimit.max,
278
- duration: job.rateLimit.duration
279
- } : void 0
280
- });
281
- worker.on("failed", async (bullJob, error) => {
282
- const maxAttempts = job.retries ?? defaults.retries ?? 3;
283
- if (dlqQueue && bullJob && (bullJob.attemptsMade ?? 0) >= maxAttempts) try {
284
- await dlqQueue.add(`${queueName}:dead`, bullJob.data, {
285
- jobId: `${bullJob.id}:dlq`,
286
- removeOnComplete: false
287
- });
288
- fastify.log.warn({
289
- jobId: bullJob.id,
290
- dlq: job.deadLetterQueue ?? `${queueName}:dead`
291
- }, `Job moved to dead-letter queue`);
292
- } catch (dlqErr) {
293
- fastify.log.error({
294
- err: dlqErr,
295
- jobId: bullJob.id
296
- }, `Failed to move job to DLQ`);
297
- }
298
- if (bridgeEvents && fastify.events?.publish) try {
299
- await fastify.events.publish(`job.${queueName}.failed`, {
300
- jobId: bullJob?.id,
301
- data: bullJob?.data,
302
- error: error.message,
303
- attemptsMade: bullJob?.attemptsMade
304
- });
305
- } catch (err) {
306
- fastify.log.warn({
307
- err,
308
- jobId: bullJob?.id
309
- }, `Failed to publish job.${queueName}.failed event`);
310
- }
311
- });
312
- worker.on("stalled", async (jobId) => {
313
- fastify.log.warn({
314
- jobId,
315
- queue: queueName
316
- }, "Job stalled — worker may have crashed");
317
- if (bridgeEvents && fastify.events?.publish) try {
318
- await fastify.events.publish(`job.${queueName}.stalled`, { jobId });
319
- } catch (err) {
282
+ worker.on("failed", async (bullJob, error) => {
283
+ const maxAttempts = job.retries ?? defaults.retries ?? 3;
284
+ if (dlqQueue && bullJob && (bullJob.attemptsMade ?? 0) >= maxAttempts) try {
285
+ await dlqQueue.add(`${queueName}:dead`, bullJob.data, {
286
+ jobId: `${bullJob.id}:dlq`,
287
+ removeOnComplete: false
288
+ });
289
+ fastify.log.warn({
290
+ jobId: bullJob.id,
291
+ dlq: job.deadLetterQueue ?? `${queueName}:dead`
292
+ }, `Job moved to dead-letter queue`);
293
+ } catch (dlqErr) {
294
+ fastify.log.error({
295
+ err: dlqErr,
296
+ jobId: bullJob.id
297
+ }, `Failed to move job to DLQ`);
298
+ }
299
+ if (bridgeEvents && fastify.events?.publish) try {
300
+ await fastify.events.publish(`job.${queueName}.failed`, {
301
+ jobId: bullJob?.id,
302
+ data: bullJob?.data,
303
+ error: error.message,
304
+ attemptsMade: bullJob?.attemptsMade
305
+ });
306
+ } catch (err) {
307
+ fastify.log.warn({
308
+ err,
309
+ jobId: bullJob?.id
310
+ }, `Failed to publish job.${queueName}.failed event`);
311
+ }
312
+ });
313
+ worker.on("stalled", async (jobId) => {
320
314
  fastify.log.warn({
321
- err,
322
- jobId
323
- }, `Failed to publish job.${queueName}.stalled event`);
324
- }
325
- });
326
- workers.set(queueName, worker);
315
+ jobId,
316
+ queue: queueName
317
+ }, "Job stalled — worker may have crashed");
318
+ if (bridgeEvents && fastify.events?.publish) try {
319
+ await fastify.events.publish(`job.${queueName}.stalled`, { jobId });
320
+ } catch (err) {
321
+ fastify.log.warn({
322
+ err,
323
+ jobId
324
+ }, `Failed to publish job.${queueName}.stalled event`);
325
+ }
326
+ });
327
+ workers.set(queueName, worker);
328
+ }
327
329
  }
328
- const JOB_PAYLOAD_WARN_BYTES = 100 * 1024;
330
+ const JOB_PAYLOAD_WARN_BYTES = 102400;
329
331
  const jobDefsByName = /* @__PURE__ */ new Map();
330
332
  for (const job of jobs) if (!jobDefsByName.has(job.name)) jobDefsByName.set(job.name, job);
331
333
  const dispatcher = {