@classytic/arc 2.31.0 → 2.32.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 (151) hide show
  1. package/dist/{BaseController-De7GqHck.mjs → BaseController-Dk34dxhI.mjs} +16 -13
  2. package/dist/{EventTransport-9mlTgqzE.mjs → EventTransport-BV10D0oG.mjs} +1 -1
  3. package/dist/{HookSystem-BcmPyq5I.mjs → HookSystem-vimw5D7Z.mjs} +2 -2
  4. package/dist/{ResourceRegistry-qq0mn2s9.mjs → ResourceRegistry-BVr7PgA0.mjs} +17 -15
  5. package/dist/{actionPermissions-BE5NwaQk.mjs → actionPermissions-Dti7ebyv.mjs} +1 -1
  6. package/dist/audit/index.mjs +2 -2
  7. package/dist/auth/audit.mjs +1 -1
  8. package/dist/auth/index.mjs +11 -10
  9. package/dist/auth/redis-session.mjs +1 -1
  10. package/dist/{authorizationDecision-ChvUQGG1.mjs → authorizationDecision-__T3EJDA.mjs} +2 -2
  11. package/dist/{buildHandler-CDrCJzmB.mjs → buildHandler-Dn7rzUJo.mjs} +6 -5
  12. package/dist/cache/index.mjs +4 -4
  13. package/dist/{caching-BFHA6Scf.mjs → caching-DFJqHyFs.mjs} +2 -2
  14. package/dist/cleanup/index.d.mts +36 -14
  15. package/dist/cleanup/index.mjs +45 -29
  16. package/dist/cli/commands/describe.mjs +4 -6
  17. package/dist/cli/commands/docs.mjs +3 -3
  18. package/dist/cli/commands/doctor.mjs +1 -1
  19. package/dist/cli/commands/generate.mjs +2 -2
  20. package/dist/cli/commands/init.mjs +2 -2
  21. package/dist/cli/commands/introspect.mjs +2 -2
  22. package/dist/cli/index.mjs +3 -3
  23. package/dist/{constants-D3Dv4LAV.mjs → constants-J99LGTJI.mjs} +1 -1
  24. package/dist/context/index.mjs +3 -3
  25. package/dist/core/index.d.mts +1 -1
  26. package/dist/core/index.mjs +7 -7
  27. package/dist/{core-BGpIxINN.mjs → core-BwwmNSp7.mjs} +3 -3
  28. package/dist/{createActionRouter-CDXEdasl.mjs → createActionRouter-DkJZWo0m.mjs} +14 -11
  29. package/dist/{createAggregationRouter-KrQDzx-k.mjs → createAggregationRouter-B1exOVD8.mjs} +10 -8
  30. package/dist/{createApp-Df89BEni.mjs → createApp-Bv0m-Q6_.mjs} +182 -61
  31. package/dist/{defineAggregation-DbPPS8RI.mjs → defineAggregation-gX4No1gt.mjs} +1 -1
  32. package/dist/{defineResource-Bv6EtN1x.mjs → defineResource-XFPPUu2c.mjs} +41 -32
  33. package/dist/discovery/index.mjs +1 -1
  34. package/dist/docs/index.mjs +3 -3
  35. package/dist/{elevation-D2l1mh4g.mjs → elevation-DNXXxgjl.mjs} +4 -4
  36. package/dist/encryption/index.mjs +5 -4
  37. package/dist/{errorHandler-C5NeD6bT.mjs → errorHandler-B2AZUJUj.mjs} +3 -3
  38. package/dist/{errors-Cj42AntO.mjs → errors-Bh1KK5ps.mjs} +1 -1
  39. package/dist/{eventPlugin-CkffEihm.mjs → eventPlugin-Dk_TyXeE.mjs} +8 -7
  40. package/dist/events/index.d.mts +108 -41
  41. package/dist/events/index.mjs +166 -142
  42. package/dist/events/transports/redis-stream-entry.mjs +14 -10
  43. package/dist/events/transports/redis.mjs +1 -1
  44. package/dist/factory/index.d.mts +5 -5
  45. package/dist/factory/index.mjs +131 -8
  46. package/dist/fastify-augmentation-BppG5bMT.d.mts +179 -0
  47. package/dist/{fields-CB5Cuzk9.mjs → fields-DEi65pGj.mjs} +6 -11
  48. package/dist/{generate-EcA6ui4i.mjs → generate-CRSG0jTv.mjs} +2 -2
  49. package/dist/{headers-3zvE0rM3.mjs → headers-BXjQYbeC.mjs} +2 -2
  50. package/dist/{health-DjZYjM7H.mjs → health-5XnTa2uo.mjs} +1 -1
  51. package/dist/hooks/index.mjs +2 -2
  52. package/dist/idempotency/index.mjs +8 -6
  53. package/dist/idempotency/redis.mjs +1 -1
  54. package/dist/{index-Bc2ox8_U.d.mts → index-DXlHwvuE.d.mts} +1 -1
  55. package/dist/{index-CFThn1K9.d.mts → index-ZWhLTp_s.d.mts} +70 -4
  56. package/dist/{index-CEJNZFtX.d.mts → index-zq6VrjaB.d.mts} +70 -1
  57. package/dist/index.d.mts +3 -3
  58. package/dist/index.mjs +11 -11
  59. package/dist/{init-BEiNZBsJ.mjs → init-BbfP8aky.mjs} +7 -5
  60. package/dist/integrations/event-gateway.mjs +2 -2
  61. package/dist/integrations/index.mjs +1 -1
  62. package/dist/integrations/jobs/index.mjs +3 -3
  63. package/dist/integrations/mcp/index.mjs +2 -2
  64. package/dist/integrations/mcp/testing.mjs +2 -2
  65. package/dist/integrations/streamline.mjs +3 -3
  66. package/dist/integrations/webhooks.mjs +1 -1
  67. package/dist/integrations/websocket-pushref-redis.mjs +1 -1
  68. package/dist/integrations/websocket-redis.mjs +1 -1
  69. package/dist/integrations/websocket.mjs +38 -35
  70. package/dist/{interface-DYzM0q-u.mjs → interface-BP4IJCBO.mjs} +1 -1
  71. package/dist/{jsonBody-BYbLDi5D.mjs → jsonBody-DDSR2HFl.mjs} +2 -2
  72. package/dist/{keys-C0_pa1tY.mjs → keys-B-HBTGXl.mjs} +1 -1
  73. package/dist/{loadResources-yawi9tAE.mjs → loadResources-DisEAmkm.mjs} +4 -3
  74. package/dist/{loadResourcesFromEntry-BAjYZonx.mjs → loadResourcesFromEntry-D1MJp13f.mjs} +2 -2
  75. package/dist/logger/index.mjs +1 -1
  76. package/dist/{mcpPlugin-B_es0hiF.mjs → mcpPlugin-CpfVpKHE.mjs} +32 -31
  77. package/dist/{memory-DR6wpa9F.mjs → memory-DsuWnj4T.mjs} +5 -5
  78. package/dist/{metrics-CUdw_wLB.mjs → metrics-DdQL8syd.mjs} +2 -2
  79. package/dist/middleware/index.mjs +3 -3
  80. package/dist/migrations/index.mjs +3 -3
  81. package/dist/{module-0pFJA6YW.mjs → module-Br81am6m.mjs} +1 -1
  82. package/dist/{multipartBody-wOgj_fnj.mjs → multipartBody-BnkBLN7v.mjs} +3 -3
  83. package/dist/{openapi-B2L4js1v.mjs → openapi-DIRzvxC0.mjs} +6 -6
  84. package/dist/outbox-admin/index.d.mts +85 -0
  85. package/dist/outbox-admin/index.mjs +115 -0
  86. package/dist/permissions/index.d.mts +2 -2
  87. package/dist/permissions/index.mjs +6 -6
  88. package/dist/{permissions-L--QDAir.mjs → permissions-Dl_m0NCe.mjs} +101 -8
  89. package/dist/{pipe-DRDNsI2T.mjs → pipe-ELHCP3zj.mjs} +3 -5
  90. package/dist/pipeline/index.mjs +2 -2
  91. package/dist/{pipeline-UPQFatit.mjs → pipeline-CPA-jx0M.mjs} +17 -15
  92. package/dist/plugins/index.d.mts +2 -2
  93. package/dist/plugins/index.mjs +16 -16
  94. package/dist/plugins/response-cache.mjs +2 -2
  95. package/dist/plugins/tracing-entry.mjs +2 -2
  96. package/dist/{pluralize-O0FZgESl.mjs → pluralize-C2ZkKbsn.mjs} +1 -1
  97. package/dist/{preloadResources-Dz6BjzM6.mjs → preloadResources-CDs87fTw.mjs} +1 -1
  98. package/dist/{preloadResources-CyoJMSiO.d.mts → preloadResources-T1hmlTEZ.d.mts} +2 -2
  99. package/dist/presets/filesUpload.mjs +6 -6
  100. package/dist/presets/index.mjs +2 -2
  101. package/dist/presets/multiTenant.mjs +3 -3
  102. package/dist/presets/search.mjs +2 -2
  103. package/dist/{presets-C4-g4_4P.mjs → presets-Dntd_pUO.mjs} +6 -5
  104. package/dist/{projection-BHw6xlOQ.mjs → projection-CjHhM5W1.mjs} +2 -2
  105. package/dist/{queryCachePlugin-BZr8v46E.mjs → queryCachePlugin-Dhps-Ldt.mjs} +6 -6
  106. package/dist/{rateLimit-CMPY5Qms.mjs → rateLimit-C7mmAGs3.mjs} +2 -2
  107. package/dist/{rateLimitKey-Dn5JNmkj.mjs → rateLimitKey-CccEFBfk.mjs} +1 -1
  108. package/dist/{realtime-C5NoxWFY.mjs → realtime-DVvVZZFz.mjs} +10 -10
  109. package/dist/{registerRoute-CBN84fc7.mjs → registerRoute-B_QrjYZS.mjs} +10 -8
  110. package/dist/registry/index.d.mts +1 -1
  111. package/dist/registry/index.mjs +3 -3
  112. package/dist/{registry-4213U4zb.mjs → registry-DqUmzA9W.mjs} +2 -2
  113. package/dist/{renewingLease-Dll8mGgc.mjs → renewingLease-BpP9wwj7.mjs} +1 -1
  114. package/dist/{replyHelpers-DIiZKGUt.mjs → replyHelpers-DS-P0b32.mjs} +2 -2
  115. package/dist/{repositoryFilter-f9eAfq_l.mjs → repositoryFilter-DotlxG3L.mjs} +1 -1
  116. package/dist/{requestContext-2TxXOJ7T.mjs → requestContext-B6vQF-sy.mjs} +1 -1
  117. package/dist/{rolldown-runtime-CUsjNX9R.mjs → rolldown-runtime-BhflRrBs.mjs} +1 -1
  118. package/dist/{schedules-DdtlICTf.mjs → schedules-C2Q3uv2d.mjs} +3 -3
  119. package/dist/{schemaConverter-D--wdJM-.mjs → schemaConverter-Crjvczi_.mjs} +1 -1
  120. package/dist/{schemaIR-Bm2enbnh.mjs → schemaIR-CnyKK_1j.mjs} +2 -2
  121. package/dist/schemas/index.mjs +1 -1
  122. package/dist/scim/index.mjs +2 -2
  123. package/dist/scope/index.mjs +5 -5
  124. package/dist/{scope-DHx5Fous.mjs → scope-afz_Ieek.mjs} +4 -4
  125. package/dist/{simpleEqualityMatcher-DjQJ7FKA.mjs → simpleEqualityMatcher-C4KiMWUa.mjs} +1 -1
  126. package/dist/{sse-CUTo9y0X.mjs → sse-B9P4Y-UI.mjs} +7 -6
  127. package/dist/{sseStream-B_5XcVVd.mjs → sseStream-B3zb_d1h.mjs} +2 -2
  128. package/dist/{store-helpers-D1MP_gRG.mjs → store-helpers-DmEMHlPQ.mjs} +1 -1
  129. package/dist/{streaming-PSZwi8JV.mjs → streaming-DPZdQmDz.mjs} +1 -1
  130. package/dist/{subscribe-helpers-C0Tb2aUp.mjs → subscribe-helpers-sp5xTDVA.mjs} +2 -2
  131. package/dist/sync/changelog.mjs +1 -1
  132. package/dist/testing/cleanupStoreContract.mjs +10 -6
  133. package/dist/testing/index.d.mts +31 -4
  134. package/dist/testing/index.mjs +97 -39
  135. package/dist/testing/outboxStoreContract.d.mts +11 -2
  136. package/dist/testing/outboxStoreContract.mjs +110 -21
  137. package/dist/testing/storageContract.mjs +11 -6
  138. package/dist/{transactionContext-dAfBVUrk.mjs → transactionContext-BvLKvOIL.mjs} +1 -1
  139. package/dist/{typeGuards-B0ryPo3I.mjs → typeGuards-B_5-hKjJ.mjs} +1 -1
  140. package/dist/types/index.mjs +1 -1
  141. package/dist/types/storage.mjs +1 -1
  142. package/dist/{types-CBgvkp8O.d.mts → types-CT5vu6M0.d.mts} +87 -11
  143. package/dist/{types-Cys0ko9Z.mjs → types-DXYX7dIR.mjs} +4 -4
  144. package/dist/usage/index.mjs +0 -0
  145. package/dist/{userHelpers-ChYJ6CdK.mjs → userHelpers-BNsOXzOd.mjs} +1 -1
  146. package/dist/utils/index.mjs +10 -10
  147. package/dist/{utils-vL8BrDE2.mjs → utils-BtOha_Sp.mjs} +3 -3
  148. package/dist/{validate-_KbifpHF.mjs → validate-PMCPR9El.mjs} +2 -2
  149. package/dist/{versioning-CHDTor3P.mjs → versioning-CKv2jz_U.mjs} +4 -4
  150. package/package.json +23 -13
  151. package/dist/fastify-augmentation-zh0_AYHa.d.mts +0 -85
