@classytic/arc 2.34.0 → 2.35.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 (182) hide show
  1. package/dist/{BaseController-CbkuhNI2.mjs → BaseController-C-pofd0v.mjs} +95 -14
  2. package/dist/{EventTransport-tq4CEB-q.mjs → EventTransport-BrPeGUil.mjs} +1 -1
  3. package/dist/{HookSystem-DqXkMXkB.mjs → HookSystem-LlPm3Anm.mjs} +6 -4
  4. package/dist/{ResourceRegistry-DoALUlOO.mjs → ResourceRegistry-yuD1Ra53.mjs} +2 -2
  5. package/dist/{pipeline-q69DZzgG.mjs → actionPermissions-LFuOra7W.mjs} +30 -7
  6. package/dist/audit/index.d.mts +2 -2
  7. package/dist/audit/index.mjs +2 -2
  8. package/dist/auth/audit.mjs +1 -1
  9. package/dist/auth/index.d.mts +2 -2
  10. package/dist/auth/index.mjs +6 -6
  11. package/dist/auth/redis-session.mjs +1 -1
  12. package/dist/{authorizationDecision-CMMLWmuZ.mjs → authorizationDecision-DYXBBgtg.mjs} +2 -2
  13. package/dist/{base-Csjc2oF-.d.mts → base-GZU3LlzP.d.mts} +1 -1
  14. package/dist/{buildHandler-BrdYrG_1.mjs → buildHandler-Do9aMIvL.mjs} +4 -4
  15. package/dist/cache/index.mjs +4 -4
  16. package/dist/{caching-BcGmvnHh.mjs → caching-cN5X9VEL.mjs} +2 -2
  17. package/dist/cleanup/index.d.mts +2 -2
  18. package/dist/cleanup/index.mjs +4 -4
  19. package/dist/cli/commands/describe.d.mts +1 -1
  20. package/dist/cli/commands/describe.mjs +3 -3
  21. package/dist/cli/commands/docs.mjs +3 -3
  22. package/dist/cli/commands/doctor.mjs +1 -1
  23. package/dist/cli/commands/generate.mjs +2 -2
  24. package/dist/cli/commands/init.mjs +2 -2
  25. package/dist/cli/commands/introspect.mjs +2 -2
  26. package/dist/cli/index.mjs +3 -3
  27. package/dist/{constants-BxCoxmiN.mjs → constants-BhzLXCfN.mjs} +1 -1
  28. package/dist/context/index.d.mts +16 -1
  29. package/dist/context/index.mjs +64 -4
  30. package/dist/core/index.d.mts +2 -2
  31. package/dist/core/index.mjs +7 -8
  32. package/dist/{core-BYKa8wHu.mjs → core-DdEvmmkY.mjs} +3 -3
  33. package/dist/{createActionRouter-D6T0jWhS.mjs → createActionRouter-EYWgd0ly.mjs} +27 -64
  34. package/dist/{createAggregationRouter-QLV2PrWP.mjs → createAggregationRouter-ByOK9Iev.mjs} +7 -7
  35. package/dist/defineAggregation-DoIijIFq.mjs +25 -0
  36. package/dist/{defineResource-ZhuLonLm.mjs → defineResource-BOrGeocE.mjs} +62 -66
  37. package/dist/discovery/index.mjs +1 -1
  38. package/dist/docs/index.d.mts +1 -1
  39. package/dist/docs/index.mjs +3 -3
  40. package/dist/{elevation-B0tlY8y1.mjs → elevation-tGIAldco.mjs} +4 -4
  41. package/dist/encryption/index.mjs +3 -3
  42. package/dist/{errorHandler-C7xBqHsI.mjs → errorHandler-BbQ1nQdk.mjs} +3 -3
  43. package/dist/{errors-Cd_yy7aW.mjs → errors-CLid6atr.mjs} +1 -1
  44. package/dist/{eventPlugin-DSNEZWfV.d.mts → eventPlugin-B47sfCJ8.d.mts} +1 -1
  45. package/dist/{eventPlugin-Dar8qRaj.mjs → eventPlugin-ClPn5kjn.mjs} +5 -5
  46. package/dist/events/index.d.mts +2 -2
  47. package/dist/events/index.mjs +5 -5
  48. package/dist/events/transports/redis-stream-entry.mjs +1 -1
  49. package/dist/events/transports/redis.mjs +1 -1
  50. package/dist/factory/index.d.mts +5 -5
  51. package/dist/factory/index.mjs +5 -6
  52. package/dist/{fastify-augmentation-DVsTAy6X.d.mts → fastify-augmentation-CMMTL3cj.d.mts} +3 -3
  53. package/dist/{fields-CojeUkS4.mjs → fields-UtpiJO5R.mjs} +1 -1
  54. package/dist/{generate-DiB0nHPR.mjs → generate-BoAVy3_b.mjs} +2 -2
  55. package/dist/{headers-CveNO9gR.mjs → headers-DODWf7aC.mjs} +2 -2
  56. package/dist/{health-CasG2A28.mjs → health-_Zs3R_Sb.mjs} +1 -1
  57. package/dist/hooks/index.d.mts +1 -1
  58. package/dist/hooks/index.mjs +2 -2
  59. package/dist/idempotency/index.mjs +22 -56
  60. package/dist/idempotency/redis.mjs +1 -1
  61. package/dist/{index-C5NnMEKF.d.mts → index-C50BUxKs.d.mts} +1 -1
  62. package/dist/{index-BcR2bFZQ.d.mts → index-C5K78SXo.d.mts} +33 -105
  63. package/dist/{index-ugr1tQlW.d.mts → index-CJCcbADG.d.mts} +1 -1
  64. package/dist/{index-B-DvUzsr.d.mts → index-K7auNNW0.d.mts} +2 -2
  65. package/dist/{index-CFAJEWCX.d.mts → index-h-mTgMqy.d.mts} +7 -30
  66. package/dist/index.d.mts +5 -5
  67. package/dist/index.mjs +11 -12
  68. package/dist/{init-mdJ-v4Xp.mjs → init-Ce4R0ZGK.mjs} +1 -1
  69. package/dist/integrations/event-gateway.mjs +2 -2
  70. package/dist/integrations/index.d.mts +2 -2
  71. package/dist/integrations/index.mjs +1 -1
  72. package/dist/integrations/jobs/index.d.mts +1 -1
  73. package/dist/integrations/jobs/index.mjs +2 -2
  74. package/dist/integrations/mcp/index.d.mts +4 -4
  75. package/dist/integrations/mcp/index.mjs +2 -2
  76. package/dist/integrations/mcp/testing.d.mts +1 -1
  77. package/dist/integrations/mcp/testing.mjs +3 -3
  78. package/dist/integrations/streamline.mjs +3 -3
  79. package/dist/integrations/webhooks.d.mts +1 -1
  80. package/dist/integrations/webhooks.mjs +11 -24
  81. package/dist/integrations/websocket-pushref-redis.mjs +1 -1
  82. package/dist/integrations/websocket-redis.mjs +1 -1
  83. package/dist/integrations/websocket.mjs +1 -1
  84. package/dist/{interface-DznJrm9R.mjs → interface-my7sxjw5.mjs} +1 -1
  85. package/dist/{jsonBody-CfGH-GxO.mjs → jsonBody-CVKA7C5m.mjs} +2 -2
  86. package/dist/{keys-WeKvY1dE.mjs → keys-GlU7XpmG.mjs} +1 -1
  87. package/dist/{loadResources-Bj-aSsXi.mjs → loadResources-DdQb0qgV.mjs} +2 -2
  88. package/dist/{loadResourcesFromEntry-DwaxNcE2.mjs → loadResourcesFromEntry-s6aGs6-0.mjs} +2 -2
  89. package/dist/logger/index.d.mts +23 -4
  90. package/dist/logger/index.mjs +50 -7
  91. package/dist/{mcpPlugin-DX3PHD7K.mjs → mcpPlugin-DkzZ7Nfx.mjs} +15 -16
  92. package/dist/{memory-qYSB7rMQ.mjs → memory-BwedEXau.mjs} +2 -2
  93. package/dist/{metrics-D7uchLjN.mjs → metrics-5LNPvL3P.mjs} +2 -2
  94. package/dist/middleware/index.d.mts +1 -1
  95. package/dist/middleware/index.mjs +3 -3
  96. package/dist/migrations/index.mjs +7 -4
  97. package/dist/{module-CwKsgZXp.mjs → module-Bh5OC7ww.mjs} +1 -1
  98. package/dist/{multipartBody-4w-S3-PU.mjs → multipartBody-DjilSDAT.mjs} +1 -1
  99. package/dist/{openapi-CkV5mQ53.mjs → openapi-ItLH12_L.mjs} +6 -6
  100. package/dist/outbox-admin/index.d.mts +2 -2
  101. package/dist/outbox-admin/index.mjs +4 -4
  102. package/dist/{outbox-module-D1QfHqO4.mjs → outbox-module-SGIZz6oS.mjs} +6 -4
  103. package/dist/{outbox-module-C1Bs_FXF.d.mts → outbox-module-b1TyDGGi.d.mts} +24 -1
  104. package/dist/permissions/index.d.mts +2 -2
  105. package/dist/permissions/index.mjs +5 -5
  106. package/dist/{permissions-CP47jdi7.mjs → permissions-CpSBlFXZ.mjs} +6 -6
  107. package/dist/{pipe-BzzoEhHj.mjs → pipe-DNOuCfAs.mjs} +2 -2
  108. package/dist/pipeline/index.d.mts +1 -1
  109. package/dist/pipeline/index.mjs +2 -2
  110. package/dist/plugins/index.d.mts +92 -7
  111. package/dist/plugins/index.mjs +168 -17
  112. package/dist/plugins/response-cache.mjs +2 -2
  113. package/dist/plugins/tracing-entry.mjs +2 -2
  114. package/dist/{pluralize-B7xf8qZF.mjs → pluralize-DGAQQKL8.mjs} +1 -1
  115. package/dist/{preloadResources-g07ldtzh.d.mts → preloadResources--ZtY9pe9.d.mts} +54 -270
  116. package/dist/{createApp-zR-DEesr.mjs → preloadResources-DYMzmUk1.mjs} +112 -31
  117. package/dist/presets/filesUpload.d.mts +3 -3
  118. package/dist/presets/filesUpload.mjs +5 -5
  119. package/dist/presets/index.d.mts +2 -2
  120. package/dist/presets/index.mjs +2 -2
  121. package/dist/presets/multiTenant.d.mts +1 -1
  122. package/dist/presets/multiTenant.mjs +3 -3
  123. package/dist/presets/search.d.mts +9 -47
  124. package/dist/presets/search.mjs +2 -2
  125. package/dist/{presets-BAPijK_A.mjs → presets-Bi0Z6Iq8.mjs} +4 -4
  126. package/dist/{projection-BKM0Ui-s.mjs → projection-aevMua7Q.mjs} +2 -2
  127. package/dist/{queryCachePlugin-DhsZ0ZIc.mjs → queryCachePlugin-BI7Z88Cx.mjs} +5 -5
  128. package/dist/{rateLimitKey-XngqVNEV.mjs → rateLimitKey-pyevMUVf.mjs} +1 -1
  129. package/dist/{realtime-G1TC6Yzc.mjs → realtime-Cfl2bVjj.mjs} +9 -9
  130. package/dist/{rateLimit-D4-ASwsI.mjs → registerRoute-u1opU66a.mjs} +114 -3
  131. package/dist/registry/index.d.mts +2 -2
  132. package/dist/registry/index.mjs +3 -3
  133. package/dist/{registry-CLxCR5LF.mjs → registry-B4sf9Rfm.mjs} +15 -56
  134. package/dist/{renewingLease-BnWtbA2U.mjs → renewingLease-5ESPMxp0.mjs} +14 -2
  135. package/dist/{replyHelpers-BSBVCwL3.mjs → replyHelpers-2jfmMnnV.mjs} +2 -2
  136. package/dist/{requestContext-uYE35JxI.mjs → requestContext-DzOUGNdY.mjs} +1 -1
  137. package/dist/{rolldown-runtime-DNg-KNCk.mjs → rolldown-runtime-CEvvVXTC.mjs} +1 -1
  138. package/dist/{runtimeCapabilities-Dm88DaTW.mjs → runtimeCapabilities-BagWc3TI.mjs} +1 -1
  139. package/dist/{schedules-CAcZgia0.mjs → schedules-BLpZLWGF.mjs} +6 -4
  140. package/dist/{schemaConverter-XH1RZRyu.mjs → schemaConverter-D2_bHGil.mjs} +19 -32
  141. package/dist/{schemaIR-CDvclAew.mjs → schemaIR-s3-ouZmP.mjs} +2 -2
  142. package/dist/schemas/index.mjs +1 -1
  143. package/dist/scim/index.mjs +2 -2
  144. package/dist/scope/index.d.mts +1 -1
  145. package/dist/scope/index.mjs +5 -5
  146. package/dist/{scope-BaWcqBvr.mjs → scope-DgepeCv6.mjs} +4 -4
  147. package/dist/simpleEqualityMatcher-BO-sFTQf.mjs +43 -0
  148. package/dist/{sse-Cf0jUHsh.mjs → sse-DUIP1XH6.mjs} +5 -5
  149. package/dist/{sseStream-Bvpi-UXQ.mjs → sseStream-ByFGyIVr.mjs} +2 -2
  150. package/dist/{store-helpers-B88p99Z2.mjs → store-helpers-kIJCY0wI.mjs} +1 -1
  151. package/dist/{streaming-DsT1B5zJ.mjs → streaming-DOpZVht6.mjs} +1 -1
  152. package/dist/{subscribe-helpers-CLIOHsOK.mjs → subscribe-helpers-Dh2BnzJf.mjs} +12 -46
  153. package/dist/sync/changelog.mjs +1 -1
  154. package/dist/testing/cleanupStoreContract.mjs +1 -1
  155. package/dist/testing/index.d.mts +6 -6
  156. package/dist/testing/index.mjs +10 -11
  157. package/dist/testing/outboxStoreContract.mjs +1 -1
  158. package/dist/testing/storageContract.mjs +1 -1
  159. package/dist/{transactionContext-BYtWnwAS.mjs → transactionContext-BTZzEcRo.mjs} +1 -1
  160. package/dist/{typeGuards-jjKJDN13.mjs → typeGuards-B-_jqaMi.mjs} +1 -1
  161. package/dist/types/index.d.mts +3 -3
  162. package/dist/types/index.mjs +1 -1
  163. package/dist/types/storage.mjs +1 -1
  164. package/dist/{types-BcTumAz_.d.mts → types-DDD5RKTu.d.mts} +30 -87
  165. package/dist/{types-BfC83KsP.d.mts → types-DSvHH0uR.d.mts} +1 -1
  166. package/dist/{types-ChuShpCP.d.mts → types-Ddl9OjmE.d.mts} +18 -121
  167. package/dist/{types-CoqIRrkY.mjs → types-GY4kATJb.mjs} +10 -53
  168. package/dist/usage/index.d.mts +2 -2
  169. package/dist/usage/index.mjs +0 -0
  170. package/dist/{userHelpers-CWF5pbZD.mjs → userHelpers-AKcB4V03.mjs} +1 -1
  171. package/dist/utils/index.d.mts +16 -42
  172. package/dist/utils/index.mjs +11 -11
  173. package/dist/{utils-h1V_sT-t.mjs → utils-CBK9HQOI.mjs} +3 -3
  174. package/dist/{validate-CdQlz52F.mjs → validate-dosAIvQU.mjs} +2 -2
  175. package/dist/{versioning-rZbyLVD-.mjs → versioning-BbTs4pwM.mjs} +3 -3
  176. package/package.json +8 -8
  177. package/dist/actionPermissions-CUeCmpUd.mjs +0 -25
  178. package/dist/defineAggregation-Nv-DwfOf.mjs +0 -48
  179. package/dist/preloadResources-BkyqeTDz.mjs +0 -46
  180. package/dist/registerRoute-Ba8v0PCa.mjs +0 -113
  181. package/dist/repositoryFilter-BANpz6BX.mjs +0 -78
  182. package/dist/simpleEqualityMatcher-Se8VrsaP.mjs +0 -69
