@classytic/arc 2.32.0 → 2.34.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 (193) hide show
  1. package/README.md +1 -1
  2. package/bin/arc.js +58 -17
  3. package/dist/{BaseController-Dk34dxhI.mjs → BaseController-CbkuhNI2.mjs} +329 -35
  4. package/dist/{EventTransport-2uVV34WU.d.mts → EventTransport-BEVP50ka.d.mts} +16 -0
  5. package/dist/{EventTransport-BV10D0oG.mjs → EventTransport-tq4CEB-q.mjs} +39 -2
  6. package/dist/{HookSystem-vimw5D7Z.mjs → HookSystem-DqXkMXkB.mjs} +2 -2
  7. package/dist/{ResourceRegistry-BVr7PgA0.mjs → ResourceRegistry-DoALUlOO.mjs} +3 -2
  8. package/dist/{actionPermissions-Dti7ebyv.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 +39 -7
  14. package/dist/auth/redis-session.mjs +1 -1
  15. package/dist/{authorizationDecision-__T3EJDA.mjs → authorizationDecision-CMMLWmuZ.mjs} +6 -2
  16. package/dist/{types-B7XeLEgK.d.mts → base-Csjc2oF-.d.mts} +74 -74
  17. package/dist/{buildHandler-Dn7rzUJo.mjs → buildHandler-BrdYrG_1.mjs} +4 -4
  18. package/dist/cache/index.mjs +4 -4
  19. package/dist/{caching-DFJqHyFs.mjs → caching-BcGmvnHh.mjs} +2 -2
  20. package/dist/cleanup/index.d.mts +17 -5
  21. package/dist/cleanup/index.mjs +240 -7
  22. package/dist/cli/commands/describe.d.mts +1 -1
  23. package/dist/cli/commands/describe.mjs +3 -3
  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-J99LGTJI.mjs → constants-BxCoxmiN.mjs} +1 -1
  31. package/dist/context/index.mjs +3 -3
  32. package/dist/core/index.d.mts +3 -3
  33. package/dist/core/index.mjs +9 -8
  34. package/dist/{core-BwwmNSp7.mjs → core-BYKa8wHu.mjs} +3 -3
  35. package/dist/{createActionRouter-DkJZWo0m.mjs → createActionRouter-D6T0jWhS.mjs} +8 -8
  36. package/dist/{createAggregationRouter-B1exOVD8.mjs → createAggregationRouter-QLV2PrWP.mjs} +7 -7
  37. package/dist/{createApp-Bv0m-Q6_.mjs → createApp-zR-DEesr.mjs} +128 -24
  38. package/dist/{defineAggregation-gX4No1gt.mjs → defineAggregation-Nv-DwfOf.mjs} +1 -1
  39. package/dist/{defineResource-XFPPUu2c.mjs → defineResource-ZhuLonLm.mjs} +297 -23
  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-DNXXxgjl.mjs → elevation-B0tlY8y1.mjs} +4 -4
  44. package/dist/encryption/index.mjs +3 -3
  45. package/dist/{errorHandler-B2AZUJUj.mjs → errorHandler-C7xBqHsI.mjs} +42 -5
  46. package/dist/{errorHandler-CpYUJmPA.d.mts → errorHandler-DI5AN2b5.d.mts} +14 -3
  47. package/dist/{errors-Bh1KK5ps.mjs → errors-Cd_yy7aW.mjs} +1 -1
  48. package/dist/{eventPlugin-GF5nnBIq.d.mts → eventPlugin-DSNEZWfV.d.mts} +29 -1
  49. package/dist/{eventPlugin-Dk_TyXeE.mjs → eventPlugin-Dar8qRaj.mjs} +65 -9
  50. package/dist/events/index.d.mts +5 -351
  51. package/dist/events/index.mjs +5 -780
  52. package/dist/events/transports/redis-stream-entry.d.mts +1 -1
  53. package/dist/events/transports/redis-stream-entry.mjs +1 -1
  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 +7 -7
  58. package/dist/{fastify-augmentation-BppG5bMT.d.mts → fastify-augmentation-DVsTAy6X.d.mts} +3 -3
  59. package/dist/{fields-DEi65pGj.mjs → fields-CojeUkS4.mjs} +1 -1
  60. package/dist/{generate-CRSG0jTv.mjs → generate-DiB0nHPR.mjs} +2 -2
  61. package/dist/{headers-BXjQYbeC.mjs → headers-CveNO9gR.mjs} +2 -2
  62. package/dist/{health-5XnTa2uo.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 +90 -9
  67. package/dist/idempotency/redis.mjs +1 -1
  68. package/dist/{index-zq6VrjaB.d.mts → index-B-DvUzsr.d.mts} +12 -2
  69. package/dist/{index-CpzxqePp.d.mts → index-BcR2bFZQ.d.mts} +707 -373
  70. package/dist/{index-ZWhLTp_s.d.mts → index-C5NnMEKF.d.mts} +1 -1
  71. package/dist/{index-DXlHwvuE.d.mts → index-CFAJEWCX.d.mts} +18 -5
  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 +13 -12
  75. package/dist/{init-BbfP8aky.mjs → init-mdJ-v4Xp.mjs} +18 -12
  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 +99 -97
  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 +1 -1
  92. package/dist/{interface-BP4IJCBO.mjs → interface-DznJrm9R.mjs} +1 -1
  93. package/dist/{jsonBody-DDSR2HFl.mjs → jsonBody-CfGH-GxO.mjs} +2 -2
  94. package/dist/{keys-B-HBTGXl.mjs → keys-WeKvY1dE.mjs} +1 -1
  95. package/dist/{loadResources-DisEAmkm.mjs → loadResources-Bj-aSsXi.mjs} +2 -2
  96. package/dist/{loadResourcesFromEntry-D1MJp13f.mjs → loadResourcesFromEntry-DwaxNcE2.mjs} +2 -2
  97. package/dist/logger/index.mjs +1 -1
  98. package/dist/{mcpPlugin-CpfVpKHE.mjs → mcpPlugin-DX3PHD7K.mjs} +60 -21
  99. package/dist/{memory-DsuWnj4T.mjs → memory-qYSB7rMQ.mjs} +2 -2
  100. package/dist/{metrics-DdQL8syd.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 +2 -2
  104. package/dist/{module-Br81am6m.mjs → module-CwKsgZXp.mjs} +1 -1
  105. package/dist/{multipartBody-BnkBLN7v.mjs → multipartBody-4w-S3-PU.mjs} +1 -1
  106. package/dist/{openapi-DIRzvxC0.mjs → openapi-CkV5mQ53.mjs} +6 -6
  107. package/dist/outbox-admin/index.d.mts +2 -2
  108. package/dist/outbox-admin/index.mjs +4 -4
  109. package/dist/outbox-module-C1Bs_FXF.d.mts +382 -0
  110. package/dist/outbox-module-D1QfHqO4.mjs +846 -0
  111. package/dist/permissions/index.d.mts +2 -2
  112. package/dist/permissions/index.mjs +5 -5
  113. package/dist/{permissions-Dl_m0NCe.mjs → permissions-CP47jdi7.mjs} +25 -6
  114. package/dist/{pipe-ELHCP3zj.mjs → pipe-BzzoEhHj.mjs} +2 -2
  115. package/dist/pipeline/index.d.mts +1 -1
  116. package/dist/pipeline/index.mjs +2 -2
  117. package/dist/{pipeline-CPA-jx0M.mjs → pipeline-q69DZzgG.mjs} +6 -6
  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-C2ZkKbsn.mjs → pluralize-B7xf8qZF.mjs} +1 -1
  123. package/dist/{preloadResources-CDs87fTw.mjs → preloadResources-BkyqeTDz.mjs} +1 -1
  124. package/dist/{preloadResources-T1hmlTEZ.d.mts → preloadResources-g07ldtzh.d.mts} +30 -7
  125. package/dist/presets/filesUpload.d.mts +2 -2
  126. package/dist/presets/filesUpload.mjs +5 -5
  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-Dntd_pUO.mjs → presets-BAPijK_A.mjs} +4 -4
  134. package/dist/projection-BKM0Ui-s.mjs +42 -0
  135. package/dist/{queryCachePlugin-Dhps-Ldt.mjs → queryCachePlugin-DhsZ0ZIc.mjs} +49 -7
  136. package/dist/{rateLimit-C7mmAGs3.mjs → rateLimit-D4-ASwsI.mjs} +2 -2
  137. package/dist/{rateLimitKey-CccEFBfk.mjs → rateLimitKey-XngqVNEV.mjs} +1 -1
  138. package/dist/{realtime-DVvVZZFz.mjs → realtime-G1TC6Yzc.mjs} +9 -9
  139. package/dist/{redis-stream-qN6A-RFv.d.mts → redis-stream-mwLWlfHG.d.mts} +1 -1
  140. package/dist/{registerRoute-B_QrjYZS.mjs → registerRoute-Ba8v0PCa.mjs} +4 -4
  141. package/dist/registry/index.d.mts +3 -3
  142. package/dist/registry/index.mjs +3 -3
  143. package/dist/{registry-DqUmzA9W.mjs → registry-CLxCR5LF.mjs} +2 -2
  144. package/dist/{renewingLease-BpP9wwj7.mjs → renewingLease-BnWtbA2U.mjs} +1 -1
  145. package/dist/{replyHelpers-DS-P0b32.mjs → replyHelpers-BSBVCwL3.mjs} +2 -2
  146. package/dist/repositoryFilter-BANpz6BX.mjs +78 -0
  147. package/dist/{requestContext-B6vQF-sy.mjs → requestContext-uYE35JxI.mjs} +1 -1
  148. package/dist/{rolldown-runtime-BhflRrBs.mjs → rolldown-runtime-DNg-KNCk.mjs} +1 -1
  149. package/dist/runtimeCapabilities-Dm88DaTW.mjs +49 -0
  150. package/dist/{schedules-C2Q3uv2d.mjs → schedules-CAcZgia0.mjs} +3 -3
  151. package/dist/{schemaConverter-Crjvczi_.mjs → schemaConverter-XH1RZRyu.mjs} +1 -1
  152. package/dist/{schemaIR-CnyKK_1j.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-afz_Ieek.mjs → scope-BaWcqBvr.mjs} +4 -4
  157. package/dist/{simpleEqualityMatcher-C4KiMWUa.mjs → simpleEqualityMatcher-Se8VrsaP.mjs} +1 -1
  158. package/dist/{sse-B9P4Y-UI.mjs → sse-Cf0jUHsh.mjs} +5 -5
  159. package/dist/{sseStream-B3zb_d1h.mjs → sseStream-Bvpi-UXQ.mjs} +2 -2
  160. package/dist/{store-helpers-DmEMHlPQ.mjs → store-helpers-B88p99Z2.mjs} +1 -1
  161. package/dist/{streaming-DPZdQmDz.mjs → streaming-DsT1B5zJ.mjs} +1 -1
  162. package/dist/{subscribe-helpers-sp5xTDVA.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 +3 -1
  166. package/dist/testing/index.d.mts +24 -12
  167. package/dist/testing/index.mjs +24 -12
  168. package/dist/testing/outboxStoreContract.mjs +1 -1
  169. package/dist/testing/storageContract.mjs +1 -1
  170. package/dist/{transactionContext-BvLKvOIL.mjs → transactionContext-BYtWnwAS.mjs} +1 -1
  171. package/dist/{typeGuards-B_5-hKjJ.mjs → typeGuards-jjKJDN13.mjs} +1 -1
  172. package/dist/types/index.d.mts +3 -3
  173. package/dist/types/index.mjs +1 -1
  174. package/dist/types/storage.mjs +1 -1
  175. package/dist/{types-CT5vu6M0.d.mts → types-BcTumAz_.d.mts} +41 -7
  176. package/dist/{types-CwcUQ610.d.mts → types-BfC83KsP.d.mts} +15 -1
  177. package/dist/{types-DXYX7dIR.mjs → types-CoqIRrkY.mjs} +4 -4
  178. package/dist/{types-C4QE8qnm.d.mts → types-DVLddu2q.d.mts} +144 -1
  179. package/dist/usage/index.d.mts +1 -1
  180. package/dist/usage/index.mjs +0 -0
  181. package/dist/{userHelpers-BNsOXzOd.mjs → userHelpers-CWF5pbZD.mjs} +1 -1
  182. package/dist/utils/index.d.mts +57 -5
  183. package/dist/utils/index.mjs +12 -11
  184. package/dist/{utils-BtOha_Sp.mjs → utils-h1V_sT-t.mjs} +38 -7
  185. package/dist/{validate-PMCPR9El.mjs → validate-CdQlz52F.mjs} +2 -2
  186. package/dist/{versioning-D_rhHfZm.d.mts → versioning-DEs-_hFi.d.mts} +1 -1
  187. package/dist/{versioning-CKv2jz_U.mjs → versioning-rZbyLVD-.mjs} +3 -3
  188. package/package.json +17 -16
  189. package/skills/arc/SKILL.md +96 -4
  190. package/skills/arc/references/api-reference.md +19 -0
  191. package/skills/arc/references/production.md +2 -2
  192. package/dist/projection-CjHhM5W1.mjs +0 -18
  193. package/dist/repositoryFilter-DotlxG3L.mjs +0 -45
@@ -1,5 +1,5 @@
1
1
 
2
- import { _ as HealthCheck, a as ModuleContribution, f as ScheduleDefinition, n as ArcModuleInput, r as ArcModuleRegistry, s as ModuleSetupContext, t as ArcModule } from "./types-CT5vu6M0.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
  /**
@@ -1,12 +1,13 @@
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-BppG5bMT.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 { Filter } from "@classytic/repo-core/filter";
7
+ import { AggDateBucket, AggMeasure, AggTopN } from "@classytic/repo-core/repository";
6
8
  import { FastifyReply, FastifyRequest, RouteHandlerMethod } from "fastify";
7
9
  import { z } from "zod";
8
10
  import { DataAdapter } from "@classytic/repo-core/adapter";
9
- import { AggDateBucket, AggMeasure, AggTopN } from "@classytic/repo-core/repository";
10
11
  import { LookupSpec } from "@classytic/repo-core/lookup";
11
12
  //#region src/constants.d.ts
12
13
  /**
@@ -426,6 +427,18 @@ declare function isFieldReadable(rule: ArcFieldRule | undefined): boolean;
426
427
  */
427
428
  declare function collectReadBlockedFields(schemaOptions: RouteSchemaOptions | undefined): Set<string> | null;
428
429
  //#endregion
430
+ //#region src/core/repositoryFilter.d.ts
431
+ declare const NATIVE_FILTER_DIALECT: unique symbol;
432
+ type NativePolicyFilter<Dialect extends string = string> = AnyRecord & {
433
+ readonly [NATIVE_FILTER_DIALECT]: Dialect;
434
+ };
435
+ /**
436
+ * Mark a server-owned policy as intentionally adapter-native. This is an
437
+ * explicit escape hatch for semantics absent from repo-core's universal IR
438
+ * (for example MongoDB `$elemMatch`). Never apply it to client input.
439
+ */
440
+ declare function nativePolicyFilter<const Dialect extends string>(dialect: Dialect, record: AnyRecord): NativePolicyFilter<Dialect>;
441
+ //#endregion
429
442
  //#region src/core/validateResourceConfig.d.ts
430
443
  interface ConfigError {
431
444
  field: string;
@@ -458,4 +471,4 @@ declare function formatValidationErrors(resourceName: string, result: Validation
458
471
  */
459
472
  declare function assertValidConfig(config: ResourceConfig, options?: ValidateOptions): void;
460
473
  //#endregion
461
- export { DEFAULT_ID_FIELD as A, MAX_FILTER_DEPTH as B, DefineActionConfig as C, defineAggregation as D, createPermissionMiddleware as E, DEFAULT_UPDATE_METHOD as F, RESERVED_QUERY_PARAMS as G, MAX_SEARCH_LENGTH as H, HOOK_OPERATIONS as I, SYSTEM_FIELDS as K, HOOK_PHASES as L, DEFAULT_MAX_LIMIT as M, DEFAULT_SORT as N, CRUD_OPERATIONS as O, DEFAULT_TENANT_FIELD as P, HookOperation as R, mergeResourceConfig as S, createCrudRouter as T, MUTATION_OPERATIONS as U, MAX_REGEX_LENGTH as V, MutationOperation as W, getEntityQuery as _, formatValidationErrors as a, ResourceSeams as b, isFieldReadable as c, createRequestContext as d, getControllerContext as f, getEntityIdField as g, getEntityId as h, assertValidConfig as i, DEFAULT_LIMIT as j, CrudOperation as k, createCrudHandlers as l, sendControllerResponse as m, ValidateOptions as n, validateResourceConfig as o, getControllerScope as p, ValidationResult as r, collectReadBlockedFields as s, ConfigError as t, createFastifyHandler as u, defineResourceVariants as v, defineAction as w, SeamedResourceConfig as x, AdapterLike as y, HookPhase as z };
474
+ export { CRUD_OPERATIONS as A, HookOperation as B, SeamedResourceConfig as C, createCrudRouter as D, defineAction as E, DEFAULT_SORT as F, MUTATION_OPERATIONS as G, MAX_FILTER_DEPTH as H, DEFAULT_TENANT_FIELD as I, SYSTEM_FIELDS as J, MutationOperation as K, DEFAULT_UPDATE_METHOD as L, DEFAULT_ID_FIELD as M, DEFAULT_LIMIT as N, createPermissionMiddleware as O, DEFAULT_MAX_LIMIT as P, HOOK_OPERATIONS as R, ResourceSeams as S, DefineActionConfig as T, MAX_REGEX_LENGTH as U, HookPhase as V, MAX_SEARCH_LENGTH as W, getEntityId as _, formatValidationErrors as a, defineResourceVariants as b, nativePolicyFilter as c, createCrudHandlers as d, createFastifyHandler as f, sendControllerResponse as g, getControllerScope as h, assertValidConfig as i, CrudOperation as j, defineAggregation as k, collectReadBlockedFields as l, getControllerContext as m, ValidateOptions as n, validateResourceConfig as o, createRequestContext as p, RESERVED_QUERY_PARAMS as q, ValidationResult as r, NativePolicyFilter as s, ConfigError as t, isFieldReadable as u, getEntityIdField as v, mergeResourceConfig as w, AdapterLike as x, getEntityQuery as y, HOOK_PHASES as z };
@@ -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-BppG5bMT.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-DXlHwvuE.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-zq6VrjaB.mjs";
5
+ import "./fastify-augmentation-DVsTAy6X.mjs";
6
+ import { A as CRUD_OPERATIONS, B as HookOperation, C as SeamedResourceConfig, E as defineAction, F as DEFAULT_SORT, G as MUTATION_OPERATIONS, H as MAX_FILTER_DEPTH, I as DEFAULT_TENANT_FIELD, J as SYSTEM_FIELDS, K as MutationOperation, L as DEFAULT_UPDATE_METHOD, M as DEFAULT_ID_FIELD, N as DEFAULT_LIMIT, P as DEFAULT_MAX_LIMIT, R as HOOK_OPERATIONS, S as ResourceSeams, U as MAX_REGEX_LENGTH, V as HookPhase, W as MAX_SEARCH_LENGTH, b as defineResourceVariants, c as nativePolicyFilter, h as getControllerScope, j as CrudOperation, k as defineAggregation, q as RESERVED_QUERY_PARAMS, s as NativePolicyFilter, w as mergeResourceConfig, x as AdapterLike, z as HOOK_PHASES } from "./index-CFAJEWCX.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, type NativePolicyFilter, 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, nativePolicyFilter, 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,15 @@
1
- /*! @classytic/arc v2.32.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-J99LGTJI.mjs";
3
- import { d as createDomainError, i as NotFoundError, l as UnauthorizedError, r as ForbiddenError, t as ArcError, u as ValidationError } from "./errors-Bh1KK5ps.mjs";
4
- import { a as BulkMixin, i as SlugMixin, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, t as BaseController } from "./BaseController-Dk34dxhI.mjs";
5
- import { n as applyFieldWritePermissions, r as fields, t as applyFieldReadPermissions } from "./fields-DEi65pGj.mjs";
6
- import { a as ResourceDefinition, t as defineResource } from "./defineResource-XFPPUu2c.mjs";
7
- import { c as getControllerScope } from "./pipeline-CPA-jx0M.mjs";
8
- import { t as defineAggregation } from "./defineAggregation-gX4No1gt.mjs";
9
- import { a as mergeResourceConfig, i as defineResourceVariants, o as defineAction } from "./core-BwwmNSp7.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-Dl_m0NCe.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 { t as nativePolicyFilter } from "./repositoryFilter-BANpz6BX.mjs";
5
+ import { a as BulkMixin, i as SlugMixin, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, t as BaseController } from "./BaseController-CbkuhNI2.mjs";
6
+ import { n as applyFieldWritePermissions, r as fields, t as applyFieldReadPermissions } from "./fields-CojeUkS4.mjs";
7
+ import { a as ResourceDefinition, t as defineResource } from "./defineResource-ZhuLonLm.mjs";
8
+ import { c as getControllerScope } from "./pipeline-q69DZzgG.mjs";
9
+ import { t as defineAggregation } from "./defineAggregation-Nv-DwfOf.mjs";
10
+ import { a as mergeResourceConfig, i as defineResourceVariants, o as defineAction } from "./core-BYKa8wHu.mjs";
11
+ 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-CP47jdi7.mjs";
11
12
  //#region src/index.ts
12
- const version = "2.32.0";
13
+ const version = "2.34.0";
13
14
  //#endregion
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 };
15
+ 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, nativePolicyFilter, 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.32.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",
@@ -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({
@@ -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.32.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-B9P4Y-UI.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.32.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.32.0 | MIT | https://classytic.com */
2
- import { n as evaluateAndApplyPermission } from "../../authorizationDecision-__T3EJDA.mjs";
1
+ /*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
2
+ import { n as evaluateAndApplyPermission } from "../../authorizationDecision-CMMLWmuZ.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,103 +227,105 @@ 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
330
  const JOB_PAYLOAD_WARN_BYTES = 102400;
329
331
  const jobDefsByName = /* @__PURE__ */ new Map();
@@ -1,9 +1,9 @@
1
1
 
2
- import { Ht as ServerAccessor, Rt as IControllerResponse, V as ResourceDefinition, zt as IRequestContext } from "../../index-CpzxqePp.mjs";
3
2
  import { i as RequestScope } from "../../types-ChuShpCP.mjs";
4
- import { r as PermissionCheck } from "../../types-B7XeLEgK.mjs";
3
+ import { l as PermissionCheck } from "../../base-Csjc2oF-.mjs";
4
+ import { Fn as IControllerResponse, In as IRequestContext, V as ResourceDefinition, zn as ServerAccessor } from "../../index-BcR2bFZQ.mjs";
5
5
  import { n as FieldPermissionMap } from "../../fields-I_EeRWND.mjs";
6
- import { _ as ToolDefinition, a as CrudDescriptionOverride, c as McpAuthResult, d as McpResourceConfig, f as PromptDefinition, g as ToolContext, h as ToolAnnotations, i as CrudDescriptionMeta, l as McpExecutionWiring, m as SessionEntry, n as CallToolResult, o as CrudOperation, p as PromptResult, r as CreateMcpServerConfig, s as McpAuthResolver, t as BetterAuthHandler, u as McpPluginOptions } from "../../types-CwcUQ610.mjs";
6
+ import { _ as ToolDefinition, a as CrudDescriptionOverride, c as McpAuthResult, d as McpResourceConfig, f as PromptDefinition, g as ToolContext, h as ToolAnnotations, i as CrudDescriptionMeta, l as McpExecutionWiring, m as SessionEntry, n as CallToolResult, o as CrudOperation, p as PromptResult, r as CreateMcpServerConfig, s as McpAuthResolver, t as BetterAuthHandler, u as McpPluginOptions } from "../../types-BfC83KsP.mjs";
7
7
  import { ErrorContract } from "@classytic/repo-core/errors";
8
8
  import { FastifyPluginAsync } from "fastify";
9
9
  import { z } from "zod";
@@ -222,6 +222,15 @@ interface FieldRulesToZodOptions {
222
222
  filterableFields?: readonly string[];
223
223
  /** Allowed filter operators — generates `field[op]` entries in list mode (e.g., price[gt], price[lte]) */
224
224
  allowedOperators?: readonly string[];
225
+ /**
226
+ * The resource's page-size cap, for the `limit` field's `max` AND its description.
227
+ *
228
+ * Defaults to 100 only when the resource states nothing. Hardcoding 100 here made
229
+ * MCP a FOURTH independent cap: a resource configured for 1000 exposed a tool that
230
+ * rejected `limit: 500` outright and told the agent "max 100" — so the model was
231
+ * misinformed about the ceiling, not merely limited by it.
232
+ */
233
+ maxLimit?: number;
225
234
  }
226
235
  /** Single field rule entry from Arc's schemaOptions.fieldRules */
227
236
  interface FieldRuleEntry {
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
- import { a as defaultCrudDescription, c as mcpHandlerAdapter, d as toCallToolResult, f as toCallToolSuccess, h as resolveToolCollisions, i as fieldRulesToZod, l as permissionDeniedResult, m as createMcpServer, n as mcpPlugin, o as resolveCrudDescription, p as buildRequestContext, r as resourceToTools, s as invokeController, t as filterResourcesForMcp, u as toCallToolError } from "../../mcpPlugin-CpfVpKHE.mjs";
1
+ /*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
2
+ import { a as defaultCrudDescription, c as mcpHandlerAdapter, d as toCallToolResult, f as toCallToolSuccess, h as resolveToolCollisions, i as fieldRulesToZod, l as permissionDeniedResult, m as createMcpServer, n as mcpPlugin, o as resolveCrudDescription, p as buildRequestContext, r as resourceToTools, s as invokeController, t as filterResourcesForMcp, u as toCallToolError } from "../../mcpPlugin-DX3PHD7K.mjs";
3
3
  //#region src/integrations/mcp/defineTool.ts
4
4
  /**
5
5
  * Define a type-safe MCP tool.
@@ -1,5 +1,5 @@
1
1
 
2
- import { c as McpAuthResult, u as McpPluginOptions } from "../../types-CwcUQ610.mjs";
2
+ import { c as McpAuthResult, u as McpPluginOptions } from "../../types-BfC83KsP.mjs";
3
3
  //#region src/integrations/mcp/testing.d.ts
4
4
  interface TestMcpClientOptions {
5
5
  /** MCP plugin options (resources, overrides, etc.) — same as mcpPlugin config */
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
- import { m as createMcpServer, r as resourceToTools, t as filterResourcesForMcp } from "../../mcpPlugin-CpfVpKHE.mjs";
1
+ /*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
2
+ import { m as createMcpServer, r as resourceToTools, t as filterResourcesForMcp } from "../../mcpPlugin-DX3PHD7K.mjs";
3
3
  //#region src/integrations/mcp/testing.ts
4
4
  /**
5
5
  * @classytic/arc/mcp/testing — MCP Test Utilities
@@ -1,6 +1,6 @@
1
- /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
- import { f as createError, i as NotFoundError, r as ForbiddenError } from "../errors-Bh1KK5ps.mjs";
3
- import { a as promoteStreamTokenToHeader, n as forwardedStreamHeaders } from "../streaming-DPZdQmDz.mjs";
1
+ /*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
2
+ import { f as createError, i as NotFoundError, r as ForbiddenError } from "../errors-Cd_yy7aW.mjs";
3
+ import { a as promoteStreamTokenToHeader, n as forwardedStreamHeaders } from "../streaming-DsT1B5zJ.mjs";
4
4
  import fp from "fastify-plugin";
5
5
  //#region src/integrations/streamline.ts
6
6
  /**