@@ -1,6 +1,6 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { a as conjoinPolicyFilters, i as normalizeToDecision, r as evaluatePermissionDecision, t as applyAuthorizationDecision } from "../authorizationDecision-ChvUQGG1.mjs";
3
- import { n as getUserRoles, r as normalizeRoles } from "../userHelpers-ChYJ6CdK.mjs";
4
- import { i as resolveEffectiveRoles, n as applyFieldWritePermissions, r as fields, t as applyFieldReadPermissions } from "../fields-CB5Cuzk9.mjs";
5
- import { A as allow, B as roles, C as requireScopeContext, D as requireDPoP, E as requireAgentScope, F as not, H as scopeOf, I as requireAuth, L as requireOwnership, M as anyOf, N as deny, O as requireMandate, P as denyAll, R as requirePlatformRole, S as requireOrgRole, T as requireTeamMembership, V as when, _ as explainAccess, a as permissionMatrix, b as requireOrgInScope, c as publicReadAdminWrite, d as GRANT_MODES, f as modeSatisfies, g as describePermissionMap, h as describePermission, i as ownerWithAdminBypass, j as allowPublic, k as allOf, l as readOnly, m as collectPublicSurface, n as authenticated, o as presets_exports, p as requireGrant, r as fullPublic, s as publicRead, t as adminOnly, u as createRoleHierarchy, v as createDynamicPermissionMatrix, w as requireServiceScope, x as requireOrgMembership, y as createOrgPermissions, z as requireRoles } from "../permissions-L--QDAir.mjs";
6
- export { GRANT_MODES, adminOnly, allOf, allow, allowPublic, anyOf, applyAuthorizationDecision, applyFieldReadPermissions, applyFieldWritePermissions, authenticated, collectPublicSurface, conjoinPolicyFilters, createDynamicPermissionMatrix, createOrgPermissions, createRoleHierarchy, deny, denyAll, describePermission, describePermissionMap, evaluatePermissionDecision, explainAccess, fields, fullPublic, getUserRoles, modeSatisfies, normalizeRoles, normalizeToDecision, not, ownerWithAdminBypass, permissionMatrix, presets_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAgentScope, requireAuth, requireDPoP, requireGrant, requireMandate, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requirePlatformRole, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, resolveEffectiveRoles, roles, scopeOf, when };
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { a as conjoinPolicyFilters, i as normalizeToDecision, r as evaluatePermissionDecision, t as applyAuthorizationDecision } from "../authorizationDecision-__T3EJDA.mjs";
3
+ import { n as getUserRoles, r as normalizeRoles } from "../userHelpers-BNsOXzOd.mjs";
4
+ import { i as resolveEffectiveRoles, n as applyFieldWritePermissions, r as fields, t as applyFieldReadPermissions } from "../fields-DEi65pGj.mjs";
5
+ import { A as requireAgentScope, B as requireAuth, C as createOrgPermissions, D as requireScopeContext, E as requireOrgRole, F as allowPublic, G as when, H as requirePlatformRole, I as anyOf, K as scopeOf, L as deny, M as requireMandate, N as allOf, O as requireServiceScope, P as allow, R as denyAll, S as createDynamicPermissionMatrix, T as requireOrgMembership, U as requireRoles, V as requireOwnership, W as roles, _ as requireGrant, a as adminOnly, b as describePermissionMap, c as ownerWithAdminBypass, d as publicRead, f as publicReadAdminWrite, g as modeSatisfies, h as GRANT_MODES, i as introspectRegistry, j as requireDPoP, k as requireTeamMembership, l as permissionMatrix, m as createRoleHierarchy, n as introspectCheck, o as authenticated, p as readOnly, r as introspectModule, s as fullPublic, t as buildPermissionMatrix, u as presets_exports, v as collectPublicSurface, w as requireOrgInScope, x as explainAccess, y as describePermission, z as not } from "../permissions-Dl_m0NCe.mjs";
6
+ export { GRANT_MODES, adminOnly, allOf, allow, allowPublic, anyOf, applyAuthorizationDecision, applyFieldReadPermissions, applyFieldWritePermissions, authenticated, buildPermissionMatrix, collectPublicSurface, conjoinPolicyFilters, createDynamicPermissionMatrix, createOrgPermissions, createRoleHierarchy, deny, denyAll, describePermission, describePermissionMap, evaluatePermissionDecision, explainAccess, fields, fullPublic, getUserRoles, introspectCheck, introspectModule, introspectRegistry, modeSatisfies, normalizeRoles, normalizeToDecision, not, ownerWithAdminBypass, permissionMatrix, presets_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAgentScope, requireAuth, requireDPoP, requireGrant, requireMandate, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requirePlatformRole, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, resolveEffectiveRoles, roles, scopeOf, when };
@@ -1,10 +1,10 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { t as __exportAll } from "./rolldown-runtime-CUsjNX9R.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { t as __exportAll } from "./rolldown-runtime-BhflRrBs.mjs";
3
3
  import { arcLog } from "./logger/index.mjs";
