@classytic/arc 2.28.0 → 2.31.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 (239) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +7 -0
  3. package/TRADEMARK.md +22 -0
  4. package/dist/{BaseController-B65zbz9m.mjs → BaseController-De7GqHck.mjs} +25 -24
  5. package/dist/{EventTransport-QmY7A258.d.mts → EventTransport-2uVV34WU.d.mts} +1 -0
  6. package/dist/EventTransport-9mlTgqzE.mjs +104 -0
  7. package/dist/{HookSystem-C1vB_Gc9.mjs → HookSystem-BcmPyq5I.mjs} +16 -35
  8. package/dist/{QueryCache-DOMT_iq7.d.mts → QueryCache-DFA-QrU9.d.mts} +2 -1
  9. package/dist/{ResourceRegistry-y9Hnypus.mjs → ResourceRegistry-qq0mn2s9.mjs} +3 -2
  10. package/dist/{actionPermissions-CAphcmUG.mjs → actionPermissions-BE5NwaQk.mjs} +1 -0
  11. package/dist/audit/index.d.mts +3 -2
  12. package/dist/audit/index.mjs +3 -2
  13. package/dist/auth/audit.d.mts +1 -0
  14. package/dist/auth/audit.mjs +1 -0
  15. package/dist/auth/index.d.mts +5 -4
  16. package/dist/auth/index.mjs +6 -5
  17. package/dist/auth/redis-session.d.mts +2 -1
  18. package/dist/auth/redis-session.mjs +1 -0
  19. package/dist/authorizationDecision-ChvUQGG1.mjs +266 -0
  20. package/dist/{buildHandler-Dtwd8fdz.mjs → buildHandler-CDrCJzmB.mjs} +34 -7
  21. package/dist/cache/index.d.mts +4 -3
  22. package/dist/cache/index.mjs +4 -3
  23. package/dist/{caching-_NJeDd1_.mjs → caching-BFHA6Scf.mjs} +2 -1
  24. package/dist/cleanup/index.d.mts +4 -3
  25. package/dist/cleanup/index.mjs +9 -13
  26. package/dist/cli/commands/describe.d.mts +2 -1
  27. package/dist/cli/commands/describe.mjs +3 -2
  28. package/dist/cli/commands/docs.d.mts +1 -0
  29. package/dist/cli/commands/docs.mjs +3 -2
  30. package/dist/cli/commands/doctor.d.mts +1 -0
  31. package/dist/cli/commands/doctor.mjs +1 -0
  32. package/dist/cli/commands/generate.d.mts +2 -1
  33. package/dist/cli/commands/generate.mjs +2 -1
  34. package/dist/cli/commands/init.d.mts +2 -1
  35. package/dist/cli/commands/init.mjs +2 -1
  36. package/dist/cli/commands/introspect.d.mts +1 -0
  37. package/dist/cli/commands/introspect.mjs +2 -1
  38. package/dist/cli/index.d.mts +3 -2
  39. package/dist/cli/index.mjs +3 -2
  40. package/dist/{constants-DNre0wRg.mjs → constants-D3Dv4LAV.mjs} +1 -0
  41. package/dist/context/index.d.mts +1 -0
  42. package/dist/context/index.mjs +3 -2
  43. package/dist/core/index.d.mts +3 -2
  44. package/dist/core/index.mjs +7 -5
  45. package/dist/{core-BGa8TXJR.mjs → core-BGpIxINN.mjs} +4 -49
  46. package/dist/{createActionRouter-C-N7z2EL.mjs → createActionRouter-CDXEdasl.mjs} +8 -7
  47. package/dist/{createAggregationRouter-wzwFa_dW.mjs → createAggregationRouter-KrQDzx-k.mjs} +10 -22
  48. package/dist/{createApp-Du5G54TM.mjs → createApp-Df89BEni.mjs} +505 -209
  49. package/dist/defineAggregation-DbPPS8RI.mjs +48 -0
  50. package/dist/{defineResource-2zvVVpxg.mjs → defineResource-Bv6EtN1x.mjs} +90 -72
  51. package/dist/discovery/index.d.mts +1 -0
  52. package/dist/discovery/index.mjs +1 -0
  53. package/dist/docs/index.d.mts +3 -2
  54. package/dist/docs/index.mjs +3 -2
  55. package/dist/{elevation-C9s5hFP_.d.mts → elevation-BXCfVcNG.d.mts} +1 -0
  56. package/dist/{elevation-CIz1GjGm.mjs → elevation-D2l1mh4g.mjs} +4 -3
  57. package/dist/encryption/index.d.mts +2 -1
  58. package/dist/encryption/index.mjs +3 -2
  59. package/dist/{errorHandler-Bq2OeEQL.mjs → errorHandler-C5NeD6bT.mjs} +3 -2
  60. package/dist/{errorHandler-C6yv4ZTW.d.mts → errorHandler-CpYUJmPA.d.mts} +1 -0
  61. package/dist/{errors-DHcHVAgk.d.mts → errors-BGdVwP25.d.mts} +1 -0
  62. package/dist/{errors-DkO8Nk6-.mjs → errors-Cj42AntO.mjs} +1 -0
  63. package/dist/{eventPlugin-DrQ_FesK.mjs → eventPlugin-CkffEihm.mjs} +6 -106
  64. package/dist/{eventPlugin-Bg3cP2_u.d.mts → eventPlugin-GF5nnBIq.d.mts} +2 -1
  65. package/dist/events/index.d.mts +4 -3
  66. package/dist/events/index.mjs +17 -340
  67. package/dist/events/transports/redis-stream-entry.d.mts +2 -1
  68. package/dist/events/transports/redis-stream-entry.mjs +1 -0
  69. package/dist/events/transports/redis.d.mts +2 -1
  70. package/dist/events/transports/redis.mjs +1 -0
  71. package/dist/{externalPaths-BE6wFpYv.d.mts → externalPaths-CmGOxOtD.d.mts} +1 -0
  72. package/dist/factory/index.d.mts +9 -5
  73. package/dist/factory/index.mjs +7 -6
  74. package/dist/{fastify-augmentation-OzYGIiU1.d.mts → fastify-augmentation-zh0_AYHa.d.mts} +13 -4
  75. package/dist/{applyPermissionResult-BnyVE9eD.mjs → fields-CB5Cuzk9.mjs} +2 -107
  76. package/dist/{fields-D3lhgzhD.d.mts → fields-I_EeRWND.d.mts} +1 -0
  77. package/dist/{generate-BnsL9GBm.d.mts → generate-DCGuEbqI.d.mts} +1 -0
  78. package/dist/{generate-D0wZupBg.mjs → generate-EcA6ui4i.mjs} +2 -1
  79. package/dist/{headers-BvlQSDMB.mjs → headers-3zvE0rM3.mjs} +2 -1
  80. package/dist/{health-CB_m4S32.mjs → health-DjZYjM7H.mjs} +1 -0
  81. package/dist/hooks/index.d.mts +2 -1
  82. package/dist/hooks/index.mjs +2 -1
  83. package/dist/idempotency/index.d.mts +3 -2
  84. package/dist/idempotency/index.mjs +5 -4
  85. package/dist/idempotency/redis.d.mts +2 -1
  86. package/dist/idempotency/redis.mjs +1 -0
  87. package/dist/{index-CjVg-Epg.d.mts → index-Bc2ox8_U.d.mts} +6 -5
  88. package/dist/{index-CG4yqMDB.d.mts → index-C-481Zf2.d.mts} +74 -18
  89. package/dist/{index-BMnbzvtO.d.mts → index-CEJNZFtX.d.mts} +242 -24
  90. package/dist/index-CFThn1K9.d.mts +224 -0
  91. package/dist/{index-DPRH0Cme.d.mts → index-CpzxqePp.d.mts} +203 -97
  92. package/dist/index.d.mts +9 -8
  93. package/dist/index.mjs +11 -9
  94. package/dist/{init-tlRSt667.mjs → init-BEiNZBsJ.mjs} +19 -23
  95. package/dist/{init-BPEu8cs-.d.mts → init-Cscs4lab.d.mts} +1 -0
  96. package/dist/integrations/event-gateway.d.mts +3 -2
  97. package/dist/integrations/event-gateway.mjs +2 -1
  98. package/dist/integrations/index.d.mts +4 -3
  99. package/dist/integrations/index.mjs +1 -0
  100. package/dist/integrations/jobs/index.d.mts +2 -1
  101. package/dist/integrations/jobs/index.mjs +108 -32
  102. package/dist/integrations/mcp/index.d.mts +9 -9
  103. package/dist/integrations/mcp/index.mjs +2 -1
  104. package/dist/integrations/mcp/testing.d.mts +3 -2
  105. package/dist/integrations/mcp/testing.mjs +2 -2
  106. package/dist/integrations/streamline.d.mts +1 -0
  107. package/dist/integrations/streamline.mjs +3 -2
  108. package/dist/integrations/webhooks.d.mts +1 -0
  109. package/dist/integrations/webhooks.mjs +1 -0
  110. package/dist/integrations/websocket-pushref-redis.d.mts +2 -1
  111. package/dist/integrations/websocket-pushref-redis.mjs +1 -0
  112. package/dist/integrations/websocket-redis.d.mts +2 -1
  113. package/dist/integrations/websocket-redis.mjs +1 -0
  114. package/dist/integrations/websocket.d.mts +3 -2
  115. package/dist/integrations/websocket.mjs +1 -0
  116. package/dist/{interface-BGZCzOGL.d.mts → interface-BOk3YnTz.d.mts} +1 -0
  117. package/dist/{interface-Uk8ONJv7.d.mts → interface-DEWNOMza.d.mts} +1 -0
  118. package/dist/{interface-n5hpKg1d.mjs → interface-DYzM0q-u.mjs} +1 -0
  119. package/dist/{jsonBody-BlzAoGCe.mjs → jsonBody-BYbLDi5D.mjs} +2 -1
  120. package/dist/{keys-Cd316u_y.mjs → keys-C0_pa1tY.mjs} +1 -0
  121. package/dist/{loadResources-DpU8pfjV.mjs → loadResources-yawi9tAE.mjs} +2 -1
  122. package/dist/{loadResourcesFromEntry-kvGT6EcO.mjs → loadResourcesFromEntry-BAjYZonx.mjs} +2 -1
  123. package/dist/logger/index.d.mts +1 -0
  124. package/dist/logger/index.mjs +1 -0
  125. package/dist/{mcpPlugin-Cs6nRGCt.mjs → mcpPlugin-B_es0hiF.mjs} +52 -60
  126. package/dist/{memory-CmnzXE5Z.mjs → memory-DR6wpa9F.mjs} +2 -1
  127. package/dist/{metrics-fdxI5mn_.mjs → metrics-CUdw_wLB.mjs} +2 -1
  128. package/dist/middleware/index.d.mts +2 -1
  129. package/dist/middleware/index.mjs +3 -2
  130. package/dist/migrations/index.d.mts +1 -3
  131. package/dist/migrations/index.mjs +2 -4
  132. package/dist/module-0pFJA6YW.mjs +78 -0
  133. package/dist/{multipartBody-D0eBvkeq.mjs → multipartBody-wOgj_fnj.mjs} +1 -0
  134. package/dist/{openapi-BLV4OMXb.mjs → openapi-B2L4js1v.mjs} +6 -5
  135. package/dist/permissions/index.d.mts +5 -4
  136. package/dist/permissions/index.mjs +6 -4
  137. package/dist/{permissions-BrtiBKGs.mjs → permissions-L--QDAir.mjs} +518 -316
  138. package/dist/{pipe-BOLmGIxa.mjs → pipe-DRDNsI2T.mjs} +2 -1
  139. package/dist/pipeline/index.d.mts +2 -1
  140. package/dist/pipeline/index.mjs +2 -1
  141. package/dist/{pipeline-BGRnV-To.mjs → pipeline-UPQFatit.mjs} +7 -20
  142. package/dist/plugins/index.d.mts +8 -7
  143. package/dist/plugins/index.mjs +16 -15
  144. package/dist/plugins/response-cache.d.mts +1 -0
  145. package/dist/plugins/response-cache.mjs +2 -1
  146. package/dist/plugins/tracing-entry.d.mts +2 -1
  147. package/dist/plugins/tracing-entry.mjs +2 -1
  148. package/dist/{pluralize-BhrgwZb9.mjs → pluralize-O0FZgESl.mjs} +1 -0
  149. package/dist/{preloadResources-CM4uUaFv.d.mts → preloadResources-CyoJMSiO.d.mts} +117 -12
  150. package/dist/{preloadResources-DSY5HGpS.mjs → preloadResources-Dz6BjzM6.mjs} +1 -0
  151. package/dist/presets/filesUpload.d.mts +6 -5
  152. package/dist/presets/filesUpload.mjs +9 -11
  153. package/dist/presets/index.d.mts +15 -2
  154. package/dist/presets/index.mjs +2 -1
  155. package/dist/presets/multiTenant.d.mts +2 -1
  156. package/dist/presets/multiTenant.mjs +3 -2
  157. package/dist/presets/search.d.mts +3 -2
  158. package/dist/presets/search.mjs +2 -1
  159. package/dist/{presets-DwFDVKP0.mjs → presets-C4-g4_4P.mjs} +27 -10
  160. package/dist/projection-BHw6xlOQ.mjs +18 -0
  161. package/dist/{pushref-registry-BbcnpNTm.d.mts → pushref-registry-Dov9l4qE.d.mts} +1 -0
  162. package/dist/{queryCachePlugin-DSGuSVLW.mjs → queryCachePlugin-BZr8v46E.mjs} +5 -4
  163. package/dist/{queryCachePlugin-br4otiqF.d.mts → queryCachePlugin-BzqxconG.d.mts} +3 -2
  164. package/dist/{rateLimit-DrED-C4v.mjs → rateLimit-CMPY5Qms.mjs} +7 -3
  165. package/dist/{rateLimitKey-BoWRH3e7.mjs → rateLimitKey-Dn5JNmkj.mjs} +1 -0
  166. package/dist/{realtime-DEuDu9io.mjs → realtime-C5NoxWFY.mjs} +20 -8
  167. package/dist/{redis-UDtLaNj6.d.mts → redis-CduhKsJi.d.mts} +2 -1
  168. package/dist/{redis-stream-uIaauNpZ.d.mts → redis-stream-qN6A-RFv.d.mts} +2 -1
  169. package/dist/{registerRoute-DTp18Ah_.mjs → registerRoute-CBN84fc7.mjs} +5 -2
  170. package/dist/registry/index.d.mts +3 -2
  171. package/dist/registry/index.mjs +3 -2
  172. package/dist/{registry-9km_w1aP.mjs → registry-4213U4zb.mjs} +3 -2
  173. package/dist/{renewingLease-3cuQH7h8.mjs → renewingLease-Dll8mGgc.mjs} +1 -0
  174. package/dist/{replyHelpers-67tRawQZ.mjs → replyHelpers-DIiZKGUt.mjs} +2 -1
  175. package/dist/repositoryFilter-f9eAfq_l.mjs +45 -0
  176. package/dist/{requestContext-MrlJwECf.mjs → requestContext-2TxXOJ7T.mjs} +1 -0
  177. package/dist/{rolldown-runtime-8H4AJuhK.mjs → rolldown-runtime-CUsjNX9R.mjs} +1 -0
  178. package/dist/{schedules-CjOd2MG9.mjs → schedules-DdtlICTf.mjs} +3 -2
  179. package/dist/{schemaConverter-DJvodiHj.mjs → schemaConverter-D--wdJM-.mjs} +70 -17
  180. package/dist/{schemaIR-Ca7ySNPx.mjs → schemaIR-Bm2enbnh.mjs} +2 -1
  181. package/dist/schemas/index.d.mts +1 -0
  182. package/dist/schemas/index.mjs +1 -0
  183. package/dist/scim/index.d.mts +1 -0
  184. package/dist/scim/index.mjs +2 -1
  185. package/dist/scope/index.d.mts +3 -2
  186. package/dist/scope/index.mjs +5 -4
  187. package/dist/{scope-DfaPntpo.mjs → scope-DHx5Fous.mjs} +4 -3
  188. package/dist/{sessionManager-BHOM3N_0.d.mts → sessionManager-qimlKV0P.d.mts} +1 -0
  189. package/dist/{simpleEqualityMatcher-Cg05HPsn.mjs → simpleEqualityMatcher-DjQJ7FKA.mjs} +1 -0
  190. package/dist/{sse-BQ1w0dfl.mjs → sse-CUTo9y0X.mjs} +5 -4
  191. package/dist/{sseStream-BQ7Qaynp.mjs → sseStream-B_5XcVVd.mjs} +2 -1
  192. package/dist/{storage-DLUZ04kK.d.mts → storage-Cx9Sz3Ou.d.mts} +1 -0
  193. package/dist/{store-helpers-DY6xq4sM.mjs → store-helpers-D1MP_gRG.mjs} +1 -0
  194. package/dist/{streaming-BQcW6_Kq.mjs → streaming-PSZwi8JV.mjs} +1 -0
  195. package/dist/subscribe-helpers-C0Tb2aUp.mjs +340 -0
  196. package/dist/sync/changelog.d.mts +1 -0
  197. package/dist/sync/changelog.mjs +1 -0
  198. package/dist/testing/cleanupStoreContract.d.mts +2 -1
  199. package/dist/testing/cleanupStoreContract.mjs +1 -0
  200. package/dist/testing/index.d.mts +167 -12
  201. package/dist/testing/index.mjs +522 -205
  202. package/dist/testing/outboxStoreContract.d.mts +1 -0
  203. package/dist/testing/outboxStoreContract.mjs +1 -0
  204. package/dist/testing/storageContract.d.mts +2 -1
  205. package/dist/testing/storageContract.mjs +1 -0
  206. package/dist/{tracing-CsGKQJGg.d.mts → tracing-Dro5eH6j.d.mts} +1 -0
  207. package/dist/{transactionContext-PNdoyLLm.mjs → transactionContext-dAfBVUrk.mjs} +1 -0
  208. package/dist/{typeGuards-C9KXUly6.mjs → typeGuards-B0ryPo3I.mjs} +1 -0
  209. package/dist/types/index.d.mts +6 -5
  210. package/dist/types/index.mjs +1 -0
  211. package/dist/types/storage.d.mts +2 -1
  212. package/dist/types/storage.mjs +1 -0
  213. package/dist/{types-Dmw-6Qeo.d.mts → types-B7XeLEgK.d.mts} +127 -90
  214. package/dist/{types-Cc91nXuA.d.mts → types-ByHn9rEO.d.mts} +1 -0
  215. package/dist/{types-C_ZZRcD6.d.mts → types-C4QE8qnm.d.mts} +1 -0
  216. package/dist/{types-Cu6vVJmh.d.mts → types-CBgvkp8O.d.mts} +82 -12
  217. package/dist/{types-DjC-KUCz.d.mts → types-ChuShpCP.d.mts} +1 -0
  218. package/dist/{types-QFGc3Cjv.d.mts → types-CwcUQ610.d.mts} +2 -6
  219. package/dist/{types-CSyCxl2V.mjs → types-Cys0ko9Z.mjs} +4 -3
  220. package/dist/usage/index.d.mts +3 -2
  221. package/dist/usage/index.mjs +0 -0
  222. package/dist/{userHelpers-Cg_y3fBz.mjs → userHelpers-ChYJ6CdK.mjs} +1 -0
  223. package/dist/utils/index.d.mts +16 -10
  224. package/dist/utils/index.mjs +10 -9
  225. package/dist/{utils-taUVD4p3.mjs → utils-vL8BrDE2.mjs} +3 -2
  226. package/dist/{validate-Bk44F2yT.mjs → validate-_KbifpHF.mjs} +2 -1
  227. package/dist/{versioning-gKWyryT3.mjs → versioning-CHDTor3P.mjs} +3 -2
  228. package/dist/{versioning-DXgY5BUm.d.mts → versioning-D_rhHfZm.d.mts} +5 -2
  229. package/dist/{websocket-_Pd0CgR0.d.mts → websocket-BOXVggMf.d.mts} +2 -1
  230. package/package.json +15 -7
  231. package/skills/arc/SKILL.md +22 -8
  232. package/skills/arc/references/api-reference.md +4 -0
  233. package/skills/arc/references/auth.md +3 -0
  234. package/skills/arc/references/integrations.md +33 -0
  235. package/skills/arc/references/mcp.md +6 -7
  236. package/skills/arc/references/production.md +24 -25
  237. package/skills/arc-code-review/references/anti-patterns.md +3 -3
  238. package/dist/index-CZY4EGga.d.mts +0 -107
  239. package/dist/module-_-M7C5ES.mjs +0 -29