@@ -1,2 +1,2 @@
1
- /*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
2
2
  export {};
@@ -446,52 +446,23 @@ interface ArcModule<TExports = unknown> {
446
446
  */
447
447
  readonly dependsOn?: readonly string[];
448
448
  /**
449
- * Infra SETUP function — the module-level analog of the app's `plugins()`
450
- * slot. Runs in the plugins phase: AFTER the app's own `plugins()` (so
451
- * module infra can build on app foundations like a DB connection) and in
452
- * `dependsOn` order, but BEFORE any module `bootstrap` — so engines
453
- * initialised in `bootstrap` can rely on what's registered here.
454
- *
455
- * ## ⚠ This is NOT itself a Fastify plugin
456
- *
457
- * Despite the name, arc CALLS this function directly — it is never handed
458
- * to `fastify.register()`. Two consequences, both of which bite module
459
- * authors coming from ordinary Fastify plugins:
460
- *
461
- * - **You must register plugins yourself.** `await fastify.register(x)`,
462
- * not `return x`. A returned function is read as a DISPOSER (below),
463
- * so returning a plugin silently registers nothing and then invokes
464
- * your plugin as a teardown callback. Arc detects the `fastify-plugin`
465
- * case and throws; the bare-function case warns.
466
- * - **There is no encapsulation and no prefix here.** Decorators and
467
- * hooks you add land on the instance arc passes you — the same
468
- * instance every other module sees. Fastify's encapsulation applies
469
- * only inside a `register()` call you make yourself. See
470
- * https://fastify.dev/docs/latest/Reference/Plugins/
449
+ * Infra SETUP — the module analog of the app's `plugins()`. Runs after the
450
+ * app's own `plugins()`, in `dependsOn` order, before any module `bootstrap`.
471
451
  *
472
- * ```ts
473
- * plugins: async (fastify) => {
474
- * await fastify.register(somePlugin, { prefix: '/x' }); // ✅ register
475
- * fastify.decorate('thing', thing); // ✅ root-visible
476
- * // return somePlugin // ❌ never registered
477
- * },
478
- * ```
452
+ * ⚠ NOT a Fastify plugin: arc CALLS it, never `register()`s it. So you
453
+ * register your own (`await fastify.register(x)`, not `return x` — a
454
+ * returned function is read as a DISPOSER), and there is no encapsulation
455
+ * or prefix: decorators land on the shared instance. Returning an `fp()`
456
+ * plugin throws; a bare multi-arg function warns.
479
457
  *
480
- * The name is kept for the 2.x line; v3 renames the slot to `setup` and
481
- * REMOVES `plugins` outright — v3 ships no compatibility aliases (v3.md).
482
- *
483
- * Separating this from `bootstrap` keeps lifecycle intent explicit for
484
- * published ecosystem packages: `plugins` = "register infra"; `bootstrap` =
485
- * "initialise engines (and return the public export)". Registering a plugin
486
- * inside `bootstrap` still works — this slot just makes the two distinct.
487
- *
488
- * Receives `{ defer }` to register teardown for anything it acquires, and
489
- * may RETURN a single disposer as shorthand for the one-resource case:
458
+ * Receives `{ defer }` for teardown, or return one disposer as shorthand.
459
+ * v3 renames this slot to `setup` with no alias (v3.md).
490
460
  *
491
461
  * ```ts
492
462
  * plugins: async (fastify) => {
463
+ * await fastify.register(somePlugin, { prefix: '/x' });
493
464
  * const conn = await connect();
494
- * return () => conn.close(); // equivalent to defer(...)
465
+ * return () => conn.close();
495
466
  * },
496
467
  * ```
497
468
  */