4
- import { a as conjoinPolicyFilters, i as normalizeToDecision } from "./authorizationDecision-ChvUQGG1.mjs";
5
- import { n as getUserRoles } from "./userHelpers-ChYJ6CdK.mjs";
6
- import { C as isService, S as isOrgInScope, a as getDPoPJkt, b as isElevated, d as getScopeContext, f as getScopeContextMap, g as getUserId, m as getTeamId, n as PUBLIC_SCOPE, o as getMandate, p as getServiceScopes, u as getRequestScope, v as hasOrgAccess, x as isMember } from "./types-Cys0ko9Z.mjs";
7
- import { t as MemoryCacheStore } from "./memory-DR6wpa9F.mjs";
4
+ import { a as conjoinPolicyFilters, i as normalizeToDecision } from "./authorizationDecision-__T3EJDA.mjs";
5
+ import { n as getUserRoles } from "./userHelpers-BNsOXzOd.mjs";
6
+ import { C as isService, S as isOrgInScope, a as getDPoPJkt, b as isElevated, d as getScopeContext, f as getScopeContextMap, g as getUserId, m as getTeamId, n as PUBLIC_SCOPE, o as getMandate, p as getServiceScopes, u as getRequestScope, v as hasOrgAccess, x as isMember } from "./types-DXYX7dIR.mjs";
7
+ import { t as MemoryCacheStore } from "./memory-DsuWnj4T.mjs";
8
8
  import { randomUUID } from "node:crypto";
9
9
  //#region src/permissions/context.ts
10
10
  /**
@@ -578,7 +578,8 @@ function requireAgentScope(opts) {
578
578
  */
579
579
  function requireOrgMembership() {
580
580
  const check = (ctx) => {
581
- if (hasOrgAccess(scopeOf(ctx))) return true;
581
+ const scope = scopeOf(ctx);
582
+ if (hasOrgAccess(scope)) return true;
582
583
  if (!ctx.user) return deny("Authentication required");
583
584
  return deny("Organization membership required");
584
585
  };
@@ -1545,4 +1546,96 @@ function readOnly(overrides) {
1545
1546
  }, overrides);
1546
1547
  }
1547
1548
  //#endregion