@@ -0,0 +1,266 @@
1
+ /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
+ import { arcLog } from "./logger/index.mjs";
3
+ import { t as ArcError } from "./errors-Cj42AntO.mjs";
4
+ //#region src/permissions/filter-merge.ts
5
+ /**
6
+ * Policy-filter composition — logical AND, never last-writer-wins.
7
+ *
8
+ * Row-level policy filters can arrive from several INDEPENDENT sources for one
9
+ * request: a tenant preset, an `ownedByUser` grant, an `allOf(...)` branch, a
10
+ * host permission check. Every one of them is a RESTRICTION the row must
11
+ * satisfy, so composing them is logical AND.
12
+ *
13
+ * The historical `{ ...base, ...incoming }` shallow spread did NOT implement AND:
14
+ * when two sources constrained the SAME key with different values, the later one
15
+ * silently REPLACED the earlier one — widening (or erasing) a restriction another
16
+ * layer deliberately imposed. That is a defense-in-depth defect, not a
17
+ * refinement. "Later can refine" is only sound when the refinement is provably
18
+ * narrower, and a bare overwrite proves nothing.
19
+ *
20
+ * {@link conjoinPolicyFilters} composes with AND semantics while preserving the
21
+ * common case byte-for-byte:
22
+ *
23
+ * - key present on only one side → carried through flat. Non-overlapping
24
+ * filters (the ~99% case) produce exactly the same object the old spread did,
25
+ * so there is ZERO behavior change for them.
26
+ * - same key, deep-equal value → kept once (idempotent — e.g. two checks
27
+ * both pinning the same `organizationId`).
28
+ * - same key, DIFFERENT value → BOTH constraints are preserved under an
29
+ * `$and`, so a row must satisfy both. For flat equality that conjunction is
30
+ * unsatisfiable, so the query returns nothing — the safe, correct outcome for
31
+ * contradictory policies (deny), and the earlier restriction is never dropped.
32
+ *
33
+ * Adapter safety: mongokit / sqlitekit compile `$and` natively at the DB layer,
34
+ * and arc's in-memory `simpleEqualityMatcher` (AccessControl.checkPolicyFilters)
35
+ * already fail-closes on operator-shaped filters. So a produced `$and` is either
36
+ * evaluated correctly by the DB or rejected fail-closed in memory — both safe.
37
+ *
38
+ * This is the pragmatic, adapter-neutral form of the AND semantics. A canonical
39
+ * filter IR in `repo-core` (nested and/or/not nodes each adapter compiles) is the
40
+ * fuller design, but this closes the security defect without one.
41
+ */
42
+ /**
43
+ * Validate + return a `$and` operand's fragment array. A security-policy
44
+ * normalizer must NEVER silently drop a malformed constraint — a non-array
45
+ * `$and` (e.g. `{ $and: { organizationId: "a" } }`) is a policy bug, so fail
46
+ * loud (fail-closed) rather than discard the restriction it was meant to carry.
47
+ */
48
+ function coercePolicyAnd(value) {
49
+ if (!Array.isArray(value)) throw new Error(`conjoinPolicyFilters: malformed '$and' — expected an array of filter fragments, got ${value === null ? "null" : typeof value}. A policy filter constraint must not be silently dropped.`);
50
+ return value;
51
+ }
52
+ /** Are two flat policy-filter values equivalent for conjunction purposes? */
53
+ function filterValueEqual(a, b) {
54
+ if (Object.is(a, b)) return true;
55
+ if (a !== null && b !== null && typeof a === "object" && typeof b === "object") try {
56
+ return JSON.stringify(a) === JSON.stringify(b);
57
+ } catch {
58
+ return false;
59
+ }
60
+ return false;
61
+ }
62
+ /**
63
+ * Conjoin two policy-filter maps with AND semantics. Never silently overwrites a
64
+ * same-key constraint with a different value — conflicting keys are preserved
65
+ * under `$and`. See the module doc for the full contract.
66
+ */
67
+ function conjoinPolicyFilters(base, incoming) {
68
+ const baseEmpty = !base || Object.keys(base).length === 0;
69
+ const incomingEmpty = !incoming || Object.keys(incoming).length === 0;
70
+ if (baseEmpty) return incomingEmpty ? {} : { ...incoming };
71
+ if (incomingEmpty) return { ...base };
72
+ const result = {};
73
+ const andParts = [];
74
+ const baseAnd = base.$and;
75
+ if (baseAnd !== void 0) andParts.push(...coercePolicyAnd(baseAnd));
76
+ for (const [key, value] of Object.entries(base)) {
77
+ if (key === "$and") continue;
78
+ result[key] = value;
79
+ }
80
+ for (const [key, value] of Object.entries(incoming)) {
81
+ if (key === "$and") {
82
+ andParts.push(...coercePolicyAnd(value));
83
+ continue;
84
+ }
85
+ if (!(key in result)) {
86
+ result[key] = value;
87
+ continue;
88
+ }
89
+ if (filterValueEqual(result[key], value)) continue;
90
+ andParts.push({ [key]: result[key] }, { [key]: value });
91
+ delete result[key];
92
+ }
93
+ if (andParts.length > 0) result.$and = andParts;
94
+ return result;
95
+ }
96
+ //#endregion
97
+ //#region src/permissions/authorizationDecision.ts
98
+ const log = arcLog("permissions:enforce");
99
+ /**
100
+ * Normalize a check return into the canonical {@link AuthorizationDecision}.
101
+ * A boolean promotes to `{ effect: "allow" | "deny" }`; a decision passes
102
+ * through. This is the ONE place booleans are promoted, so the rest of the
103
+ * pipeline only ever handles decisions.
104
+ */
105
+ function normalizeToDecision(result) {
106
+ if (typeof result === "boolean") return { effect: result ? "allow" : "deny" };
107
+ /**
108
+ * A returned object MUST carry an `effect`. Without this guard a foreign shape — the
109
+ * pre-2.30 `{ granted: true }`, a hand-rolled `{ allowed: true }`, a stray Promise
110
+ * someone forgot to await — passed through as a decision with no effect and was read
111
+ * as DENY. A gate that says yes and is silently overruled is the worst available
112
+ * failure: nine `@classytic/arc-*` test suites went red at once and every symptom
113
+ * pointed at authentication rather than at the return shape.
114
+ *
115
+ * Throwing lands in `failed` (fail-closed, still a denial), so behaviour is unchanged
116
+ * for anything already correct — but the reason now names itself instead of hiding.
117
+ */
118
+ const effect = result?.effect;
119
+ if (result === null || typeof result !== "object" || effect !== "allow" && effect !== "deny") throw new Error(`[arc] a permission check returned an unrecognized shape: ${JSON.stringify(result)}. Return a boolean or an AuthorizationDecision ({ effect: 'allow' | 'deny', ... }). The pre-2.30 { granted } shape is no longer accepted — it normalized to a silent deny.`);
120
+ return result;
121
+ }
122
+ /**
123
+ * Run a permission check once and classify the result. The single source of the
124
+ * try/normalize/catch sequence — see {@link PermissionOutcome}. Non-`ArcError`
125
+ * throws are logged once here through arc's namespaced logger (a deliberate
126
+ * `ArcError` denial is expected control-flow, not a warning). Pure w.r.t. the
127
+ * request — neither reads a reply nor mutates the request.
128
+ */
129
+ async function evaluatePermissionOutcome(check, context) {
130
+ try {
131
+ return {
132
+ status: "decided",
133
+ decision: normalizeToDecision(await check(context))
134
+ };
135
+ } catch (err) {
136
+ if (err instanceof ArcError) return {
137
+ status: "structured",
138
+ error: err
139
+ };
140
+ log.warn({
141
+ err,
142
+ resource: context.resource,
143
+ action: context.action
144
+ }, "Permission check threw — denying (fail-closed)");
145
+ return {
146
+ status: "failed",
147
+ error: err
148
+ };
149
+ }
150
+ }
151
+ /**
152
+ * Run a permission check and return a canonical {@link AuthorizationDecision} —
153
+ * the transport-neutral PDP (HTTP, aggregation, MCP, and any future transport).
154
+ * A thin mapper over {@link evaluatePermissionOutcome}:
155
+ *
156
+ * - a structured `ArcError` is RE-THROWN so the transport surfaces it verbatim
157
+ * (e.g. a tier gate throwing `arc.tier_required` with machine-readable meta);
158
+ * - any OTHER throw is fail-closed to a `deny` decision (a broken check must
159
+ * never fall open to a 500 that skips authorization).
160
+ *
161
+ * Pure w.r.t. the request — it neither reads a reply nor mutates the request.
162
+ * Callers translate the returned decision into their own response mechanism and
163
+ * apply side-effects via {@link applyAuthorizationDecision}. HTTP additionally
164
+ * hardens a *thrown* check to 403-even-when-anonymous — that transport-specific
165
+ * nuance lives in {@link evaluateAndApplyPermission}, not here.
166
+ */
167
+ async function evaluatePermissionDecision(check, context) {
168
+ const outcome = await evaluatePermissionOutcome(check, context);
169
+ switch (outcome.status) {
170
+ case "decided": return outcome.decision;
171
+ case "structured": throw outcome.error;
172
+ case "failed": return { effect: "deny" };
173
+ }
174
+ }
175
+ /**
176
+ * Apply an allowed {@link AuthorizationDecision} to a Fastify request — conjoins
177
+ * the decision's row-level `policy` into `_policyFilters` and conditionally
178
+ * installs the `scope`.
179
+ *
180
+ * **Scope install rule:** only writes `scope` when the current request scope
181
+ * is absent or `public`. This prevents downgrading an already-authenticated
182
+ * request (e.g. Better Auth set `member`, then a permission check returns a
183
+ * narrower `service` scope — the original `member` wins because it came from
184
+ * a more authoritative source).
185
+ *
186
+ * Safe to call with a denied decision — it simply no-ops. Callers should still
187
+ * check `decision.effect` and send an error response before reaching here, but
188
+ * this function tolerates the misuse defensively.
189
+ *
190
+ * This is the enforcement point (PEP) — the ONE place scope + data policy are
191
+ * installed (and the obligation seam lives).
192
+ */
193
+ function applyAuthorizationDecision(decision, request) {
194
+ if (decision.effect !== "allow") return;
195
+ if (decision.policy) request._policyFilters = conjoinPolicyFilters(request._policyFilters, decision.policy);
196
+ if (decision.scope) {
197
+ const current = request.scope;
198
+ if (!current || current.kind === "public") request.scope = decision.scope;
199
+ }
200
+ }
201
+ /**
202
+ * Max length of a decision `reason` string before we fall back to the
203
+ * generic default message. Upstream checks can return arbitrary strings; we
204
+ * clamp to prevent accidental leakage of internal diagnostics or oversized
205
+ * payloads via the 4xx response body.
206
+ */
207
+ const MAX_DENIAL_REASON_LENGTH = 100;
208
+ /**
209
+ * End-to-end HTTP PEP: evaluates the check through the shared
210
+ * {@link evaluatePermissionOutcome} core, sends a 401/403 response on denial,
211
+ * and applies side-effects on grant. Returns `true` if the caller should
212
+ * continue, `false` if a response has been sent and the caller should return.
213
+ *
214
+ * The HTTP specialization of the ONE evaluation core — it does NOT re-run or
215
+ * re-normalize the check; it only maps the classified outcome onto Fastify:
216
+ *
217
+ * - `structured` (thrown `ArcError`) → surface verbatim, byte-compatible with
218
+ * the global error handler (`code`/`message`/`status` + `meta`);
219
+ * - `failed` (other throw) → 403 EVEN WHEN ANONYMOUS (a broken check is a hard
220
+ * denial, not a "please authenticate");
221
+ * - `decided` → allow, or a returned deny → 401 (no user) / 403 (user) with a
222
+ * clamped `reason`.
223
+ *
224
+ * Context construction, pre-check auth gating, and success-path handler
225
+ * invocation stay at the callsite — those are genuinely different per router
226
+ * and don't belong here.
227
+ *
228
+ * @returns `true` if authorized (caller continues), `false` if a response was sent
229
+ */
230
+ async function evaluateAndApplyPermission(check, context, request, reply, opts) {
231
+ const outcome = await evaluatePermissionOutcome(check, context);
232
+ if (outcome.status === "structured") {
233
+ const err = outcome.error;
234
+ reply.code(err.status).send({
235
+ code: err.code,
236
+ message: err.message,
237
+ status: err.status,
238
+ ...err.meta ? { meta: err.meta } : {}
239
+ });
240
+ return false;
241
+ }
242
+ if (outcome.status === "failed") {
243
+ reply.code(403).send({
244
+ code: "arc.forbidden",
245
+ message: "Permission denied",
246
+ status: 403
247
+ });
248
+ return false;
249
+ }
250
+ const { decision } = outcome;
251
+ if (decision.effect !== "allow") {
252
+ const defaultMsg = opts?.defaultDenialMessage?.(context.user) ?? (context.user ? "Permission denied" : "Authentication required");
253
+ const reason = decision.reason && decision.reason.length <= MAX_DENIAL_REASON_LENGTH ? decision.reason : defaultMsg;
254
+ const status = context.user ? 403 : 401;
255
+ reply.code(status).send({
256
+ code: context.user ? "arc.forbidden" : "arc.unauthorized",
257
+ message: reason,
258
+ status
259
+ });
260
+ return false;
261
+ }
262
+ applyAuthorizationDecision(decision, request);
263
+ return true;
264
+ }
265
+ //#endregion
266
+ export { conjoinPolicyFilters as a, normalizeToDecision as i, evaluateAndApplyPermission as n, evaluatePermissionDecision as r, applyAuthorizationDecision as t };
@@ -1,4 +1,7 @@
1
- import { i as compileAggRequest, t as adapterSupportsAggregate } from "./validate-Bk44F2yT.mjs";
1
+ /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
+ import { a as conjoinPolicyFilters } from "./authorizationDecision-ChvUQGG1.mjs";
3
+ import { t as toRepositoryFilter } from "./repositoryFilter-f9eAfq_l.mjs";
4
+ import { i as compileAggRequest, t as adapterSupportsAggregate } from "./validate-_KbifpHF.mjs";
2
5
  //#region src/core/aggregation/buildHandler.ts