@@ -550,53 +521,25 @@ interface ArcModule<TExports = unknown> {
550
521
  */
551
522
  bootstrap?: (fastify: FastifyInstance, context: ModuleSetupContext) => TExports | Promise<TExports>;
552
523
  /**
553
- * App-level resource NAMES this module authoritatively SUPERSEDES. When the
554
- * host also lists (or `resourceDir`-discovers) a resource of the same name,
555
- * arc DROPS the app copy and registers THIS module's version instead — so the
556
- * host keeps NO hand-maintained "which resources did modules take over" filter
557
- * set. Ownership lives on the atom that provides it (colocated, drift-proof):
558
- *
559
- * ```ts
560
- * defineModule({ name: "order", owns: ["order", "quotation", "rfq"], resources: () => [...] })
561
- * ```
562
- *
563
- * Semantics:
564
- * - Purely a supersede-the-app-fork switch — it filters the *app* resource
565
- * list, never the module's own `resources` (those always register).
566
- * - Idempotent + tolerant on the APP side: an `owns` entry with no matching
567
- * app resource is a silent no-op — a module may pre-declare a name before
568
- * any fork exists.
569
- * - Collected across ALL modules; the app-side supersession is their union.
570
- *
571
- * **Prefer `owns: "provided"`** (2.32) — arc derives the list from the
572
- * resources this module actually returned, so the claim and the reality
573
- * cannot disagree:
574
- *
575
- * ```ts
576
- * defineModule({ name: "order", owns: "provided", resources: () => [...] })
577
- * ```
578
- *
579
- * That is the whole arm for most modules. Resources are resolved exactly
580
- * once, names are validated (duplicates within a module are rejected), the
581
- * effective `owns` is derived, and supersession runs afterward — one atomic
582
- * phase arc owns, rather than a rule each module re-states.
583
- *
584
- * **The explicit-array form is ENFORCED at boot: if you `owns` a name,
585
- * PROVIDE it** — in THIS module's own `resources`. Arc fails boot when a
586
- * claimed name is not among them, naming the module, the unmet names, and
587
- * what it did supply. Without that check, a typo or a resource deleted
588
- * without updating the list booted "successfully" with the app's route
589
- * silently removed and nothing serving it. Two real cases, both silent 404s:
590
- * a POS module claiming a checkout resource it mounted only when the host
591
- * supplied a pipeline, and a device gateway claiming a name it never
592
- * provided at all.
593
- *
594
- * Keep the explicit array only when the list is genuinely NOT the module's
595
- * own resource set — e.g. pre-declaring a name before the fork exists.
596
- *
597
- * A sibling module supplying the name does NOT satisfy the claim — ownership
598
- * is local to the module that declares it, which is the colocation this arm
599
- * exists for.
524
+ * App-level resource NAMES this module SUPERSEDES. When the host lists (or
525
+ * discovers) a resource of the same name, arc drops the app copy and
526
+ * registers this module's — so the host maintains no "which resources did
527
+ * modules take over" filter set.
528
+ *
529
+ * PREFER `owns: "provided"`: arc derives the list from the resources the
530
+ * module actually returned, so the claim cannot disagree with reality.
531
+ * Resources resolve once, names are validated, `owns` is derived, and
532
+ * supersession runs after — one phase arc owns.
533
+ *
534
+ * The explicit array is ENFORCED at boot: a claimed name must appear in THIS
535
+ * module's own `resources`, or boot fails naming the unmet names. Without
536
+ * that, a typo or a deleted resource booted "successfully" with the app's
537
+ * route removed and nothing serving it. A sibling module providing the name
538
+ * does NOT satisfy the claim — ownership is local to its declarer.
539
+ *
540
+ * It only filters the APP list, never the module's own resources; an entry
541
+ * matching no app resource is a silent no-op (a module may pre-declare a
542
+ * name before any fork exists). Collected across modules as a union.
600
543
  */
601
544
  readonly owns?: readonly string[] | "provided";
602
545
  /**
@@ -1,5 +1,5 @@
1
1
 
2
- import { V as ResourceDefinition } from "./index-BcR2bFZQ.mjs";
2
+ import { V as ResourceDefinition } from "./index-C5K78SXo.mjs";
3
3
  import { z } from "zod";
4
4
  //#region src/integrations/mcp/types.d.ts
5
5
  /** Behavioral hints for MCP clients (tool annotations per MCP spec) */
@@ -36,48 +36,17 @@ declare function requireSingleHeaderValue(headers: ArcHeaders | Record<string, s
36
36
  //#endregion
37
37
  //#region src/scope/types.d.ts
38
38
  /**
39
- * A capability mandate — declarative, time-boxed, optionally cap-bounded
40
- * authorization for a single high-value action by an AI agent or service.
39
+ * A capability mandate — time-boxed, optionally cap-bounded authorization for
40
+ * ONE high-value action by an agent or service.
41
41
  *
42
- * Models the **2025 agent-payments / agent-authorization conventions**:
43
- * - Google + Anthropic + Stripe **AP2** (Agent Payments Protocol)
44
- * - Stripe **x402 / Agentic Commerce**
45
- * - **MCP authorization** (RFC 9728 + RFC 9700 + RFC 9449)
42
+ * Where OAuth scopes answer "what may this client EVER do?", a mandate answers
43
+ * "what is THIS request authorized to do right now?" — narrower in capability,
44
+ * time, and value. Shape follows the 2025 agent-authorization conventions
45
+ * (AP2, x402, MCP authorization: RFC 9728/9700/9449).
46
46
  *
47
- * Where OAuth `scopes` answer "what can this client EVER do?", a mandate
48
- * answers "what is THIS REQUEST authorized to do RIGHT NOW?" — narrower in
49
- * capability, time, and value.
50
- *
51
- * Arc does **not** parse mandate JWTs / Verifiable Credentials — your
52
- * authenticate callback does (one `jose.jwtVerify()` or `did-jwt-vc.verify()`
53
- * call) and populates this object. Arc's `requireMandate(capability, opts)`
54
- * permission helper reads it and validates the action against the mandate's
55
- * declared bounds.
56
- *
57
- * @example
58
- * ```typescript
59
- * // Inbound: Authorization: Mandate eyJhbGc...
60
- * authenticate: async (request) => {
61
- * const proof = request.headers['authorization']?.replace(/^Mandate /, '');
62
- * const claims = await verifyMandate(proof); // host's verifier
63
- * request.scope = {
64
- * kind: 'service',
65
- * clientId: claims.iss,
66
- * organizationId: claims.org,
67
- * scopes: claims.scope?.split(' '),
68
- * mandate: {
69
- * id: claims.jti,
70
- * capability: claims.cap, // 'payment.charge' / 'inbox.send' / ...
71
- * cap: claims.amount, // numeric ceiling
72
- * expiresAt: claims.exp * 1000,
73
- * parent: claims.parent, // delegated mandate chain
74
- * audience: claims.aud, // resource id mandate is bound to
75
- * },
76
- * dpopJkt: claims.cnf?.jkt, // RFC 7638 — sender-constrained
77
- * };
78
- * return { id: claims.iss };
79
- * };
80
- * ```
47
+ * Arc does NOT verify mandate JWTs or VCs. The host's `authenticate` callback
48
+ * verifies and populates this object; `requireMandate(capability, opts)` then
49
+ * validates the action against its bounds.
81
50
  */
82
51
  interface Mandate {
83
52
  /** Mandate identifier — typically the JWT `jti` claim. */
@@ -252,36 +221,10 @@ declare function isAuthenticated(scope: RequestScope): boolean;
252
221
  /** Get organizationId from scope (member, service, or elevated — undefined otherwise) */
253
222
  declare function getOrgId(scope: RequestScope): string | undefined;
254
223
  /**
255
- * Resolve the tenant (organization) id from an incoming Fastify request,
256
- * walking the canonical sources in order: `request.scope` → `x-organization-id`
257
- * header. Returns `{ organizationId, source }` so callers can log or branch
258
- * on which path won.
259
- *
260
- * Use in custom handlers that bypass arc's auto-CRUD path (worker routes,
261
- * batch importers, cross-engine subscribers) and therefore don't get the
262
- * tenant injected by `BaseCrudController`. Bridges arc's HTTP shape to
263
- * the mongokit/kit-side tenant context (e.g. `createTenantContext().run`).
224
+ * Tenant id for a request, from its scope.
264
225
  *
265
- * Header fallback is intentional: matches `resolveOrgFromHeader` semantics
266
- * for hosts that select an org via header instead of session/scope. Don't
267
- * reach for this when `getOrgId(scope)` alone is enough — for standard
268
- * authenticated routes the scope is already authoritative.
269
- *
270
- * @example
271
- * ```typescript
272
- * import { getTenantFromRequest } from '@classytic/arc/scope';
273
- * import { tenantContext } from './lib/mongokit.js';
274
- *
275
- * fastify.post('/statements/batch', async (req, reply) => {
276
- * const { organizationId } = getTenantFromRequest(req);
277
- * if (!organizationId) {
278
- * return reply.code(400).send({ error: 'organizationId required' });
279
- * }
280
- * await tenantContext.run({ tenantId: organizationId }, async () => {
281
- * await statementRepository.create(req.body);
282
- * });
283
- * });
284
- * ```
226
+ * Reads the SCOPE, never `request.user` — the two drift once elevation or a
227
+ * service token is involved, and the scope is the resolved answer.
285
228
  */
286
229
  declare function getTenantFromRequest(req: {
287
230
  scope?: RequestScope;
@@ -510,27 +453,10 @@ declare function getOrgContext(request: {
510
453
  orgRoles: string[];
511
454
  };
512
455
  /**
513
- * Read `request.scope` safely from any object that *might* have one.
514
- * Falls back to `PUBLIC_SCOPE` when the field is absent or undefined.
515
- *
516
- * This is the canonical way for permission checks, presets, and middleware
517
- * to read scope — never access `request.scope` directly because it can be
518
- * `undefined` on requests that haven't been touched by an auth adapter yet.
519
- *
520
- * Accepts a structural shape (`{ scope?: RequestScope }`) instead of the
521
- * full Fastify request type so it can be called from any layer without
522
- * dragging in the Fastify type. The actual runtime is identical.
456
+ * Read `request.scope`, falling back to `PUBLIC_SCOPE`.
523
457
  *
524
- * @example
525
- * ```typescript
526
- * import { getRequestScope } from '@classytic/arc/scope';
527
- *
528
- * function myCheck(ctx: PermissionContext) {
529
- * const scope = getRequestScope(ctx.request);
530
- * if (isElevated(scope)) return true;
531
- * // ...
532
- * }
533
- * ```
458
+ * Never returns undefined: an absent scope means an unauthenticated request,
459
+ * not a missing one, and callers must not have to distinguish those.
534
460
  */
535
461
  declare function getRequestScope(request: {
536
462
  scope?: RequestScope;
@@ -576,38 +502,9 @@ interface ScopeFirstCtxRequest {
576
502
  headers?: ArcHeaders | undefined;
577
503
  }
578
504
  /**
579
- * The ONE shared actor/org derivation for resource handlers and module
580
- * packages (`arc-*` fleet) — scope-FIRST, per the canonical precedence:
581
- *
582
- * 1. `request.scope` (arc's validated `RequestScope`, set by auth adapters):
583
- * `userId` (human) or `clientId` (service) → `actorId`; `getOrgId(scope)`
584
- * → `organizationId`.
585
- * 2. The `x-organization-id` header — ONLY when the scope carries no org.
586
- * This is the bridge for custom-auth/public routes where arc leaves scope
587
- * unpopulated; it never overrides a validated scope.
588
- *
589
- * Replaces per-package hand-rolled clones of
590
- * `req.user?._id ?? req.user?.id ?? headers['x-organization-id']` — that
591
- * pattern re-implements (and drifts from) arc's canonical resolution. A
592
- * package's `ctxOf(req)` should call this for the shared
593
- * `{ actorId, organizationId }` and only ADD its kernel-specific fields
594
- * (`actorKind` / `correlationId` / `roles` / `idempotencyKey`).
595
- *
596
- * Structural request shape — works on a raw `FastifyRequest` AND on arc's
597
- * `IRequestContext` (see {@link ScopeFirstCtxRequest}: the discriminated
598
- * `RequestScope` and the flat controller projection are both understood).
599
- *
600
- * @example
601
- * ```typescript
602
- * import { scopeFirstCtx } from '@classytic/arc/scope';
603
- *
604
- * // Guaranteed actor (kernel context requires one):
605
- * const { actorId, organizationId } = scopeFirstCtx(req, { fallbackActorId: 'system' });
606
- *
607
- * // Optional actor (package applies its own policy):
608
- * const ctx = scopeFirstCtx(req);
609
- * if (ctx.actorId) audit.record({ actor: ctx.actorId });
610
- * ```
505
+ * Build a scope-first context for permission checks outside a Fastify request
506
+ * (jobs, MCP tools, workers). `scope` is the identity channel; `user` is
507
+ * derived for legacy checks that still read it.
611
508
  */
612
509
  declare function scopeFirstCtx(req: ScopeFirstCtxRequest, options: ScopeFirstCtxOptions & {
613
510
  fallbackActorId: string;
@@ -1,7 +1,7 @@
1
- /*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
2
- import { l as UnauthorizedError, o as OrgRequiredError } from "./errors-Cd_yy7aW.mjs";
3
- import { n as requireSingleHeaderValue } from "./headers-CveNO9gR.mjs";
4
- import { t as getUserId$1 } from "./userHelpers-CWF5pbZD.mjs";
1
+ /*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
2
+ import { l as UnauthorizedError, o as OrgRequiredError } from "./errors-CLid6atr.mjs";
3
+ import { n as requireSingleHeaderValue } from "./headers-DODWf7aC.mjs";
4
+ import { t as getUserId$1 } from "./userHelpers-AKcB4V03.mjs";
5
5
  //#region src/scope/types.ts
6
6
  /**
7
7
  * Request Scope — The One Standard
@@ -50,36 +50,10 @@ function getOrgId(scope) {
50
50
  if (scope.kind === "elevated") return scope.organizationId;
51
51
  }
52
52
  /**
53
- * Resolve the tenant (organization) id from an incoming Fastify request,
54
- * walking the canonical sources in order: `request.scope` → `x-organization-id`
55
- * header. Returns `{ organizationId, source }` so callers can log or branch
56
- * on which path won.
53
+ * Tenant id for a request, from its scope.
57
54
  *
58
- * Use in custom handlers that bypass arc's auto-CRUD path (worker routes,
59
- * batch importers, cross-engine subscribers) and therefore don't get the
60
- * tenant injected by `BaseCrudController`. Bridges arc's HTTP shape to
61
- * the mongokit/kit-side tenant context (e.g. `createTenantContext().run`).
62
- *
63
- * Header fallback is intentional: matches `resolveOrgFromHeader` semantics
64
- * for hosts that select an org via header instead of session/scope. Don't
65
- * reach for this when `getOrgId(scope)` alone is enough — for standard
66
- * authenticated routes the scope is already authoritative.
67
- *
68
- * @example
69
- * ```typescript
70
- * import { getTenantFromRequest } from '@classytic/arc/scope';
71
- * import { tenantContext } from './lib/mongokit.js';
72
- *
73
- * fastify.post('/statements/batch', async (req, reply) => {
74
- * const { organizationId } = getTenantFromRequest(req);
75
- * if (!organizationId) {
76
- * return reply.code(400).send({ error: 'organizationId required' });
77
- * }
78
- * await tenantContext.run({ tenantId: organizationId }, async () => {
79
- * await statementRepository.create(req.body);
80
- * });
81
- * });
82
- * ```
55
+ * Reads the SCOPE, never `request.user` — the two drift once elevation or a
56
+ * service token is involved, and the scope is the resolved answer.
83
57
  */
84
58
  function getTenantFromRequest(req, options = {}) {
85
59
  if (req.scope) {
@@ -374,27 +348,10 @@ function getOrgContext(request) {
374
348
  };
375
349
  }
376
350
  /**
377
- * Read `request.scope` safely from any object that *might* have one.
378
- * Falls back to `PUBLIC_SCOPE` when the field is absent or undefined.
379
- *
380
- * This is the canonical way for permission checks, presets, and middleware
381
- * to read scope — never access `request.scope` directly because it can be
382
- * `undefined` on requests that haven't been touched by an auth adapter yet.
351
+ * Read `request.scope`, falling back to `PUBLIC_SCOPE`.
383
352
  *
384
- * Accepts a structural shape (`{ scope?: RequestScope }`) instead of the
385
- * full Fastify request type so it can be called from any layer without
386
- * dragging in the Fastify type. The actual runtime is identical.
387
- *
388
- * @example
389
- * ```typescript
390
- * import { getRequestScope } from '@classytic/arc/scope';
391
- *
392
- * function myCheck(ctx: PermissionContext) {
393
- * const scope = getRequestScope(ctx.request);
394
- * if (isElevated(scope)) return true;
395
- * // ...
396
- * }
397
- * ```
353
+ * Never returns undefined: an absent scope means an unauthenticated request,
354
+ * not a missing one, and callers must not have to distinguish those.
398
355
  */
399
356
  function getRequestScope(request) {
400
357
  return request.scope ?? PUBLIC_SCOPE;
@@ -1,6 +1,6 @@
1
1
 
2
- import { i as RequestScope } from "../types-ChuShpCP.mjs";
3
- import { l as PermissionCheck, u as PermissionContext } from "../base-Csjc2oF-.mjs";
2
+ import { i as RequestScope } from "../types-Ddl9OjmE.mjs";
3
+ import { l as PermissionCheck, u as PermissionContext } from "../base-GZU3LlzP.mjs";
4
4
  import { UsageBucket, UsageStore, usagePeriod } from "@classytic/repo-core/usage";
5
5
  import { FastifyPluginAsync, FastifyRequest } from "fastify";
6
6
  //#region src/usage/requireQuota.d.ts
Binary file
@@ -1,4 +1,4 @@
1
- /*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
2
2
  //#region src/utils/userHelpers.ts
3
3
  /**
4
4
  * Extract a user ID from a user object. Accepts `id` or `_id` — returns
@@ -1,7 +1,7 @@
1
1
 
2
- import { F as getHeader, I as requireSingleHeaderValue, P as ArcHeaders } from "../types-ChuShpCP.mjs";
3
- import { f as getUserId, m as normalizeRoles, p as getUserRoles, t as AnyRecord } from "../base-Csjc2oF-.mjs";
4
- import { $ as OpenApiSchemas, S as QueryParserInterface, b as ParsedQuery } from "../index-BcR2bFZQ.mjs";
2
+ import { F as getHeader, I as requireSingleHeaderValue, P as ArcHeaders } from "../types-Ddl9OjmE.mjs";
3
+ import { f as getUserId, m as normalizeRoles, p as getUserRoles, t as AnyRecord } from "../base-GZU3LlzP.mjs";
4
+ import { $ as OpenApiSchemas, S as QueryParserInterface, b as ParsedQuery } from "../index-C5K78SXo.mjs";
5
5
  import { n as ErrorMapper } from "../errorHandler-DI5AN2b5.mjs";
6
6
  import { a as NotFoundError, c as RateLimitError, d as ValidationError, f as createDomainError, i as ForbiddenError, l as ServiceUnavailableError, m as isArcError, n as ConflictError, o as OrgAccessDeniedError, p as createError, r as ErrorOptions, s as OrgRequiredError, t as ArcError, u as UnauthorizedError } from "../errors-BGdVwP25.mjs";
7
7
  import { errorContractSchema, errorDetailSchema } from "@classytic/repo-core/errors";
@@ -1243,50 +1243,24 @@ declare function convertRouteSchema(schema: Record<string, unknown>, target?: Js
1243
1243
  * `simpleEqualityMatcher` — a minimal, dialect-agnostic flat-key equality
1244
1244
  * matcher for `DataAdapter.matchesFilter` / `BaseController({ matchesFilter })`.
1245
1245
  *
1246
- * **What it does:** for each `[key, expected]` in the filter, compares
1247
- * `item[key]` to `expected` via string coercion (so Mongo `ObjectId` values
1248
- * match their string representation) and returns `true` only if every
1249
- * filter entry matches. Array item values are matched implicitly (contains).
1246
+ * Compares `item[key]` to each filter value by string coercion, so a Mongo
1247
+ * `ObjectId` matches its string form; array values match by contains. ALL
1248
+ * entries must match.
1250
1249
  *
1251
- * **What it does NOT do:**
1252
- * - No `$eq` / `$ne` / `$in` / `$nin` / `$gt` / `$lt` / `$regex` / `$exists`
1253
- * - No `$and` / `$or`
1254
- * - No dot-path traversal (`"owner.id"`)
1255
- * - No schema-specific coercion
1250
+ * NOT an operator engine: no `$in`/`$ne`/`$gt`/`$regex`/`$exists`, no
1251
+ * `$and`/`$or`, no dot paths, no schema coercion. Most `_policyFilters` from
1252
+ * arc's built-in permission helpers are flat equality (`{ ownerId }`,
1253
+ * `{ organizationId }`), and this covers exactly that — defense-in-depth for
1254
+ * hosts on minimal repos with no `getOne(compoundFilter)` path.
1256
1255
  *
1257
- * **Why it exists:** 95%+ of arc's `_policyFilters` are produced by built-in
1258
- * permission helpers and are shaped like `{ ownerId: "u1" }` or
1259
- * `{ organizationId: "org_x" }` — flat equality. For that common shape,
1260
- * this helper is a safe, tested, 15-line defense-in-depth matcher that
1261
- * hosts using minimal repos (no `getOne(compoundFilter)` DB path) can opt
1262
- * into without arc shipping a full Mongo-syntax engine.
1263
- *
1264
- * **When to use:**
1265
- * - Your adapter/repo doesn't natively filter on `getOne(compoundFilter)`
1266
- * - Your `_policyFilters` are flat equality (from arc's built-in permission helpers)
1267
- * - You want defense-in-depth on `validateItemAccess` / `fetchDetailed`'s `getById` fallback
1268
- *
1269
- * **When NOT to use:**
1270
- * - Your `_policyFilters` use operators (`$in`, `$ne`, etc.) — supply a
1271
- * native matcher (mongokit's repo does the filter at the DB layer; for
1272
- * custom repos, wrap the kit's own predicate engine).
1273
- * - You're a mongokit / sqlitekit / Prisma user — the DB-level filter
1274
- * applied by `getOne(compoundFilter)` already covers this.
1256
+ * Do NOT use it with operator-shaped filters — supply a native matcher instead
1257
+ * (a kit's predicate engine). Kit users need neither: the DB-level filter in
1258
+ * `getOne(compoundFilter)` already applies.
1275
1259
  *
1276
1260
  * @example
1277
1261
  * ```ts
1278
- * import { simpleEqualityMatcher } from '@classytic/arc/utils';
1279
- *
1280
- * // On a custom adapter
1281
- * const adapter: DataAdapter = {
1282
- * repository,
1283
- * type: 'custom',
1284
- * name: 'in-memory',
1285
- * matchesFilter: simpleEqualityMatcher,
1286
- * };
1287
- *
1288
- * // Or directly on BaseController for ad-hoc controllers
1289
- * new BaseController(repo, { matchesFilter: simpleEqualityMatcher });
1262
+ * const adapter: DataAdapter = { repository, type: 'custom', name: 'in-memory',
1263
+ * matchesFilter: simpleEqualityMatcher };
1290
1264
  * ```
1291
1265
  */
1292
1266
  declare function simpleEqualityMatcher(item: unknown, filters: Record<string, unknown>): boolean;
@@ -1,12 +1,12 @@
1
- /*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
2
- import { a as OrgAccessDeniedError, c as ServiceUnavailableError, d as createDomainError, f as createError, i as NotFoundError, l as UnauthorizedError, n as ConflictError, o as OrgRequiredError, p as isArcError, r as ForbiddenError, s as RateLimitError, t as ArcError, u as ValidationError } from "../errors-Cd_yy7aW.mjs";
3
- import { n as requireSingleHeaderValue, t as getHeader } from "../headers-CveNO9gR.mjs";
4
- import { n as getUserRoles, r as normalizeRoles, t as getUserId } from "../userHelpers-CWF5pbZD.mjs";
5
- import { t as simpleEqualityMatcher } from "../simpleEqualityMatcher-Se8VrsaP.mjs";
6
- import { A as createCircuitBreakerRegistry, C as defineCompensation, D as CircuitBreakerRegistry, E as CircuitBreakerError, O as CircuitState, S as defineErrorMapper, T as CircuitBreaker, _ as createQueryParser, a as deleteResponse, b as NEUTRAL_DIALECT, c as getDefaultCrudSchemas, d as listResponse, f as offsetListResponse, g as ArcQueryParser, h as responses, i as bareListResponse, k as createCircuitBreaker, l as getListQueryParams, m as queryParams, n as scheduleBackground, o as errorContractSchema, p as paginationSchema, r as aggregateListResponse, s as errorDetailSchema, t as createStateMachine, u as keysetListResponse, v as handleRaw, w as withCompensation, x as defineGuard, y as MONGO_DIALECT } from "../utils-h1V_sT-t.mjs";
7
- import { n as declareRuntimeCapability } from "../runtimeCapabilities-Dm88DaTW.mjs";
8
- import { a as isZodSchema, i as isJsonSchema, n as convertRouteSchema, o as toJsonSchema, t as convertOpenApiSchemas } from "../schemaConverter-XH1RZRyu.mjs";
9
- import { a as promoteStreamTokenToHeader, i as pipeUIMessageStreamToReply, n as forwardedStreamHeaders, r as isReadableStream, t as UI_MESSAGE_STREAM_HEADERS } from "../streaming-DsT1B5zJ.mjs";
10
- import { t as openSseStream } from "../sseStream-Bvpi-UXQ.mjs";
11
- import { t as hasEvents } from "../typeGuards-jjKJDN13.mjs";
1
+ /*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
2
+ import { a as OrgAccessDeniedError, c as ServiceUnavailableError, d as createDomainError, f as createError, i as NotFoundError, l as UnauthorizedError, n as ConflictError, o as OrgRequiredError, p as isArcError, r as ForbiddenError, s as RateLimitError, t as ArcError, u as ValidationError } from "../errors-CLid6atr.mjs";
3
+ import { n as requireSingleHeaderValue, t as getHeader } from "../headers-DODWf7aC.mjs";
4
+ import { n as getUserRoles, r as normalizeRoles, t as getUserId } from "../userHelpers-AKcB4V03.mjs";
5
+ import { t as simpleEqualityMatcher } from "../simpleEqualityMatcher-BO-sFTQf.mjs";
6
+ import { A as createCircuitBreakerRegistry, C as defineCompensation, D as CircuitBreakerRegistry, E as CircuitBreakerError, O as CircuitState, S as defineErrorMapper, T as CircuitBreaker, _ as createQueryParser, a as deleteResponse, b as NEUTRAL_DIALECT, c as getDefaultCrudSchemas, d as listResponse, f as offsetListResponse, g as ArcQueryParser, h as responses, i as bareListResponse, k as createCircuitBreaker, l as getListQueryParams, m as queryParams, n as scheduleBackground, o as errorContractSchema, p as paginationSchema, r as aggregateListResponse, s as errorDetailSchema, t as createStateMachine, u as keysetListResponse, v as handleRaw, w as withCompensation, x as defineGuard, y as MONGO_DIALECT } from "../utils-CBK9HQOI.mjs";
7
+ import { n as declareRuntimeCapability } from "../runtimeCapabilities-BagWc3TI.mjs";
8
+ import { a as isZodSchema, i as isJsonSchema, n as convertRouteSchema, o as toJsonSchema, t as convertOpenApiSchemas } from "../schemaConverter-D2_bHGil.mjs";
9
+ import { a as promoteStreamTokenToHeader, i as pipeUIMessageStreamToReply, n as forwardedStreamHeaders, r as isReadableStream, t as UI_MESSAGE_STREAM_HEADERS } from "../streaming-DOpZVht6.mjs";
10
+ import { t as openSseStream } from "../sseStream-ByFGyIVr.mjs";
11
+ import { t as hasEvents } from "../typeGuards-B-_jqaMi.mjs";
12
12
  export { ArcError, ArcQueryParser, CircuitBreaker, CircuitBreakerError, CircuitBreakerRegistry, CircuitState, ConflictError, ForbiddenError, MONGO_DIALECT, NEUTRAL_DIALECT, NotFoundError, OrgAccessDeniedError, OrgRequiredError, RateLimitError, ServiceUnavailableError, UI_MESSAGE_STREAM_HEADERS, UnauthorizedError, ValidationError, aggregateListResponse, bareListResponse, convertOpenApiSchemas, convertRouteSchema, createCircuitBreaker, createCircuitBreakerRegistry, createDomainError, createError, createQueryParser, createStateMachine, declareRuntimeCapability, defineCompensation, defineErrorMapper, defineGuard, deleteResponse, errorContractSchema, errorDetailSchema, forwardedStreamHeaders, getDefaultCrudSchemas, getHeader, getListQueryParams, getUserId, getUserRoles, handleRaw, hasEvents, isArcError, isJsonSchema, isReadableStream, isZodSchema, keysetListResponse, listResponse, normalizeRoles, offsetListResponse, openSseStream, paginationSchema, pipeUIMessageStreamToReply, promoteStreamTokenToHeader, queryParams, requireSingleHeaderValue, responses, scheduleBackground, simpleEqualityMatcher, toJsonSchema, withCompensation };
@@ -1,7 +1,7 @@
1
- /*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
2
- import { m as RESERVED_QUERY_PARAMS } from "./constants-BxCoxmiN.mjs";
1
+ /*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
2
+ import { m as RESERVED_QUERY_PARAMS } from "./constants-BhzLXCfN.mjs";
3
3
  import { arcLog } from "./logger/index.mjs";
4
- import { t as ArcError, u as ValidationError } from "./errors-Cd_yy7aW.mjs";
4
+ import { t as ArcError, u as ValidationError } from "./errors-CLid6atr.mjs";
5
5
  import { errorContractSchema as errorContractSchema$1, errorDetailSchema as errorDetailSchema$1 } from "@classytic/repo-core/errors";
6
6
  import { scheduleBackground } from "@classytic/repo-core/cache";
7
7
  //#region src/utils/circuitBreaker.ts
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
2
- import { t as __exportAll } from "./rolldown-runtime-DNg-KNCk.mjs";
1
+ /*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
2
+ import { t as __exportAll } from "./rolldown-runtime-CEvvVXTC.mjs";
3
3
  //#region src/core/aggregation/normalize.ts
4
4
  /**
5
5
  * Framework cap on URL-driven aggregation limits when the host opts
@@ -1,6 +1,6 @@
1
- /*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
2
- import { t as __exportAll } from "./rolldown-runtime-DNg-KNCk.mjs";
3
- import { d as createDomainError } from "./errors-Cd_yy7aW.mjs";
1
+ /*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
2
+ import { t as __exportAll } from "./rolldown-runtime-CEvvVXTC.mjs";
3
+ import { d as createDomainError } from "./errors-CLid6atr.mjs";
4
4
  import fp from "fastify-plugin";
5
5
  //#region src/plugins/versioning.ts
6
6
  var versioning_exports = /* @__PURE__ */ __exportAll({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classytic/arc",
3
- "version": "2.34.0",
3
+ "version": "2.35.0",
4
4
  "description": "Resource-oriented backend framework for Fastify - clean, minimal, powerful, tree-shakable",
5
5
  "type": "module",
6
6
  "exports": {
@@ -351,8 +351,8 @@
351
351
  "node": ">=22"
352
352
  },
353
353
  "peerDependencies": {
354
- "@classytic/primitives": ">=0.23.0",
355
- "@classytic/repo-core": ">=0.24.0",
354
+ "@classytic/primitives": ">=0.25.0",
355
+ "@classytic/repo-core": ">=0.25.0",
356
356
  "@classytic/streamline": ">=2.8.0",
357
357
  "@fastify/cors": ">=11.0.0",
358
358
  "@fastify/helmet": ">=13.0.0",
@@ -373,7 +373,7 @@
373
373
  "@opentelemetry/sdk-node": ">=0.50.0",
374
374
  "better-auth": ">=1.6.2",
375
375
  "bullmq": ">=5.0.0",
376
- "fastify": ">=5.8.5",
376
+ "fastify": ">=5.12.0",
377
377
  "fastify-raw-body": ">=5.0.0",
378
378
  "h3-js": ">=4.0.0",
379
379
  "ioredis": ">=5.0.0",
@@ -483,8 +483,8 @@
483
483
  "@classytic/gitkit": ">=0.1.0",
484
484
  "@classytic/mongokit": "^3.33.0",
485
485
  "@classytic/pgkit": "^0.1.0",
486
- "@classytic/primitives": "^0.23.0",
487
- "@classytic/repo-core": "^0.24.0",
486
+ "@classytic/primitives": "^0.25.0",
487
+ "@classytic/repo-core": "^0.25.0",
488
488
  "@classytic/sqlitekit": "^0.9.0",
489
489
  "@classytic/streamline": "^2.8.2",
490
490
  "@electric-sql/pglite": "^0.5.4",
@@ -505,12 +505,12 @@
505
505
  "@vitest/coverage-v8": "^4.1.9",
506
506
  "ajv": "^8.20.0",
507
507
  "better-auth": "^1.6.25",
508
- "better-sqlite3": "^13.0.3",
508
+ "better-sqlite3": "^12.4.1",
509
509
  "bullmq": "^6.1.2",
510
510
  "dotenv": "^17.4.2",
511
511
  "drizzle-orm": "^0.45.2",
512
512
  "fast-check": "^4.8.0",
513
- "fastify": "^5.12.0",
513
+ "fastify": "^5.12.1",
514
514
  "fastify-raw-body": "^6.0.1",
515
515
  "h3-js": "^4.4.0",
516
516
  "ioredis": "^6.0.0",