1548
- export { allow as A, roles as B, requireScopeContext as C, requireDPoP as D, requireAgentScope as E, not as F, scopeOf as H, requireAuth as I, requireOwnership as L, anyOf as M, deny as N, requireMandate as O, denyAll as P, requirePlatformRole as R, requireOrgRole as S, requireTeamMembership as T, when as V, explainAccess as _, permissionMatrix as a, requireOrgInScope as b, publicReadAdminWrite as c, GRANT_MODES as d, modeSatisfies as f, describePermissionMap as g, describePermission as h, ownerWithAdminBypass as i, allowPublic as j, allOf as k, readOnly as l, collectPublicSurface as m, authenticated as n, presets_exports as o, requireGrant as p, fullPublic as r, publicRead as s, adminOnly as t, createRoleHierarchy as u, createDynamicPermissionMatrix as v, requireServiceScope as w, requireOrgMembership as x, createOrgPermissions as y, requireRoles as z };
1549
+ //#region src/permissions/matrix.ts
1550
+ /**
1551
+ * Permission MATRIX — what the caller may do, answered from the live registry.
1552
+ *
1553
+ * A permission-gated frontend has to decide which screens and buttons to render
1554
+ * before it issues a request. Without a server answer it keeps a hand-written
1555
+ * copy of the gates, and that copy drifts the moment a resource changes one —
1556
+ * silently, and in the dangerous direction: the UI offers an action the server
1557
+ * will refuse, or hides one the user is entitled to.
1558
+ *
1559
+ * This builds the answer from what arc ACTUALLY enforces. Every registered
1560
+ * resource contributes its CRUD gates, its state-transition `action:<verb>`
1561
+ * gates and its `agg:<name>` gates, introspected through `describePermission`.
1562
+ * A resource that exists therefore gates its own screen with no one adding it
1563
+ * anywhere — including resources unique to one deployment.
1564
+ *
1565
+ * ## Why it lives in arc
1566
+ *
1567
+ * Every input is arc's: `describePermission`, the resource registry, the shapes
1568
+ * of `actions` and `aggregations`. Nothing here knows what a domain is. Built
1569
+ * in a host, it is re-derived per deployment — and the known gap below is a
1570
+ * gap in arc's own introspection, which a host cannot close but arc can.
1571
+ *
1572
+ * ## Known gap
1573
+ *
1574
+ * `anyOf(a, b)` composes checks into a bare function with no aggregated meta,
1575
+ * so `anyOf(platformAdminOnly(), requireOrgRole(…))` introspects as
1576
+ * `authenticated` with no roles. Consumers must read `authenticated` as "the
1577
+ * server decides" rather than "any logged-in user", and fall back to an
1578
+ * explicit gate for those. Fixing it means teaching the combinators to
1579
+ * aggregate meta — an arc change, tracked here because this is where it shows.
1580
+ */
1581
+ /** Re-shape arc's typed requirement into the wire entry. */
1582
+ function introspectCheck(check) {
1583
+ const req = describePermission(check);
1584
+ if (req.kind === "public") return {
1585
+ type: "public",
1586
+ roles: []
1587
+ };
1588
+ if (req.kind === "roles") return {
1589
+ type: "roles",
1590
+ roles: [...req.roles]
1591
+ };
1592
+ if (req.kind === "scoped") return {
1593
+ type: "scoped",
1594
+ roles: req.roles ? [...req.roles] : [],
1595
+ scope: { ...req.scope }
1596
+ };
1597
+ return {
1598
+ type: "authenticated",
1599
+ roles: []
1600
+ };
1601
+ }
1602
+ /** Introspect a permission module, flattening nested groups to `a.b`. */
1603
+ function introspectModule(mod) {
1604
+ const result = {};
1605
+ for (const [action, check] of Object.entries(mod)) if (typeof check === "function") result[action] = introspectCheck(check);
1606
+ else if (typeof check === "object" && check !== null) for (const [nested, entry] of Object.entries(introspectModule(check))) result[`${action}.${nested}`] = entry;
1607
+ return result;
1608
+ }
1609
+ /** Every live resource's ACTUAL gates, keyed by arc resource name. */
1610
+ function introspectRegistry(registry) {
1611
+ const modules = {};
1612
+ for (const entry of registry.getAll()) {
1613
+ const map = {};
1614
+ for (const [action, check] of Object.entries(entry.permissions ?? {})) if (typeof check === "function") map[action] = introspectCheck(check);
1615
+ for (const a of entry.actions ?? []) if (typeof a.permissions === "function") map[`action:${a.name}`] = introspectCheck(a.permissions);
1616
+ for (const agg of entry.aggregations ?? []) if (typeof agg.permissions === "function") map[`agg:${agg.name}`] = introspectCheck(agg.permissions);
1617
+ if (Object.keys(map).length > 0) modules[entry.name] = map;
1618
+ }
1619
+ return modules;
1620
+ }
1621
+ function buildPermissionMatrix(options = {}) {
1622
+ const platform = [...options.platformRoles ?? []];
1623
+ const branch = [...options.orgRoles ?? []];
1624
+ const modules = {};
1625
+ for (const [name, mod] of Object.entries(options.curatedModules ?? {})) if (typeof mod === "object" && mod !== null) modules[name] = introspectModule(mod);
1626
+ for (const [name, mod] of Object.entries(options.fallbackModules ?? {})) {
1627
+ if (modules[name]) continue;
1628
+ if (typeof mod === "object" && mod !== null) modules[name] = introspectModule(mod);
1629
+ }
1630
+ if (options.registry) Object.assign(modules, introspectRegistry(options.registry));
1631
+ return {
1632
+ roles: [.../* @__PURE__ */ new Set([...platform, ...branch])],
1633
+ roleGroups: {
1634
+ platform,
1635
+ branch
1636
+ },
1637
+ modules
1638
+ };
1639
+ }
1640
+ //#endregion
1641
+ export { requireAgentScope as A, requireAuth as B, createOrgPermissions as C, requireScopeContext as D, requireOrgRole as E, allowPublic as F, when as G, requirePlatformRole as H, anyOf as I, scopeOf as K, deny as L, requireMandate as M, allOf as N, requireServiceScope as O, allow as P, denyAll as R, createDynamicPermissionMatrix as S, requireOrgMembership as T, requireRoles as U, requireOwnership as V, roles as W, requireGrant as _, adminOnly as a, describePermissionMap as b, ownerWithAdminBypass as c, publicRead as d, publicReadAdminWrite as f, modeSatisfies as g, GRANT_MODES as h, introspectRegistry as i, requireDPoP as j, requireTeamMembership as k, permissionMatrix as l, createRoleHierarchy as m, introspectCheck as n, authenticated as o, readOnly as p, introspectModule as r, fullPublic as s, buildPermissionMatrix as t, presets_exports as u, collectPublicSurface as v, requireOrgInScope as w, explainAccess as x, describePermission as y, not as z };
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { r as ForbiddenError } from "./errors-Cj42AntO.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { r as ForbiddenError } from "./errors-Bh1KK5ps.mjs";
3
3
  //#region src/pipeline/pipe.ts