3
6
  /**
4
7
  * Framework-agnostic aggregation execution. Runs safety guards,
@@ -18,13 +21,13 @@ async function executeAggregation(normalized, deps, ctx) {
18
21
  const { repo } = deps;
19
22
  const config = normalized.base;
20
23
  const aggregationName = normalized.name;
21
- const { query, tenantOptions } = ctx;
24
+ const { query, tenantOptions, policyFilter } = ctx;
22
25
  const guardError = checkRequestGuards(query, config);
23
26
  if (guardError) return {
24
27
  status: 400,
25
28
  body: guardError
26
29
  };
27
- const aggReq = compileAggRequest(normalized, extractCallerFilter(query), tenantOptions, query);
30
+ const aggReq = compileAggRequest(normalized, conjoinPolicyFilters(extractCallerFilter(query), policyFilter), tenantOptions, query);
28
31
  if (config.materialized) {
29
32
  const matCtx = {
30
33
  filter: aggReq.filter,
@@ -51,9 +54,13 @@ async function executeAggregation(normalized, deps, ctx) {
51
54
  }
52
55
  }
53
56
  };
57
+ const aggReqForRepo = aggReq.filter && typeof aggReq.filter === "object" ? {
58
+ ...aggReq,
59
+ filter: toRepositoryFilter(aggReq.filter)
60
+ } : aggReq;
54
61
  let result;
55
62
  try {
56
- result = await repo.aggregate(aggReq, tenantOptions);
63
+ result = await repo.aggregate(aggReqForRepo, tenantOptions);
57
64
  } catch (err) {
58
65
  return mapAggregateError(err, aggregationName);
59
66
  }
@@ -95,9 +102,13 @@ async function executeAggregation(normalized, deps, ctx) {
95
102
  function buildAggregationHandler(normalized, deps) {
96
103
  const { buildOptions } = deps;
97
104
  return async (request, reply) => {
105
+ const query = request.query ?? {};
106
+ const tenantOptions = buildOptions(request);
107
+ const policyFilter = request._policyFilters;
98
108
  const result = await executeAggregation(normalized, deps, {
99
- query: request.query ?? {},
100
- tenantOptions: buildOptions(request)
109
+ query,
110
+ tenantOptions,
111
+ policyFilter
101
112
  });
102
113
  reply.status(result.status);
103
114
  if (result.headers) for (const [k, v] of Object.entries(result.headers)) reply.header(k, v);
@@ -199,6 +210,20 @@ const SHORTHAND_RANGE_OPS = /* @__PURE__ */ new Set([
199
210
  "lt",
200
211
  "lte"
201
212
  ]);