4
4
  /**
5
5
  * Compose pipeline steps into an ordered array.
@@ -40,9 +40,7 @@ async function executePipeline(steps, ctx, handler, operation) {
40
40
  case "transform":
41
41
  transforms.push(step);
42
42
  break;
43
- case "interceptor":
44
- interceptors.push(step);
45
- break;
43
+ case "interceptor": interceptors.push(step);
46
44
  }
47
45
  }
48
46
  for (const g of guards) if (!await g.handler(ctx)) throw new ForbiddenError(`Guard '${g.name}' denied access`);
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { n as pipe, t as executePipeline } from "../pipe-DRDNsI2T.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { n as pipe, t as executePipeline } from "../pipe-ELHCP3zj.mjs";
3
3
  //#region src/pipeline/guard.ts
4
4
  /**
5
5
  * Create a named guard.
@@ -1,9 +1,9 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { n as getUserRoles } from "./userHelpers-ChYJ6CdK.mjs";
3
- import { b as isElevated, n as PUBLIC_SCOPE, x as isMember } from "./types-Cys0ko9Z.mjs";
4
- import { i as resolveEffectiveRoles, t as applyFieldReadPermissions } from "./fields-CB5Cuzk9.mjs";
5
- import { t as executePipeline } from "./pipe-DRDNsI2T.mjs";
6
- import { t as buildRequestScopeProjection } from "./projection-BHw6xlOQ.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { n as getUserRoles } from "./userHelpers-BNsOXzOd.mjs";
3
+ import { b as isElevated, n as PUBLIC_SCOPE, x as isMember } from "./types-DXYX7dIR.mjs";
4
+ import { i as resolveEffectiveRoles, t as applyFieldReadPermissions } from "./fields-DEi65pGj.mjs";
5
+ import { t as executePipeline } from "./pipe-ELHCP3zj.mjs";
6
+ import { t as buildRequestScopeProjection } from "./projection-CjHhM5W1.mjs";
7
7
  import { isPaginatedResult, toCanonicalList } from "@classytic/repo-core/pagination";
8
8
  //#region src/core/fastifyAdapter.ts
9
9
  /** Type guard for Mongoose-like documents with toObject() */
@@ -122,9 +122,7 @@ function computeFieldCapabilities(fieldPerms, effectiveRoles) {
122
122
  case "visibleTo":
123
123
  readable = perm.roles?.some((r) => effectiveRoles.includes(r)) ?? false;
124
124
  break;
125
- case "writableBy":
126
- writable = perm.roles?.some((r) => effectiveRoles.includes(r)) ?? false;
127
- break;
125
+ case "writableBy": writable = perm.roles?.some((r) => effectiveRoles.includes(r)) ?? false;
128
126
  }
129
127
  caps[field] = {
130
128
  readable,
@@ -172,8 +170,10 @@ function sendControllerResponse(reply, response, request) {
172
170
  /** Apply both field mask and field-level permissions to a data item */
173
171
  const applyPermissions = (data) => {
174
172
  let result = fieldMaskConfig ? applyFieldMask(data, fieldMaskConfig) : data;
175
- if (fieldPerms && result && typeof result === "object") if (Array.isArray(result)) result = result.map((item) => applyFieldReadPermissions(item, fieldPerms, effectiveRoles));
176
- else result = applyFieldReadPermissions(result, fieldPerms, effectiveRoles);
173
+ if (fieldPerms && result && typeof result === "object") {
174
+ if (Array.isArray(result)) result = result.map((item) => applyFieldReadPermissions(item, fieldPerms, effectiveRoles));
175
+ else result = applyFieldReadPermissions(result, fieldPerms, effectiveRoles);
176
+ }
177
177
  return result;
178
178
  };
179
179
  if (response.headers) for (const [key, value] of Object.entries(response.headers)) reply.header(key, value);
@@ -281,11 +281,12 @@ function resolvePipelineSteps(pipeline, operation) {
281
281
  */
282
282
  function buildPipelineHandler(controllerMethod, steps, operation, resourceName) {
283
283
  return async (req, reply) => {
284
- sendControllerResponse(reply, await executePipeline(steps, {
284
+ const pipeCtx = {
285
285
  ...createRequestContext(req),
286
286
  resource: resourceName,
287
287
  operation
288
- }, (ctx) => controllerMethod(ctx), operation), req);
288
+ };
289
+ sendControllerResponse(reply, await executePipeline(steps, pipeCtx, (ctx) => controllerMethod(ctx), operation), req);
289
290
  };
290
291
  }
291
292
  /**
@@ -310,11 +311,12 @@ function buildActionPipelineHandler(handler, steps, operation, resourceName) {
310
311
  data: await handler(id, data, req)
311
312
  });
312
313
  return async (id, data, req) => {
313
- return executePipeline(steps, {
314
+ const pipeCtx = {
314
315
  ...createRequestContext(req),
315
316
  resource: resourceName,
316
317
  operation
317
- }, async (_ctx) => ({
318
+ };
319
+ return executePipeline(steps, pipeCtx, async (_ctx) => ({
318
320
  status: 200,
319
321
  data: await handler(id, data, req)
320
322
  }), operation);
@@ -2,8 +2,8 @@
2
2
  import { At as RouteDefinition, J as PresetHook, Q as MiddlewareConfig, et as RouteSchemaOptions } from "../index-CpzxqePp.mjs";
3
3
  import { l as AnyRecord } from "../types-B7XeLEgK.mjs";
4
4
  import { i as errorHandlerPlugin, n as ErrorMapper, r as defaultIsDuplicateKeyError, t as ErrorHandlerOptions } from "../errorHandler-CpYUJmPA.mjs";
5
- import { _ as _default$3, d as ScheduleStats, f as SchedulesPluginOptions, g as HealthOptions, h as HealthCheck, m as schedulesPlugin, p as _default$7, u as ScheduleDefinition, v as healthPlugin } from "../types-CBgvkp8O.mjs";
6
- import { a as arcCorePlugin, i as _default, n as ArcCorePluginOptions, r as PluginMeta, t as ArcCore } from "../fastify-augmentation-zh0_AYHa.mjs";
5
+ import { _ as HealthCheck, b as healthPlugin, f as ScheduleDefinition, g as schedulesPlugin, h as _default$7, m as SchedulesPluginOptions, p as ScheduleStats, v as HealthOptions, y as _default$3 } from "../types-CT5vu6M0.mjs";
6
+ import { a as arcCorePlugin, i as _default, n as ArcCorePluginOptions, r as PluginMeta, t as ArcCore } from "../fastify-augmentation-BppG5bMT.mjs";
7
7
  import { _ as CachingRule, a as MetricsCollector, c as metricsPlugin, d as _default$5, f as realtimePlugin, g as CachingOptions, h as ssePlugin, i as MetricEntry, l as ChangeOperation, m as _default$8, n as _default$9, o as MetricsOptions, p as SSEOptions, r as versioningPlugin, s as _default$4, t as VersioningOptions, u as RealtimeOptions, v as _default$1, y as cachingPlugin } from "../versioning-D_rhHfZm.mjs";
8
8
  import { t as TracingOptions } from "../tracing-Dro5eH6j.mjs";
9
9
  import { PaginatedResult } from "@classytic/repo-core/pagination";
@@ -1,19 +1,19 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { p as MUTATION_OPERATIONS } from "../constants-D3Dv4LAV.mjs";
3
- import { c as getOrgId } from "../types-Cys0ko9Z.mjs";
4
- import { n as requestContext } from "../requestContext-2TxXOJ7T.mjs";
5
- import { t as hasEvents } from "../typeGuards-B0ryPo3I.mjs";
6
- import { t as HookSystem } from "../HookSystem-BcmPyq5I.mjs";
7
- import { t as ResourceRegistry } from "../ResourceRegistry-qq0mn2s9.mjs";
8
- import { a as requestIdPlugin, i as createRequestIdGenerator, n as health_default, o as requestId_default, s as sanitizeRequestId, t as healthPlugin } from "../health-DjZYjM7H.mjs";
9
- import { n as caching_default, t as cachingPlugin } from "../caching-BFHA6Scf.mjs";
10
- import { n as errorHandlerPlugin, t as defaultIsDuplicateKeyError } from "../errorHandler-C5NeD6bT.mjs";
11
- import { n as metrics_default, t as metricsPlugin } from "../metrics-CUdw_wLB.mjs";
12
- import { n as realtime_default, t as realtimePlugin } from "../realtime-C5NoxWFY.mjs";
13
- import { t as replyHelpersPlugin } from "../replyHelpers-DIiZKGUt.mjs";
14
- import { n as schedules_default, t as schedulesPlugin } from "../schedules-DdtlICTf.mjs";
15
- import { n as sse_default, t as ssePlugin } from "../sse-CUTo9y0X.mjs";
16
- import { n as versioning_default, t as versioningPlugin } from "../versioning-CHDTor3P.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { p as MUTATION_OPERATIONS } from "../constants-J99LGTJI.mjs";
3
+ import { c as getOrgId } from "../types-DXYX7dIR.mjs";
4
+ import { n as requestContext } from "../requestContext-B6vQF-sy.mjs";
5
+ import { t as hasEvents } from "../typeGuards-B_5-hKjJ.mjs";
6
+ import { t as HookSystem } from "../HookSystem-vimw5D7Z.mjs";
7
+ import { t as ResourceRegistry } from "../ResourceRegistry-BVr7PgA0.mjs";
8
+ import { a as requestIdPlugin, i as createRequestIdGenerator, n as health_default, o as requestId_default, s as sanitizeRequestId, t as healthPlugin } from "../health-5XnTa2uo.mjs";
9
+ import { n as caching_default, t as cachingPlugin } from "../caching-DFJqHyFs.mjs";
10
+ import { n as errorHandlerPlugin, t as defaultIsDuplicateKeyError } from "../errorHandler-B2AZUJUj.mjs";
11
+ import { n as metrics_default, t as metricsPlugin } from "../metrics-DdQL8syd.mjs";
12
+ import { n as realtime_default, t as realtimePlugin } from "../realtime-DVvVZZFz.mjs";
13
+ import { t as replyHelpersPlugin } from "../replyHelpers-DS-P0b32.mjs";
14
+ import { n as schedules_default, t as schedulesPlugin } from "../schedules-C2Q3uv2d.mjs";
15
+ import { n as sse_default, t as ssePlugin } from "../sse-B9P4Y-UI.mjs";
16
+ import { n as versioning_default, t as versioningPlugin } from "../versioning-CKv2jz_U.mjs";
17
17
  import fp from "fastify-plugin";
18
18
  //#region src/core/arcCorePlugin.ts
19
19
  const arcCorePlugin = async (fastify, opts = {}) => {
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { t as hasEvents } from "../typeGuards-B0ryPo3I.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { t as hasEvents } from "../typeGuards-B_5-hKjJ.mjs";
3
3
  import fp from "fastify-plugin";
4
4
  //#region src/plugins/response-cache.ts
5
5
  /**
@@ -1,4 +1,4 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
2
  import { createRequire } from "node:module";
3
3
  import fp from "fastify-plugin";
4
4
  //#region src/plugins/tracing.ts
@@ -59,7 +59,7 @@ try {
59
59
  function createTracerProvider(options) {
60
60
  if (!isAvailable || !NodeTracerProvider || !BatchSpanProcessor || !OTLPTraceExporter) return null;
61
61
  const { serviceName = "@classytic/arc", serviceVersion, exporterUrl = "http://localhost:4318/v1/traces" } = options;
62
- const resolvedVersion = serviceVersion ?? "2.31.0";
62
+ const resolvedVersion = serviceVersion ?? "2.32.0";
63
63
  const exporter = new OTLPTraceExporter({ url: exporterUrl });
64
64
  const provider = new NodeTracerProvider({ resource: { attributes: {
65
65
  "service.name": serviceName,
@@ -1,4 +1,4 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
2
  //#region src/utils/pluralize.ts
3
3
  /**
4
4
  * Lightweight English pluralization for the Arc CLI.
@@ -1,4 +1,4 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
2
  //#region src/factory/preloadResources.ts
3
3
  /**
4
4
  * Normalize an eager `import.meta.glob` result into a `ResourceLike[]`.
@@ -6,8 +6,8 @@ import { a as EventTransport } from "./EventTransport-2uVV34WU.mjs";
6
6
  import { t as ExternalOpenApiPaths } from "./externalPaths-CmGOxOtD.mjs";
7
7
  import { r as QueryCachePluginOptions } from "./queryCachePlugin-BzqxconG.mjs";
8
8
  import { t as ErrorHandlerOptions } from "./errorHandler-CpYUJmPA.mjs";
9
- import { f as SchedulesPluginOptions, g as HealthOptions, n as ArcModuleInput, s as ResourceLike } from "./types-CBgvkp8O.mjs";
10
- import "./index-CFThn1K9.mjs";
9
+ import { l as ResourceLike, m as SchedulesPluginOptions, n as ArcModuleInput, v as HealthOptions } from "./types-CT5vu6M0.mjs";
10
+ import "./index-ZWhLTp_s.mjs";
11
11
  import { t as EventPluginOptions } from "./eventPlugin-GF5nnBIq.mjs";
12
12
  import { g as CachingOptions, o as MetricsOptions, p as SSEOptions, t as VersioningOptions, u as RealtimeOptions } from "./versioning-D_rhHfZm.mjs";
13
13
  import { r as IdempotencyStore } from "./interface-DEWNOMza.mjs";
@@ -1,11 +1,11 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { i as NotFoundError, u as ValidationError } from "../errors-Cj42AntO.mjs";
3
- import { c as getOrgId, g as getUserId } from "../types-Cys0ko9Z.mjs";
4
- import { I as requireAuth, j as allowPublic } from "../permissions-L--QDAir.mjs";
5
- import { t as multipartBody } from "../multipartBody-wOgj_fnj.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { i as NotFoundError, u as ValidationError } from "../errors-Bh1KK5ps.mjs";
3
+ import { c as getOrgId, g as getUserId } from "../types-DXYX7dIR.mjs";
4
+ import { B as requireAuth, F as allowPublic } from "../permissions-Dl_m0NCe.mjs";
5
+ import { t as multipartBody } from "../multipartBody-BnkBLN7v.mjs";
6
6
  //#region src/presets/filesUpload.ts
7
7
  const DEFAULT_FIELD_NAME = "file";
8
- const DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024;
8
+ const DEFAULT_MAX_FILE_SIZE = 10485760;
9
9
  function defaultContextFrom(scope) {
10
10
  if (!scope) return {};
11
11
  const userId = getUserId(scope);
@@ -1,6 +1,6 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
2
  import { multiTenantPreset } from "./multiTenant.mjs";
3
- import { a as registerPreset, c as auditedPreset, d as ownedByUserPreset, i as getPreset, l as softDeletePreset, n as flexibleMultiTenantPreset, o as treePreset, r as getAvailablePresets, s as bulkPreset, t as applyPresets, u as slugLookupPreset } from "../presets-C4-g4_4P.mjs";
3
+ import { a as registerPreset, c as auditedPreset, d as ownedByUserPreset, i as getPreset, l as softDeletePreset, n as flexibleMultiTenantPreset, o as treePreset, r as getAvailablePresets, s as bulkPreset, t as applyPresets, u as slugLookupPreset } from "../presets-Dntd_pUO.mjs";
4
4
  import { filesUploadPreset } from "./filesUpload.mjs";
5
5
  import { searchPreset } from "./search.mjs";
6
6
  export { applyPresets, auditedPreset, bulkPreset, filesUploadPreset, flexibleMultiTenantPreset, getAvailablePresets, getPreset, multiTenantPreset, ownedByUserPreset, registerPreset, searchPreset, slugLookupPreset, softDeletePreset, treePreset };
@@ -1,6 +1,6 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import "../constants-D3Dv4LAV.mjs";
3
- import { b as isElevated, c as getOrgId, d as getScopeContext, m as getTeamId, u as getRequestScope, v as hasOrgAccess } from "../types-Cys0ko9Z.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import "../constants-J99LGTJI.mjs";
3
+ import { b as isElevated, c as getOrgId, d as getScopeContext, m as getTeamId, u as getRequestScope, v as hasOrgAccess } from "../types-DXYX7dIR.mjs";
4
4
  //#region src/presets/multiTenant.ts
5
5
  /**
6
6
  * Resolve a single TenantFieldSpec against the current scope.
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { I as requireAuth, j as allowPublic } from "../permissions-L--QDAir.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { B as requireAuth, F as allowPublic } from "../permissions-Dl_m0NCe.mjs";
3
3
  //#region src/presets/search.ts
4
4
  const BUILTINS = [
5
5
  {
@@ -1,7 +1,7 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { l as UnauthorizedError } from "./errors-Cj42AntO.mjs";
3
- import { b as isElevated, n as PUBLIC_SCOPE } from "./types-Cys0ko9Z.mjs";
4
- import { I as requireAuth, j as allowPublic, z as requireRoles } from "./permissions-L--QDAir.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { l as UnauthorizedError } from "./errors-Bh1KK5ps.mjs";
3
+ import { b as isElevated, n as PUBLIC_SCOPE } from "./types-DXYX7dIR.mjs";
4
+ import { B as requireAuth, F as allowPublic, U as requireRoles } from "./permissions-Dl_m0NCe.mjs";
5
5
  import { multiTenantPreset } from "./presets/multiTenant.mjs";
6
6
  //#region src/presets/ownedByUser.ts
7
7
  /**
@@ -14,7 +14,8 @@ import { multiTenantPreset } from "./presets/multiTenant.mjs";
14
14
  */
15
15
  function createOwnershipCheck(ownerField, missingOwner) {
16
16
  return async (request, _reply) => {
17
- if (isElevated(request.scope ?? PUBLIC_SCOPE)) return;
17
+ const scope = request.scope ?? PUBLIC_SCOPE;
18
+ if (isElevated(scope)) return;
18
19
  const user = request.user;
19
20
  if (!user) throw new UnauthorizedError("Authentication required for this operation");
20
21
  const userWithId = user;
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { c as getOrgId, g as getUserId, x as isMember } from "./types-Cys0ko9Z.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { c as getOrgId, g as getUserId, x as isMember } from "./types-DXYX7dIR.mjs";
3
3
  //#region src/scope/projection.ts
4
4
  /**
5
5
  * Compute the request-scope projection. Returns `undefined` when no
@@ -1,8 +1,8 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { t as __exportAll } from "./rolldown-runtime-CUsjNX9R.mjs";
3
- import { t as hasEvents } from "./typeGuards-B0ryPo3I.mjs";
4
- import { i as versionKey, r as tagVersionKey } from "./keys-C0_pa1tY.mjs";
5
- import { t as MemoryCacheStore } from "./memory-DR6wpa9F.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { t as __exportAll } from "./rolldown-runtime-BhflRrBs.mjs";
3
+ import { t as hasEvents } from "./typeGuards-B_5-hKjJ.mjs";
4
+ import { i as versionKey, r as tagVersionKey } from "./keys-B-HBTGXl.mjs";
5
+ import { t as MemoryCacheStore } from "./memory-DsuWnj4T.mjs";
6
6
  import fp from "fastify-plugin";
7
7
  //#region src/cache/QueryCache.ts
8
8
  var QueryCache = class {
@@ -100,7 +100,7 @@ var QueryCache = class {
100
100
  }
101
101
  };
102
102
  /** See `bumpVersion` — effectively non-expiring, refreshed on every bump. */
103
- const VERSION_TTL_SECONDS = 365 * 24 * 60 * 60;
103
+ const VERSION_TTL_SECONDS = 31536e3;
104
104
  //#endregion
105
105
  //#region src/cache/queryCachePlugin.ts
106
106
  var queryCachePlugin_exports = /* @__PURE__ */ __exportAll({ queryCachePlugin: () => queryCachePlugin });
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { n as requestContext } from "./requestContext-2TxXOJ7T.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { n as requestContext } from "./requestContext-B6vQF-sy.mjs";
3
3
  //#region src/core/middlewares/arcDecorator.ts
4
4
  /**
5
5
  * Build the `arcDecorator` preHandler for a resource.
@@ -1,4 +1,4 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
2
  //#region src/scope/rateLimitKey.ts
3
3
  function createTenantKeyGenerator(opts) {
4
4
  if (opts?.strategy) return opts.strategy;
@@ -1,13 +1,13 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { t as __exportAll } from "./rolldown-runtime-CUsjNX9R.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { t as __exportAll } from "./rolldown-runtime-BhflRrBs.mjs";
3
3
  import { arcLog } from "./logger/index.mjs";
4
- import { n as evaluateAndApplyPermission } from "./authorizationDecision-ChvUQGG1.mjs";
5
- import { n as getUserRoles } from "./userHelpers-ChYJ6CdK.mjs";
6
- import { c as getOrgId } from "./types-Cys0ko9Z.mjs";
7
- import { t as simpleEqualityMatcher } from "./simpleEqualityMatcher-DjQJ7FKA.mjs";
8
- import { t as applyFieldReadPermissions } from "./fields-CB5Cuzk9.mjs";
9
- import { a as promoteStreamTokenToHeader } from "./streaming-PSZwi8JV.mjs";
10
- import { t as openSseStream } from "./sseStream-B_5XcVVd.mjs";
4
+ import { n as evaluateAndApplyPermission } from "./authorizationDecision-__T3EJDA.mjs";
5
+ import { n as getUserRoles } from "./userHelpers-BNsOXzOd.mjs";
6
+ import { c as getOrgId } from "./types-DXYX7dIR.mjs";
7
+ import { t as simpleEqualityMatcher } from "./simpleEqualityMatcher-C4KiMWUa.mjs";
8
+ import { t as applyFieldReadPermissions } from "./fields-DEi65pGj.mjs";
9
+ import { a as promoteStreamTokenToHeader } from "./streaming-DPZdQmDz.mjs";
10
+ import { t as openSseStream } from "./sseStream-B3zb_d1h.mjs";
11
11
  import fp from "fastify-plugin";
12
12
  //#region src/plugins/realtime.ts
13
13
  var realtime_exports = /* @__PURE__ */ __exportAll({
@@ -47,7 +47,7 @@ const MAX_TIMER_MS = 2147483647;
47
47
  * churning connections. A host that truly wants a longer-lived feed sets
48
48
  * `maxConnectionMs` explicitly (up to `MAX_TIMER_MS`).
49
49
  */
50
- const DEFAULT_MAX_CONNECTION_MS = 30 * 6e4;
50
+ const DEFAULT_MAX_CONNECTION_MS = 18e5;
51
51
  /**
52
52
  * Milliseconds from `now` until the feed should force-close to bound
53
53
  * permission staleness — `min(auth-token exp, maxConnectionMs)`. Returns
@@ -1,7 +1,7 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { n as evaluateAndApplyPermission } from "./authorizationDecision-ChvUQGG1.mjs";
3
- import { f as createError } from "./errors-Cj42AntO.mjs";
4
- import { u as getRequestScope } from "./types-Cys0ko9Z.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { n as evaluateAndApplyPermission } from "./authorizationDecision-__T3EJDA.mjs";
3
+ import { f as createError } from "./errors-Bh1KK5ps.mjs";
4
+ import { u as getRequestScope } from "./types-DXYX7dIR.mjs";
5
5
  //#region src/core/middlewares/permissions.ts
6
6
  /**
7
7
  * Build a PermissionContext from a Fastify request. Extracted so the CRUD
@@ -32,10 +32,11 @@ function buildPermissionContext(req, opts) {
32
32
  function buildCrudPermissionMw(permissionCheck, resourceName, action) {
33
33
  if (!permissionCheck) return null;
34
34
  return async (req, reply) => {
35
- await evaluateAndApplyPermission(permissionCheck, buildPermissionContext(req, {
35
+ const context = buildPermissionContext(req, {
36
36
  resource: resourceName,
37
37
  action
38
- }), req, reply);
38
+ });
39
+ await evaluateAndApplyPermission(permissionCheck, context, req, reply);
39
40
  };
40
41
  }
41
42
  /**
@@ -64,12 +65,13 @@ function buildActionPermissionMw(actionEnum, actionPermissions, globalAuth, reso
64
65
  if (!permissionCheck) return;
65
66
  const { action: _discard, ...data } = body;
66
67
  const params = req.params;
67
- await evaluateAndApplyPermission(permissionCheck, buildPermissionContext(req, {
68
+ const context = buildPermissionContext(req, {
68
69
  resource: resourceName,
69
70
  action,
70
71
  resourceId: params?.id,
71
72
  data
72
- }), req, reply, { defaultDenialMessage: (user) => user ? `Permission denied for '${action}'` : "Authentication required" });
73
+ });
74
+ await evaluateAndApplyPermission(permissionCheck, context, req, reply, { defaultDenialMessage: (user) => user ? `Permission denied for '${action}'` : "Authentication required" });
73
75
  };
74
76
  }
75
77
  //#endregion
@@ -1,6 +1,6 @@
1
1
 
2
2
  import { K as ResolvedTenantPurge, R as RegisterOptions, V as ResourceDefinition, X as CrudRouteKey, k as IntrospectionPluginOptions, p as RegistryEntry, z as ResourceRegistry } from "../index-CpzxqePp.mjs";
3
- import "../fastify-augmentation-zh0_AYHa.mjs";
3
+ import "../fastify-augmentation-BppG5bMT.mjs";
4
4
  import { FastifyPluginAsync } from "fastify";
5
5
  import { TenantPurgeProgress, TenantPurgeStrategy } from "@classytic/repo-core/repository";
6
6
  //#region src/registry/assertNoTenantData.d.ts
@@ -1,4 +1,4 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { a as cascadeDeleteForOrganization, c as assertNoTenantData, i as introspectionPlugin_default, n as buildResourceManifestFromRegistry, o as getCascadingResources, r as introspectionPlugin, s as getCascadingResourcesWithMetadata, t as buildResourceManifest } from "../registry-4213U4zb.mjs";
3
- import { t as ResourceRegistry } from "../ResourceRegistry-qq0mn2s9.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { a as cascadeDeleteForOrganization, c as assertNoTenantData, i as introspectionPlugin_default, n as buildResourceManifestFromRegistry, o as getCascadingResources, r as introspectionPlugin, s as getCascadingResourcesWithMetadata, t as buildResourceManifest } from "../registry-DqUmzA9W.mjs";
3
+ import { t as ResourceRegistry } from "../ResourceRegistry-BVr7PgA0.mjs";
4
4
  export { ResourceRegistry, assertNoTenantData, buildResourceManifest, buildResourceManifestFromRegistry, cascadeDeleteForOrganization, getCascadingResources, getCascadingResourcesWithMetadata, introspectionPlugin_default as introspectionPlugin, introspectionPlugin as introspectionPluginFn };
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { t as CRUD_OPERATIONS } from "./constants-D3Dv4LAV.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { t as CRUD_OPERATIONS } from "./constants-J99LGTJI.mjs";
3
3
  import fp from "fastify-plugin";
4
4
  //#region src/registry/assertNoTenantData.ts
5
5
  /**
@@ -1,4 +1,4 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
2
  //#region src/lock/renewingLease.ts
3
3
  /**
4
4
  * Start renewing an ALREADY-ACQUIRED lease. The caller performed the
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
2
- import { t as __exportAll } from "./rolldown-runtime-CUsjNX9R.mjs";
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
+ import { t as __exportAll } from "./rolldown-runtime-BhflRrBs.mjs";
3
3
  import { toCanonicalList } from "@classytic/repo-core/pagination";
4
4
  import fp from "fastify-plugin";
5
5
  //#region src/plugins/replyHelpers.ts
@@ -1,4 +1,4 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
2
  import { arcLog } from "./logger/index.mjs";
3
3
  import { policyRecordToFilter } from "@classytic/repo-core/filter";
4
4
  //#region src/core/repositoryFilter.ts
@@ -1,4 +1,4 @@
1
- /*! @classytic/arc v2.31.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.32.0 | MIT | https://classytic.com */
2
2
  import { AsyncLocalStorage } from "node:async_hooks";
3
3
  //#region src/context/requestContext.ts
4
4
  /**