213
+ /**
214
+ * Operators whose operand MUST be a list. A URL carries `priority[in]=high,urgent`
215
+ * as ONE string, and `$in` against a non-array is invalid — MongoDB rejects it,
216
+ * and the portable Filter IR would spread the string into characters. Split it
217
+ * the same way `ArcQueryParser` does for the CRUD list route, which is the
218
+ * contract this expansion claims to match.
219
+ */
220
+ const SHORTHAND_LIST_OPS = /* @__PURE__ */ new Set(["in", "nin"]);
221
+ /** Normalize a list-operator operand to an array (URL string → split on commas). */
222
+ function toOperandList(value) {
223
+ if (Array.isArray(value)) return value;
224
+ if (typeof value === "string") return value.split(",").map((v) => v.trim()).filter((v) => v.length > 0);
225
+ return [value];
226
+ }
202
227
  const ISO_DATE_RE = /^\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?)?$/;
203
228
  function tryCoerceDate(v) {
204
229
  if (typeof v !== "string" || !ISO_DATE_RE.test(v)) return v;
@@ -222,7 +247,9 @@ function expandShorthandOperators(value) {
222
247
  for (const [op, opVal] of Object.entries(nested)) {
223
248
  const mongoOp = OPERATOR_SHORTHAND[op];
224
249
  if (!mongoOp) continue;
225
- expanded[mongoOp] = SHORTHAND_RANGE_OPS.has(op) ? tryCoerceDate(opVal) : opVal;
250
+ if (SHORTHAND_RANGE_OPS.has(op)) expanded[mongoOp] = tryCoerceDate(opVal);
251
+ else if (SHORTHAND_LIST_OPS.has(op)) expanded[mongoOp] = toOperandList(opVal);
252
+ else expanded[mongoOp] = opVal;
226
253
  }
227
254
  return expanded;
228
255
  }
@@ -1,6 +1,7 @@
1
- import { n as CacheStats, r as CacheStore, t as CacheLogger } from "../interface-BGZCzOGL.mjs";
2
- import { a as QueryCacheConfig, i as QueryCache, n as CacheResult, r as CacheStatus, t as CacheEnvelope } from "../QueryCache-DOMT_iq7.mjs";
3
- import { i as queryCachePlugin, n as QueryCacheDefaults, r as QueryCachePluginOptions, t as CrossResourceRule } from "../queryCachePlugin-br4otiqF.mjs";
1
+
2
+ import { n as CacheStats, r as CacheStore, t as CacheLogger } from "../interface-BOk3YnTz.mjs";
3
+ import { a as QueryCacheConfig, i as QueryCache, n as CacheResult, r as CacheStatus, t as CacheEnvelope } from "../QueryCache-DFA-QrU9.mjs";
4
+ import { i as queryCachePlugin, n as QueryCacheDefaults, r as QueryCachePluginOptions, t as CrossResourceRule } from "../queryCachePlugin-BzqxconG.mjs";
4
5
  //#region src/cache/keys.d.ts
5
6
  /**
6
7
  * Cache Key Utilities
@@ -1,6 +1,7 @@
1
- import { i as versionKey, n as hashParams, r as tagVersionKey, t as buildQueryKey } from "../keys-Cd316u_y.mjs";
2
- import { t as MemoryCacheStore } from "../memory-CmnzXE5Z.mjs";
3
- import { r as QueryCache, t as queryCachePlugin } from "../queryCachePlugin-DSGuSVLW.mjs";
1
+ /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
+ import { i as versionKey, n as hashParams, r as tagVersionKey, t as buildQueryKey } from "../keys-C0_pa1tY.mjs";
3
+ import { t as MemoryCacheStore } from "../memory-DR6wpa9F.mjs";
4
+ import { r as QueryCache, t as queryCachePlugin } from "../queryCachePlugin-BZr8v46E.mjs";
4
5
  //#region src/cache/redis.ts
5
6
  /**
6
7
  * Redis-backed cache store.
@@ -1,4 +1,5 @@
1
- import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
1
+ /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
+ import { t as __exportAll } from "./rolldown-runtime-CUsjNX9R.mjs";
2
3
  import fp from "fastify-plugin";
3
4
  //#region src/plugins/caching.ts
4
5
  var caching_exports = /* @__PURE__ */ __exportAll({
@@ -1,6 +1,7 @@
1
- import { L as RequestWithExtras } from "../index-DPRH0Cme.mjs";
2
- import { A as CleanupWriteFence, C as CleanupResult, D as CleanupRunStore, E as CleanupRunStatus, F as PurgeStrategyKind, I as PurgeVerificationSummary, L as VerificationCheck, M as PurgeActor, N as PurgeEvidence, O as CleanupRunTransitionPatch, P as PurgeResourceResult, R as VerificationResult, S as CleanupRecipe, T as CleanupRunCreateResult, _ as CleanupPermissions, a as CleanupEvidenceStore, b as CleanupPlanItem, c as CleanupInput, d as CleanupLease, f as CleanupLimits, g as CleanupPermissionCheck, h as CleanupOutcomeStatus, i as CleanupContext, j as DEFAULT_CLEANUP_LIMITS, k as CleanupStepResult, l as CleanupJob, m as CleanupManifest, n as CLEANUP_TERMINAL_STATUSES, o as CleanupExecutionContext, p as CleanupLogger, r as CleanupCancelRequest, s as CleanupFinalizationPayload, t as Availability, u as CleanupJobQueue, v as CleanupPlan, w as CleanupRun, x as CleanupProgressSummary, y as CleanupPlanDraft } from "../types-C_ZZRcD6.mjs";
3
- import { t as ArcModule } from "../types-Cu6vVJmh.mjs";
1
+
2
+ import { L as RequestWithExtras } from "../index-CpzxqePp.mjs";
3
+ import { A as CleanupWriteFence, C as CleanupResult, D as CleanupRunStore, E as CleanupRunStatus, F as PurgeStrategyKind, I as PurgeVerificationSummary, L as VerificationCheck, M as PurgeActor, N as PurgeEvidence, O as CleanupRunTransitionPatch, P as PurgeResourceResult, R as VerificationResult, S as CleanupRecipe, T as CleanupRunCreateResult, _ as CleanupPermissions, a as CleanupEvidenceStore, b as CleanupPlanItem, c as CleanupInput, d as CleanupLease, f as CleanupLimits, g as CleanupPermissionCheck, h as CleanupOutcomeStatus, i as CleanupContext, j as DEFAULT_CLEANUP_LIMITS, k as CleanupStepResult, l as CleanupJob, m as CleanupManifest, n as CLEANUP_TERMINAL_STATUSES, o as CleanupExecutionContext, p as CleanupLogger, r as CleanupCancelRequest, s as CleanupFinalizationPayload, t as Availability, u as CleanupJobQueue, v as CleanupPlan, w as CleanupRun, x as CleanupProgressSummary, y as CleanupPlanDraft } from "../types-C4QE8qnm.mjs";
4
+ import { t as ArcModule } from "../types-CBgvkp8O.mjs";
4
5
  import { PurgeStrategyKind as PurgeStrategyKind$1 } from "@classytic/primitives/retention";
5
6
  import { canonicalJson } from "@classytic/primitives/canonical";
6
7
  import { CleanupStep } from "@classytic/repo-core/cleanup";
@@ -1,6 +1,7 @@
1
- import { g as getUserId } from "../types-CSyCxl2V.mjs";
2
- import { t as defineResource } from "../defineResource-2zvVVpxg.mjs";
3
- import { t as defineModule } from "../module-_-M7C5ES.mjs";
1
+ /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
+ import { g as getUserId } from "../types-Cys0ko9Z.mjs";
3
+ import { t as defineResource } from "../defineResource-Bv6EtN1x.mjs";
4
+ import { t as defineModule } from "../module-0pFJA6YW.mjs";
4
5
  import { createPurgeEvidence } from "@classytic/primitives/retention";
5
6
  import { canonicalJson, sha256Hex } from "@classytic/primitives/canonical";
6
7
  //#region src/cleanup/errors.ts
@@ -1175,8 +1176,7 @@ function createDataCleanupModule(deps) {
1175
1176
  path: "/recipes",
1176
1177
  summary: "List available cleanup recipes",
1177
1178
  permissions: view,
1178
- raw: true,
1179
- handler: async (_req, reply) => {
1179
+ rawHandler: async (_req, reply) => {
1180
1180
  return reply.send({ recipes: registry.introspect() });
1181
1181
  }
1182
1182
  },
@@ -1185,9 +1185,8 @@ function createDataCleanupModule(deps) {
1185
1185
  path: "/preview",
1186
1186
  summary: "Preview a cleanup plan (no mutation)",
1187
1187
  permissions: view,
1188
- raw: true,
1189
1188
  schema: { body: previewBodySchema },
1190
- handler: async (req, reply) => {
1189
+ rawHandler: async (req, reply) => {
1191
1190
  const r = req;
1192
1191
  const body = req.body;
1193
1192
  const plan = await service.preview({
@@ -1204,9 +1203,8 @@ function createDataCleanupModule(deps) {
1204
1203
  path: "/runs",
1205
1204
  summary: "Execute a confirmed cleanup plan",
1206
1205
  permissions: execute,
1207
- raw: true,
1208
1206
  schema: { body: runsBodySchema },
1209
- handler: async (req, reply) => {
1207
+ rawHandler: async (req, reply) => {
1210
1208
  const r = req;
1211
1209
  const body = req.body;
1212
1210
  const run = await service.execute({
@@ -1226,9 +1224,8 @@ function createDataCleanupModule(deps) {
1226
1224
  path: "/runs/:id",
1227
1225
  summary: "Observe a cleanup run",
1228
1226
  permissions: view,
1229
- raw: true,
1230
1227
  schema: { params: runIdParamsSchema },
1231
- handler: async (req, reply) => {
1228
+ rawHandler: async (req, reply) => {
1232
1229
  const { id } = req.params;
1233
1230
  return reply.send(await service.getRun(id));
1234
1231
  }
@@ -1238,12 +1235,11 @@ function createDataCleanupModule(deps) {
1238
1235
  path: "/runs/:id/action",
1239
1236
  summary: "Cancel or retry a cleanup run",
1240
1237
  permissions: manage,
1241
- raw: true,
1242
1238
  schema: {
1243
1239
  params: runIdParamsSchema,
1244
1240
  body: actionBodySchema
1245
1241
  },
1246
- handler: async (req, reply) => {
1242
+ rawHandler: async (req, reply) => {
1247
1243
  const actionActor = resolveActor(req);
1248
1244
  const { id } = req.params;
1249
1245
  const { action, reason } = req.body;
@@ -1,4 +1,5 @@
1
- import { Nt as RateLimitConfig, V as ResourceDefinition, et as RouteSchemaOptions } from "../../index-DPRH0Cme.mjs";
1
+
2
+ import { Nt as RateLimitConfig, V as ResourceDefinition, et as RouteSchemaOptions } from "../../index-CpzxqePp.mjs";
2
3
  //#region src/cli/commands/describe.d.ts
3
4
  interface DescribedResource {
4
5
  name: string;
@@ -1,5 +1,6 @@
1
- import { t as CRUD_OPERATIONS } from "../../constants-DNre0wRg.mjs";
2
- import { n as stringifyMeasureMap } from "../../ResourceRegistry-y9Hnypus.mjs";
1
+ /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
+ import { t as CRUD_OPERATIONS } from "../../constants-D3Dv4LAV.mjs";
3
+ import { n as stringifyMeasureMap } from "../../ResourceRegistry-qq0mn2s9.mjs";
3
4
  import { resolve } from "node:path";
4
5
  import { pathToFileURL } from "node:url";
5
6
  //#region src/cli/commands/describe.ts
@@ -1,3 +1,4 @@
1
+
1
2
  //#region src/cli/commands/docs.d.ts
2
3
  /**
3
4
  * Arc CLI - Docs Command
@@ -1,5 +1,6 @@
1
- import { t as buildOpenApiSpec } from "../../openapi-BLV4OMXb.mjs";
2
- import { t as loadResourcesFromEntry } from "../../loadResourcesFromEntry-kvGT6EcO.mjs";
1
+ /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
+ import { t as buildOpenApiSpec } from "../../openapi-B2L4js1v.mjs";
3
+ import { t as loadResourcesFromEntry } from "../../loadResourcesFromEntry-BAjYZonx.mjs";
3
4
  import { dirname, resolve } from "node:path";
4
5
  import { mkdirSync, writeFileSync } from "node:fs";
5
6
  //#region src/cli/commands/docs.ts
@@ -1,3 +1,4 @@
1
+
1
2
  //#region src/cli/commands/doctor.d.ts
2
3
  /**
3
4
  * Arc CLI - Doctor Command
@@ -1,3 +1,4 @@
1
+ /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
1
2
  import { dirname, join, parse, resolve } from "node:path";
2
3
  import { existsSync, readFileSync } from "node:fs";
3
4
  //#region src/cli/commands/doctor.ts
@@ -1,2 +1,3 @@
1
- import { n as generate, t as ArcProjectConfig } from "../../generate-BnsL9GBm.mjs";
1
+
2
+ import { n as generate, t as ArcProjectConfig } from "../../generate-DCGuEbqI.mjs";
2
3
  export { type ArcProjectConfig, generate };
@@ -1,2 +1,3 @@
1
- import { t as generate } from "../../generate-D0wZupBg.mjs";
1
+ /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
+ import { t as generate } from "../../generate-EcA6ui4i.mjs";
2
3
  export { generate };
@@ -1,2 +1,3 @@
1
- import { a as ProjectConfig, i as PackageManager, n as DependencyManifest, r as InitOptions, t as init } from "../../init-BPEu8cs-.mjs";
1
+
2
+ import { a as ProjectConfig, i as PackageManager, n as DependencyManifest, r as InitOptions, t as init } from "../../init-Cscs4lab.mjs";
2
3
  export { type DependencyManifest, type InitOptions, type PackageManager, type ProjectConfig, init };
@@ -1,2 +1,3 @@
1
- import { t as init } from "../../init-tlRSt667.mjs";
1
+ /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
+ import { t as init } from "../../init-BEiNZBsJ.mjs";
2
3
  export { init };
@@ -1,3 +1,4 @@
1
+
1
2
  //#region src/cli/commands/introspect.d.ts
2
3
  /**
3
4
  * Arc CLI - Introspect Command
@@ -1,4 +1,5 @@
1
- import { t as loadResourcesFromEntry } from "../../loadResourcesFromEntry-kvGT6EcO.mjs";
1
+ /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
+ import { t as loadResourcesFromEntry } from "../../loadResourcesFromEntry-BAjYZonx.mjs";
2
3
  //#region src/cli/commands/introspect.ts
3
4
  function describePermission(value) {
4
5
  if (!value) return "none";
@@ -1,7 +1,8 @@
1
+
1
2
  import { describe } from "./commands/describe.mjs";
2
3
  import { exportDocs } from "./commands/docs.mjs";
3
4
  import { doctor } from "./commands/doctor.mjs";
4
- import { n as generate } from "../generate-BnsL9GBm.mjs";
5
- import { t as init } from "../init-BPEu8cs-.mjs";
5
+ import { n as generate } from "../generate-DCGuEbqI.mjs";
6
+ import { t as init } from "../init-Cscs4lab.mjs";
6
7
  import { introspect } from "./commands/introspect.mjs";
7
8
  export { describe, doctor, exportDocs, generate, init, introspect };
@@ -1,7 +1,8 @@
1
+ /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
1
2
  import { describe } from "./commands/describe.mjs";
2
3
  import { exportDocs } from "./commands/docs.mjs";
3
4
  import { doctor } from "./commands/doctor.mjs";
4
- import { t as generate } from "../generate-D0wZupBg.mjs";
5
- import { t as init } from "../init-tlRSt667.mjs";
5
+ import { t as generate } from "../generate-EcA6ui4i.mjs";
6
+ import { t as init } from "../init-BEiNZBsJ.mjs";
6
7
  import { introspect } from "./commands/introspect.mjs";
7
8
  export { describe, doctor, exportDocs, generate, init, introspect };
@@ -1,3 +1,4 @@
1
+ /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
1
2
  //#region src/constants.ts
2
3
  /**
3
4
  * Arc Framework Constants — Single Source of Truth
@@ -1,3 +1,4 @@
1
+
1
2
  import { AsyncLocalStorage } from "node:async_hooks";
2
3
  //#region src/context/requestContext.d.ts
3
4
  /**
@@ -1,3 +1,4 @@
1
- import { n as requestContext, t as getTraceHeaders } from "../requestContext-MrlJwECf.mjs";
2
- import { t as transactionContext } from "../transactionContext-PNdoyLLm.mjs";
1
+ /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
+ import { n as requestContext, t as getTraceHeaders } from "../requestContext-2TxXOJ7T.mjs";
3
+ import { t as transactionContext } from "../transactionContext-dAfBVUrk.mjs";
3
4
  export { getTraceHeaders, requestContext, transactionContext };
@@ -1,3 +1,4 @@
1
- import { $t as SlugExt, An as ControllerConfigurableOptions, B as defineResource, Jt as BaseController, Mn as ListResult, Nn as BodySanitizer, Pn as BodySanitizerConfig, Qt as TreeMixin, V as ResourceDefinition, Xt as SoftDeleteMixin, Yt as SoftDeleteExt, Zt as TreeExt, an as QueryResolverConfig, ct as AggMeasureShorthand, dt as AggregationDateRangeRequirement, en as SlugMixin, ft as AggregationIndexHint, gt as AggregationsMap, ht as AggregationRateLimit, in as QueryResolver, jn as ControllerConstructionOptions, kn as BaseControllerOptions, lt as AggregationCacheConfig, mt as AggregationMaterializedResult, nn as BulkMixin, on as AccessControl, pt as AggregationMaterializedContext, rn as BaseCrudController, sn as AccessControlConfig, st as AggMeasureInput, tn as BulkExt, ut as AggregationConfig } from "../index-DPRH0Cme.mjs";
2
- import { A as DEFAULT_ID_FIELD, B as MAX_FILTER_DEPTH, C as DefineActionConfig, D as defineAggregation, E as createPermissionMiddleware, 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, T as createCrudRouter, U as MUTATION_OPERATIONS, V as MAX_REGEX_LENGTH, W as MutationOperation, _ as getEntityQuery, a as formatValidationErrors, b as ResourceSeams, c as isFieldReadable, d as createRequestContext, f as getControllerContext, g as getEntityIdField, h as getEntityId, i as assertValidConfig, j as DEFAULT_LIMIT, k as CrudOperation, l as createCrudHandlers, m as sendControllerResponse, n as ValidateOptions, o as validateResourceConfig, p as getControllerScope, r as ValidationResult, s as collectReadBlockedFields, t as ConfigError, u as createFastifyHandler, v as defineResourceVariants, w as defineAction, x as SeamedResourceConfig, y as AdapterLike, z as HookPhase } from "../index-CjVg-Epg.mjs";
1
+
2
+ import { $t as TreeMixin, An as BaseControllerOptions, B as defineResource, Fn as BodySanitizerConfig, Mn as ControllerConstructionOptions, Nn as ListResult, Pn as BodySanitizer, Qt as TreeExt, V as ResourceDefinition, Xt as SoftDeleteExt, Yt as BaseController, Zt as SoftDeleteMixin, an as QueryResolver, cn as AccessControlConfig, ct as AggMeasureShorthand, dt as AggregationDateRangeRequirement, en as SlugExt, ft as AggregationIndexHint, gt as AggregationsMap, ht as AggregationRateLimit, in as BaseCrudController, jn as ControllerConfigurableOptions, lt as AggregationCacheConfig, mt as AggregationMaterializedResult, nn as BulkExt, on as QueryResolverConfig, pt as AggregationMaterializedContext, rn as BulkMixin, sn as AccessControl, st as AggMeasureInput, tn as SlugMixin, ut as AggregationConfig } from "../index-CpzxqePp.mjs";
3
+ import { A as DEFAULT_ID_FIELD, B as MAX_FILTER_DEPTH, C as DefineActionConfig, D as defineAggregation, E as createPermissionMiddleware, 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, T as createCrudRouter, U as MUTATION_OPERATIONS, V as MAX_REGEX_LENGTH, W as MutationOperation, _ as getEntityQuery, a as formatValidationErrors, b as ResourceSeams, c as isFieldReadable, d as createRequestContext, f as getControllerContext, g as getEntityIdField, h as getEntityId, i as assertValidConfig, j as DEFAULT_LIMIT, k as CrudOperation, l as createCrudHandlers, m as sendControllerResponse, n as ValidateOptions, o as validateResourceConfig, p as getControllerScope, r as ValidationResult, s as collectReadBlockedFields, t as ConfigError, u as createFastifyHandler, v as defineResourceVariants, w as defineAction, x as SeamedResourceConfig, y as AdapterLike, z as HookPhase } from "../index-Bc2ox8_U.mjs";
3
4
  export { AccessControl, type AccessControlConfig, type AdapterLike, type AggMeasureInput, type AggMeasureShorthand, type AggregationCacheConfig, type AggregationConfig, type AggregationDateRangeRequirement, type AggregationIndexHint, type AggregationMaterializedContext, type AggregationMaterializedResult, type AggregationRateLimit, type AggregationsMap, BaseController, type BaseControllerOptions, BaseCrudController, BodySanitizer, type BodySanitizerConfig, type BulkExt, BulkMixin, CRUD_OPERATIONS, type ConfigError, type ControllerConfigurableOptions, type ControllerConstructionOptions, CrudOperation, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, type DefineActionConfig, HOOK_OPERATIONS, HOOK_PHASES, HookOperation, HookPhase, type ListResult, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, MutationOperation, QueryResolver, type QueryResolverConfig, RESERVED_QUERY_PARAMS, ResourceDefinition, type ResourceSeams, SYSTEM_FIELDS, type SeamedResourceConfig, type SlugExt, SlugMixin, type SoftDeleteExt, SoftDeleteMixin, type TreeExt, TreeMixin, type ValidateOptions, type ValidationResult, assertValidConfig, collectReadBlockedFields, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineAction, defineAggregation, defineResource, defineResourceVariants, formatValidationErrors, getControllerContext, getControllerScope, getEntityId, getEntityIdField, getEntityQuery, isFieldReadable, mergeResourceConfig, sendControllerResponse, validateResourceConfig };