@classytic/arc 2.35.0 → 2.36.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 (167) hide show
  1. package/dist/{BaseController-C-pofd0v.mjs → BaseController-CTJKm6Cb.mjs} +11 -11
  2. package/dist/{EventTransport-BrPeGUil.mjs → EventTransport-D23Uvhg4.mjs} +1 -1
  3. package/dist/{HookSystem-LlPm3Anm.mjs → HookSystem-DgwxNZTx.mjs} +2 -2
  4. package/dist/{ResourceRegistry-yuD1Ra53.mjs → ResourceRegistry-DNuYVbmv.mjs} +2 -2
  5. package/dist/{actionPermissions-LFuOra7W.mjs → actionPermissions-D97DniUQ.mjs} +6 -6
  6. package/dist/audit/index.d.mts +2 -2
  7. package/dist/audit/index.mjs +2 -2
  8. package/dist/auth/audit.mjs +1 -1
  9. package/dist/auth/index.d.mts +2 -2
  10. package/dist/auth/index.mjs +6 -6
  11. package/dist/auth/redis-session.mjs +1 -1
  12. package/dist/{authorizationDecision-DYXBBgtg.mjs → authorizationDecision-EsiY3nUu.mjs} +2 -2
  13. package/dist/{base-GZU3LlzP.d.mts → base-C-NL2fTi.d.mts} +15 -0
  14. package/dist/{buildHandler-Do9aMIvL.mjs → buildHandler-Dohd2JuY.mjs} +4 -4
  15. package/dist/cache/index.mjs +4 -4
  16. package/dist/{caching-cN5X9VEL.mjs → caching-CP3GLJ7U.mjs} +2 -2
  17. package/dist/cleanup/index.d.mts +1 -1
  18. package/dist/cleanup/index.mjs +4 -4
  19. package/dist/cli/commands/describe.d.mts +1 -1
  20. package/dist/cli/commands/describe.mjs +3 -3
  21. package/dist/cli/commands/docs.mjs +3 -3
  22. package/dist/cli/commands/doctor.mjs +1 -1
  23. package/dist/cli/commands/generate.mjs +2 -2
  24. package/dist/cli/commands/init.mjs +2 -2
  25. package/dist/cli/commands/introspect.mjs +2 -2
  26. package/dist/cli/index.mjs +3 -3
  27. package/dist/{constants-BhzLXCfN.mjs → constants-DUoKAGYD.mjs} +1 -1
  28. package/dist/context/index.mjs +3 -3
  29. package/dist/core/index.d.mts +2 -2
  30. package/dist/core/index.mjs +7 -7
  31. package/dist/{core-DdEvmmkY.mjs → core-DTXsiNTJ.mjs} +3 -3
  32. package/dist/{createActionRouter-EYWgd0ly.mjs → createActionRouter-CZz6JO93.mjs} +7 -7
  33. package/dist/{createAggregationRouter-ByOK9Iev.mjs → createAggregationRouter-DKrGv_EC.mjs} +7 -7
  34. package/dist/{defineAggregation-DoIijIFq.mjs → defineAggregation-CpQfcM8R.mjs} +1 -1
  35. package/dist/{defineResource-BOrGeocE.mjs → defineResource-DWzjyxb2.mjs} +18 -18
  36. package/dist/discovery/index.mjs +1 -1
  37. package/dist/docs/index.d.mts +1 -1
  38. package/dist/docs/index.mjs +3 -3
  39. package/dist/{elevation-tGIAldco.mjs → elevation-D_cmo80j.mjs} +4 -4
  40. package/dist/encryption/index.mjs +3 -3
  41. package/dist/{errorHandler-BbQ1nQdk.mjs → errorHandler-2RT0hLSI.mjs} +3 -3
  42. package/dist/{errors-CLid6atr.mjs → errors-DDKni6Tz.mjs} +1 -1
  43. package/dist/{eventPlugin-ClPn5kjn.mjs → eventPlugin-c3YwGzz9.mjs} +5 -5
  44. package/dist/events/index.mjs +5 -5
  45. package/dist/events/transports/redis-stream-entry.mjs +1 -1
  46. package/dist/events/transports/redis.mjs +1 -1
  47. package/dist/factory/index.d.mts +2 -2
  48. package/dist/factory/index.mjs +5 -5
  49. package/dist/{fastify-augmentation-CMMTL3cj.d.mts → fastify-augmentation-Bk_9PoiV.d.mts} +1 -1
  50. package/dist/{fields-UtpiJO5R.mjs → fields-DdP225wt.mjs} +1 -1
  51. package/dist/{generate-BoAVy3_b.mjs → generate-B1bKdcV9.mjs} +2 -2
  52. package/dist/{headers-DODWf7aC.mjs → headers-DKslnhey.mjs} +2 -2
  53. package/dist/{health-_Zs3R_Sb.mjs → health-k6NODS8f.mjs} +1 -1
  54. package/dist/hooks/index.d.mts +1 -1
  55. package/dist/hooks/index.mjs +2 -2
  56. package/dist/idempotency/index.mjs +4 -4
  57. package/dist/idempotency/redis.mjs +1 -1
  58. package/dist/{index-K7auNNW0.d.mts → index-BtYoMip1.d.mts} +20 -2
  59. package/dist/{index-C5K78SXo.d.mts → index-C01wWGJt.d.mts} +1 -1
  60. package/dist/{index-h-mTgMqy.d.mts → index-RdpLP71b.d.mts} +3 -3
  61. package/dist/{index-CJCcbADG.d.mts → index-eyg5WEcy.d.mts} +1 -1
  62. package/dist/index.d.mts +5 -5
  63. package/dist/index.mjs +11 -11
  64. package/dist/{init-Ce4R0ZGK.mjs → init-LuGxIbQ_.mjs} +1 -1
  65. package/dist/integrations/event-gateway.mjs +2 -2
  66. package/dist/integrations/index.d.mts +2 -2
  67. package/dist/integrations/index.mjs +1 -1
  68. package/dist/integrations/jobs/index.d.mts +1 -1
  69. package/dist/integrations/jobs/index.mjs +2 -2
  70. package/dist/integrations/mcp/index.d.mts +3 -3
  71. package/dist/integrations/mcp/index.mjs +2 -2
  72. package/dist/integrations/mcp/testing.d.mts +1 -1
  73. package/dist/integrations/mcp/testing.mjs +2 -2
  74. package/dist/integrations/streamline.mjs +3 -3
  75. package/dist/integrations/webhooks.d.mts +3 -1
  76. package/dist/integrations/webhooks.mjs +20 -6
  77. package/dist/integrations/websocket-pushref-redis.mjs +1 -1
  78. package/dist/integrations/websocket-redis.mjs +1 -1
  79. package/dist/integrations/websocket.mjs +1 -1
  80. package/dist/{interface-my7sxjw5.mjs → interface-B7awDx3b.mjs} +1 -1
  81. package/dist/{jsonBody-CVKA7C5m.mjs → jsonBody-CiHih3ZU.mjs} +2 -2
  82. package/dist/{keys-GlU7XpmG.mjs → keys-BcNl12HN.mjs} +1 -1
  83. package/dist/{loadResources-DdQb0qgV.mjs → loadResources-DGlfRQc9.mjs} +2 -2
  84. package/dist/{loadResourcesFromEntry-s6aGs6-0.mjs → loadResourcesFromEntry-VYPGSas8.mjs} +2 -2
  85. package/dist/logger/index.mjs +1 -1
  86. package/dist/{mcpPlugin-DkzZ7Nfx.mjs → mcpPlugin-NxSlc-Ks.mjs} +15 -15
  87. package/dist/{memory-BwedEXau.mjs → memory-BU-C-MV3.mjs} +2 -2
  88. package/dist/{metrics-5LNPvL3P.mjs → metrics-7_1GbJpl.mjs} +2 -2
  89. package/dist/middleware/index.d.mts +1 -1
  90. package/dist/middleware/index.mjs +3 -3
  91. package/dist/migrations/index.mjs +2 -2
  92. package/dist/{module-Bh5OC7ww.mjs → module-CQNHzE7g.mjs} +1 -1
  93. package/dist/{multipartBody-DjilSDAT.mjs → multipartBody-Bi5yqW0M.mjs} +1 -1
  94. package/dist/{openapi-ItLH12_L.mjs → openapi-RpNbPBL-.mjs} +6 -6
  95. package/dist/outbox-admin/index.d.mts +1 -1
  96. package/dist/outbox-admin/index.mjs +4 -4
  97. package/dist/{outbox-module-SGIZz6oS.mjs → outbox-module-ClcFrq98.mjs} +4 -4
  98. package/dist/permissions/index.d.mts +2 -2
  99. package/dist/permissions/index.mjs +5 -5
  100. package/dist/{permissions-CpSBlFXZ.mjs → permissions-DgPrZsJh.mjs} +36 -9
  101. package/dist/{pipe-DNOuCfAs.mjs → pipe-Cjy1UiXX.mjs} +2 -2
  102. package/dist/pipeline/index.d.mts +1 -1
  103. package/dist/pipeline/index.mjs +2 -2
  104. package/dist/plugins/index.d.mts +3 -3
  105. package/dist/plugins/index.mjs +16 -16
  106. package/dist/plugins/response-cache.mjs +2 -2
  107. package/dist/plugins/tracing-entry.mjs +2 -2
  108. package/dist/{pluralize-DGAQQKL8.mjs → pluralize-B7m0dPm8.mjs} +1 -1
  109. package/dist/{preloadResources--ZtY9pe9.d.mts → preloadResources-BuutdWgr.d.mts} +1 -1
  110. package/dist/{preloadResources-DYMzmUk1.mjs → preloadResources-CjnW4iIX.mjs} +79 -24
  111. package/dist/presets/filesUpload.d.mts +2 -2
  112. package/dist/presets/filesUpload.mjs +5 -5
  113. package/dist/presets/index.d.mts +2 -2
  114. package/dist/presets/index.mjs +2 -2
  115. package/dist/presets/multiTenant.d.mts +1 -1
  116. package/dist/presets/multiTenant.mjs +3 -3
  117. package/dist/presets/search.d.mts +2 -2
  118. package/dist/presets/search.mjs +2 -2
  119. package/dist/{presets-Bi0Z6Iq8.mjs → presets-CsGg8B58.mjs} +4 -4
  120. package/dist/{projection-aevMua7Q.mjs → projection-koISNyQo.mjs} +2 -2
  121. package/dist/{queryCachePlugin-BI7Z88Cx.mjs → queryCachePlugin-DHueQT9O.mjs} +5 -5
  122. package/dist/{rateLimitKey-pyevMUVf.mjs → rateLimitKey-Bma8VXDO.mjs} +1 -1
  123. package/dist/{realtime-Cfl2bVjj.mjs → realtime-BBoC91Bz.mjs} +9 -9
  124. package/dist/{registerRoute-u1opU66a.mjs → registerRoute-BTgORTlR.mjs} +5 -5
  125. package/dist/registry/index.d.mts +2 -2
  126. package/dist/registry/index.mjs +3 -3
  127. package/dist/{registry-B4sf9Rfm.mjs → registry-BzvRCYS6.mjs} +2 -2
  128. package/dist/{renewingLease-5ESPMxp0.mjs → renewingLease-CgIGh0Ab.mjs} +1 -1
  129. package/dist/{replyHelpers-2jfmMnnV.mjs → replyHelpers-BN16KPHr.mjs} +2 -2
  130. package/dist/{requestContext-DzOUGNdY.mjs → requestContext-B93dmpf0.mjs} +1 -1
  131. package/dist/{rolldown-runtime-CEvvVXTC.mjs → rolldown-runtime-JJWfp8rp.mjs} +1 -1
  132. package/dist/{runtimeCapabilities-BagWc3TI.mjs → runtimeCapabilities-jK99Ciw_.mjs} +1 -1
  133. package/dist/{schedules-BLpZLWGF.mjs → schedules-CKKEL21P.mjs} +3 -3
  134. package/dist/{schemaConverter-D2_bHGil.mjs → schemaConverter-gg0_aUPF.mjs} +1 -1
  135. package/dist/{schemaIR-s3-ouZmP.mjs → schemaIR-CngYvpCF.mjs} +2 -2
  136. package/dist/schemas/index.mjs +1 -1
  137. package/dist/scim/index.mjs +2 -2
  138. package/dist/scope/index.mjs +5 -5
  139. package/dist/{scope-DgepeCv6.mjs → scope-B1RsHdjF.mjs} +4 -4
  140. package/dist/{simpleEqualityMatcher-BO-sFTQf.mjs → simpleEqualityMatcher-_9NAMHUD.mjs} +1 -1
  141. package/dist/{sse-DUIP1XH6.mjs → sse-Bxt03Hk5.mjs} +5 -5
  142. package/dist/{sseStream-ByFGyIVr.mjs → sseStream-BMHTLlhR.mjs} +2 -2
  143. package/dist/{store-helpers-kIJCY0wI.mjs → store-helpers-Brt8OxWZ.mjs} +1 -1
  144. package/dist/{streaming-DOpZVht6.mjs → streaming-CiTJW8kZ.mjs} +1 -1
  145. package/dist/{subscribe-helpers-Dh2BnzJf.mjs → subscribe-helpers-B4fNHRNc.mjs} +11 -5
  146. package/dist/sync/changelog.mjs +1 -1
  147. package/dist/testing/cleanupStoreContract.mjs +1 -1
  148. package/dist/testing/index.d.mts +3 -3
  149. package/dist/testing/index.mjs +10 -10
  150. package/dist/testing/outboxStoreContract.mjs +1 -1
  151. package/dist/testing/storageContract.mjs +1 -1
  152. package/dist/{transactionContext-BTZzEcRo.mjs → transactionContext-D2HwJM2z.mjs} +1 -1
  153. package/dist/{typeGuards-B-_jqaMi.mjs → typeGuards-IE1laMDf.mjs} +1 -1
  154. package/dist/types/index.d.mts +2 -2
  155. package/dist/types/index.mjs +1 -1
  156. package/dist/types/storage.mjs +1 -1
  157. package/dist/{types-GY4kATJb.mjs → types-B8lwJv9Q.mjs} +4 -4
  158. package/dist/{types-DSvHH0uR.d.mts → types-BXnTOsXP.d.mts} +1 -1
  159. package/dist/usage/index.d.mts +1 -1
  160. package/dist/usage/index.mjs +0 -0
  161. package/dist/{userHelpers-AKcB4V03.mjs → userHelpers-xQAi5bPF.mjs} +1 -1
  162. package/dist/utils/index.d.mts +2 -2
  163. package/dist/utils/index.mjs +11 -11
  164. package/dist/{utils-CBK9HQOI.mjs → utils-DgNFsJ2c.mjs} +3 -3
  165. package/dist/{validate-dosAIvQU.mjs → validate-DI3L5V9w.mjs} +2 -2
  166. package/dist/{versioning-BbTs4pwM.mjs → versioning-COpAyfpZ.mjs} +3 -3
  167. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
2
- import { t as startRenewingLease } from "../renewingLease-5ESPMxp0.mjs";
1
+ /*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
2
+ import { t as startRenewingLease } from "../renewingLease-CgIGh0Ab.mjs";
3
3
  import { createHash, randomUUID } from "node:crypto";
4
4
  //#region src/migrations/index.ts
5
5
  /**
@@ -1,4 +1,4 @@
1
- /*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
2
2
  //#region src/factory/module/index.ts
3
3
  /**
4
4
  * Identity helper for authoring a typed module — mirrors `defineResource`.
@@ -1,4 +1,4 @@
1
- /*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
2
2
  import sjson from "secure-json-parse";
3
3
  //#region src/middleware/multipartBody.ts
4
4
  const DEFAULT_MAX_FILE_SIZE = 10485760;
@@ -1,9 +1,9 @@
1
- /*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
2
- import { n as getUserRoles } from "./userHelpers-AKcB4V03.mjs";
3
- import { n as convertRouteSchema } from "./schemaConverter-D2_bHGil.mjs";
4
- import { t as resolveActionPermission } from "./actionPermissions-LFuOra7W.mjs";
5
- import { t as pluralize } from "./pluralize-DGAQQKL8.mjs";
6
- import { t as buildActionBodySchema } from "./createActionRouter-EYWgd0ly.mjs";
1
+ /*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
2
+ import { n as getUserRoles } from "./userHelpers-xQAi5bPF.mjs";
3
+ import { n as convertRouteSchema } from "./schemaConverter-gg0_aUPF.mjs";
4
+ import { t as resolveActionPermission } from "./actionPermissions-D97DniUQ.mjs";
5
+ import { t as pluralize } from "./pluralize-B7m0dPm8.mjs";
6
+ import { t as buildActionBodySchema } from "./createActionRouter-CZz6JO93.mjs";
7
7
  import fp from "fastify-plugin";
8
8
  //#region src/docs/openapi/canonical-schemas.ts
9
9
  /**
@@ -1,5 +1,5 @@
1
1
 
2
- import { l as PermissionCheck } from "../base-GZU3LlzP.mjs";
2
+ import { l as PermissionCheck } from "../base-C-NL2fTi.mjs";
3
3
  import { t as ArcModule } from "../types-DDD5RKTu.mjs";
4
4
  import { OutboxStore } from "@classytic/primitives/outbox";
5
5
  //#region src/outbox-admin/module.d.ts
@@ -1,7 +1,7 @@
1
- /*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
2
- import { i as NotFoundError, u as ValidationError } from "../errors-CLid6atr.mjs";
3
- import { t as defineResource } from "../defineResource-BOrGeocE.mjs";
4
- import { n as getModuleExports, t as defineModule } from "../module-Bh5OC7ww.mjs";
1
+ /*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
2
+ import { i as NotFoundError, u as ValidationError } from "../errors-DDKni6Tz.mjs";
3
+ import { t as defineResource } from "../defineResource-DWzjyxb2.mjs";
4
+ import { n as getModuleExports, t as defineModule } from "../module-CQNHzE7g.mjs";
5
5
  //#region src/outbox-admin/module.ts
6
6
  /**
7
7
  * Strip the domain payload and the stack unless explicitly opted in.
@@ -1,7 +1,7 @@
1
- /*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
2
- import { t as transactionContext } from "./transactionContext-BTZzEcRo.mjs";
3
- import { i as resolveEventTransport } from "./EventTransport-BrPeGUil.mjs";
4
- import { n as createSafeGetOne, t as createIsDuplicateKeyError } from "./store-helpers-kIJCY0wI.mjs";
1
+ /*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
2
+ import { t as transactionContext } from "./transactionContext-D2HwJM2z.mjs";
3
+ import { i as resolveEventTransport } from "./EventTransport-D23Uvhg4.mjs";
4
+ import { n as createSafeGetOne, t as createIsDuplicateKeyError } from "./store-helpers-Brt8OxWZ.mjs";
5
5
  import { and, anyOf, eq, lte, ne, or } from "@classytic/repo-core/filter";
6
6
  import { randomBytes } from "node:crypto";
7
7
  import { InvalidOutboxEventError, OutboxOwnershipError } from "@classytic/primitives/outbox";
@@ -1,5 +1,5 @@
1
1
 
2
- import { c as DataPolicy, d as UserBase, l as PermissionCheck, m as normalizeRoles, p as getUserRoles, s as AuthorizationDecision, u as PermissionContext } from "../base-GZU3LlzP.mjs";
2
+ import { c as DataPolicy, d as UserBase, l as PermissionCheck, m as normalizeRoles, p as getUserRoles, s as AuthorizationDecision, u as PermissionContext } from "../base-C-NL2fTi.mjs";
3
3
  import { a as applyFieldWritePermissions, i as applyFieldReadPermissions, n as FieldPermissionMap, o as fields, r as FieldPermissionType, s as resolveEffectiveRoles, t as FieldPermission } from "../fields-I_EeRWND.mjs";
4
- import { $ as requireAuth, A as RequireGrantOptions, B as ConnectEventsOptions, C as requireServiceScope, D as GRANT_MODES, E as createRoleHierarchy, F as PermissionRequirement, G as createOrgPermissions, H as DynamicPermissionMatrixConfig, I as collectPublicSurface, J as allowPublic, K as allOf, L as describePermission, M as requireGrant, N as conjoinPolicyFilters, O as GrantMode, P as AccessExplanation, Q as not, R as describePermissionMap, S as requireScopeContext, T as RoleHierarchy, U as PermissionEventBus, V as DynamicPermissionMatrix, W as createDynamicPermissionMatrix, X as deny, Y as anyOf, Z as denyAll, _ as publicReadAdminWrite, a as PermissionMatrixRegistry, at as scopeOf, b as requireOrgMembership, c as introspectModule, ct as evaluatePermissionDecision, d as authenticated, dt as RequireMandateOptions, et as requireOwnership, f as fullPublic, ft as requireAgentScope, g as publicRead, h as presets_d_exports, i as PermissionMatrixOptions, it as when, j as modeSatisfies, k as GrantResolution, l as introspectRegistry, lt as normalizeToDecision, m as permissionMatrix, mt as requireMandate, n as PermissionEntryType, nt as requireRoles, o as buildPermissionMatrix, ot as PermissionCheckReturn, p as ownerWithAdminBypass, pt as requireDPoP, q as allow, r as PermissionMatrix, rt as roles, s as introspectCheck, st as applyAuthorizationDecision, t as PermissionEntry, tt as requirePlatformRole, u as adminOnly, ut as RequireAgentScopeOptions, v as readOnly, w as requireTeamMembership, x as requireOrgRole, y as requireOrgInScope, z as explainAccess } from "../index-K7auNNW0.mjs";
4
+ import { $ as requireAuth, A as RequireGrantOptions, B as ConnectEventsOptions, C as requireServiceScope, D as GRANT_MODES, E as createRoleHierarchy, F as PermissionRequirement, G as createOrgPermissions, H as DynamicPermissionMatrixConfig, I as collectPublicSurface, J as allowPublic, K as allOf, L as describePermission, M as requireGrant, N as conjoinPolicyFilters, O as GrantMode, P as AccessExplanation, Q as not, R as describePermissionMap, S as requireScopeContext, T as RoleHierarchy, U as PermissionEventBus, V as DynamicPermissionMatrix, W as createDynamicPermissionMatrix, X as deny, Y as anyOf, Z as denyAll, _ as publicReadAdminWrite, a as PermissionMatrixRegistry, at as scopeOf, b as requireOrgMembership, c as introspectModule, ct as evaluatePermissionDecision, d as authenticated, dt as RequireMandateOptions, et as requireOwnership, f as fullPublic, ft as requireAgentScope, g as publicRead, h as presets_d_exports, i as PermissionMatrixOptions, it as when, j as modeSatisfies, k as GrantResolution, l as introspectRegistry, lt as normalizeToDecision, m as permissionMatrix, mt as requireMandate, n as PermissionEntryType, nt as requireRoles, o as buildPermissionMatrix, ot as PermissionCheckReturn, p as ownerWithAdminBypass, pt as requireDPoP, q as allow, r as PermissionMatrix, rt as roles, s as introspectCheck, st as applyAuthorizationDecision, t as PermissionEntry, tt as requirePlatformRole, u as adminOnly, ut as RequireAgentScopeOptions, v as readOnly, w as requireTeamMembership, x as requireOrgRole, y as requireOrgInScope, z as explainAccess } from "../index-BtYoMip1.mjs";
5
5
  export { type AccessExplanation, type AuthorizationDecision, type ConnectEventsOptions, type DataPolicy, type DynamicPermissionMatrix, type DynamicPermissionMatrixConfig, type FieldPermission, type FieldPermissionMap, type FieldPermissionType, GRANT_MODES, type GrantMode, type GrantResolution, type PermissionCheck, type PermissionCheckReturn, type PermissionContext, type PermissionEntry, type PermissionEntryType, type PermissionEventBus, type PermissionMatrix, type PermissionMatrixOptions, type PermissionMatrixRegistry, type PermissionRequirement, type RequireAgentScopeOptions, type RequireGrantOptions, type RequireMandateOptions, type RoleHierarchy, type UserBase, 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_d_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,6 +1,6 @@
1
- /*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
2
- import { a as conjoinPolicyFilters, i as normalizeToDecision, r as evaluatePermissionDecision, t as applyAuthorizationDecision } from "../authorizationDecision-DYXBBgtg.mjs";
3
- import { n as getUserRoles, r as normalizeRoles } from "../userHelpers-AKcB4V03.mjs";
4
- import { i as resolveEffectiveRoles, n as applyFieldWritePermissions, r as fields, t as applyFieldReadPermissions } from "../fields-UtpiJO5R.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-CpSBlFXZ.mjs";
1
+ /*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
2
+ import { a as conjoinPolicyFilters, i as normalizeToDecision, r as evaluatePermissionDecision, t as applyAuthorizationDecision } from "../authorizationDecision-EsiY3nUu.mjs";
3
+ import { n as getUserRoles, r as normalizeRoles } from "../userHelpers-xQAi5bPF.mjs";
4
+ import { i as resolveEffectiveRoles, n as applyFieldWritePermissions, r as fields, t as applyFieldReadPermissions } from "../fields-DdP225wt.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-DgPrZsJh.mjs";
6
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.35.0 | MIT | https://classytic.com */
2
- import { t as __exportAll } from "./rolldown-runtime-CEvvVXTC.mjs";
1
+ /*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
2
+ import { t as __exportAll } from "./rolldown-runtime-JJWfp8rp.mjs";
3
3
  import { arcLog } from "./logger/index.mjs";
4
- import { a as conjoinPolicyFilters, i as normalizeToDecision } from "./authorizationDecision-DYXBBgtg.mjs";
5
- import { n as getUserRoles } from "./userHelpers-AKcB4V03.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-GY4kATJb.mjs";
7
- import { t as MemoryCacheStore } from "./memory-BwedEXau.mjs";
4
+ import { a as conjoinPolicyFilters, i as normalizeToDecision } from "./authorizationDecision-EsiY3nUu.mjs";
5
+ import { n as getUserRoles } from "./userHelpers-xQAi5bPF.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-B8lwJv9Q.mjs";
7
+ import { t as MemoryCacheStore } from "./memory-BU-C-MV3.mjs";
8
8
  import { randomUUID } from "node:crypto";
9
9
  //#region src/permissions/context.ts
10
10
  /**
@@ -260,7 +260,8 @@ function allOf(...checks) {
260
260
  });
261
261
  };
262
262
  const roleBranches = checks.filter((c) => (c._roles?.length ?? 0) > 0 || (c._orgRoles?.length ?? 0) > 0);
263
- if (checks.length > 0 && checks.every((c) => c._isPublic)) check._isPublic = true;
263
+ if (checks.some((c) => c._isDenied)) check._isDenied = true;
264
+ else if (checks.length > 0 && checks.every((c) => c._isPublic)) check._isPublic = true;
264
265
  else if (roleBranches.length === 1) {
265
266
  const [rb] = roleBranches;
266
267
  if (rb?._roles?.length) check._roles = [...rb._roles];
@@ -300,7 +301,8 @@ function anyOf(...checks) {
300
301
  }
301
302
  return deny(reasons.join("; "));
302
303
  };
303
- if (checks.some((c) => c._isPublic)) check._isPublic = true;
304
+ if (checks.length > 0 && checks.every((c) => c._isDenied)) check._isDenied = true;
305
+ else if (checks.some((c) => c._isPublic)) check._isPublic = true;
304
306
  else if (checks.every((c) => (c._roles?.length ?? 0) > 0 || (c._orgRoles?.length ?? 0) > 0)) {
305
307
  const roles = /* @__PURE__ */ new Set();
306
308
  const orgRoles = /* @__PURE__ */ new Set();
@@ -344,7 +346,16 @@ function not(check, reason = "Access denied") {
344
346
  * ```
345
347
  */
346
348
  function denyAll(reason = "Access denied") {
347
- return () => deny(reason);
349
+ const check = () => deny(reason);
350
+ /**
351
+ * MARKED, not bare. Introspection (`describePermission`) reads metadata, and a
352
+ * closure with none fell through to `{ kind: "authenticated" }` — publishing
353
+ * the library's most restrictive gate as "any signed-in user may do this".
354
+ * Enforcement was never wrong; the description was, in the direction that
355
+ * makes a UI offer an action nobody can perform.
356
+ */
357
+ check._isDenied = true;
358
+ return check;
348
359
  }
349
360
  /**
350
361
  * Dynamic permission based on a condition function.
@@ -1068,6 +1079,7 @@ function createDynamicPermissionMatrix(config) {
1068
1079
  * fully captured statically carries `conditional: true` (see `_conditional`).
1069
1080
  */
1070
1081
  function describePermission(check) {
1082
+ if (check._isDenied) return { kind: "denied" };
1071
1083
  if (check._isPublic) return { kind: "public" };
1072
1084
  const roles = [...check._roles ?? [], ...check._orgRoles ?? []];
1073
1085
  const scope = check._scopeContext;
@@ -1100,6 +1112,17 @@ function describePermission(check) {
1100
1112
  */
1101
1113
  function explainAccess(check, principal) {
1102
1114
  const requirement = describePermission(check);
1115
+ /**
1116
+ * DEFINITIVE, and checked before everything else. `denyAll()` is the one gate
1117
+ * whose answer needs no principal and no request — reporting it as
1118
+ * `conditional` (which "authenticated" does) tells a UI to render the action
1119
+ * and find out later, and later is a 403 the user cannot act on.
1120
+ */
1121
+ if (requirement.kind === "denied") return {
1122
+ decision: "deny",
1123
+ reason: "denied to everyone",
1124
+ requirement
1125
+ };
1103
1126
  if (requirement.kind === "public") return {
1104
1127
  decision: "allow",
1105
1128
  reason: "public — no authentication required",
@@ -1594,6 +1617,10 @@ function introspectCheck(check) {
1594
1617
  roles: req.roles ? [...req.roles] : [],
1595
1618
  scope: { ...req.scope }
1596
1619
  };
1620
+ if (req.kind === "denied") return {
1621
+ type: "denied",
1622
+ roles: []
1623
+ };
1597
1624
  return {
1598
1625
  type: "authenticated",
1599
1626
  roles: []
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
2
- import { r as ForbiddenError } from "./errors-CLid6atr.mjs";
1
+ /*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
2
+ import { r as ForbiddenError } from "./errors-DDKni6Tz.mjs";
3
3
  //#region src/pipeline/pipe.ts
4
4
  /**
5
5
  * Compose pipeline steps into an ordered array.
@@ -1,5 +1,5 @@
1
1
 
2
- import { Ct as PipelineStep, Fn as IControllerResponse, St as PipelineContext, _t as Guard, bt as OperationFilter, vt as Interceptor, wt as Transform, xt as PipelineConfig, yt as NextFunction } from "../index-C5K78SXo.mjs";
2
+ import { Ct as PipelineStep, Fn as IControllerResponse, St as PipelineContext, _t as Guard, bt as OperationFilter, vt as Interceptor, wt as Transform, xt as PipelineConfig, yt as NextFunction } from "../index-C01wWGJt.mjs";
3
3
  //#region src/pipeline/guard.d.ts
4
4
  interface GuardOptions {
5
5
  operations?: OperationFilter;
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
2
- import { n as pipe, t as executePipeline } from "../pipe-DNOuCfAs.mjs";
1
+ /*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
2
+ import { n as pipe, t as executePipeline } from "../pipe-Cjy1UiXX.mjs";
3
3
  //#region src/pipeline/guard.ts
4
4
  /**
5
5
  * Create a named guard.
@@ -1,9 +1,9 @@
1
1
 
2
- import { t as AnyRecord } from "../base-GZU3LlzP.mjs";
3
- import { At as RouteDefinition, J as PresetHook, Q as MiddlewareConfig, et as RouteSchemaOptions } from "../index-C5K78SXo.mjs";
2
+ import { t as AnyRecord } from "../base-C-NL2fTi.mjs";
3
+ import { At as RouteDefinition, J as PresetHook, Q as MiddlewareConfig, et as RouteSchemaOptions } from "../index-C01wWGJt.mjs";
4
4
  import { i as errorHandlerPlugin, n as ErrorMapper, r as defaultIsDuplicateKeyError, t as ErrorHandlerOptions } from "../errorHandler-DI5AN2b5.mjs";
5
5
  import { _ as HealthCheck, b as healthPlugin, f as ScheduleDefinition, g as schedulesPlugin, h as _default$8, m as SchedulesPluginOptions, p as ScheduleStats, v as HealthOptions, y as _default$3 } from "../types-DDD5RKTu.mjs";
6
- import { a as arcCorePlugin, i as _default, n as ArcCorePluginOptions, r as PluginMeta, t as ArcCore } from "../fastify-augmentation-CMMTL3cj.mjs";
6
+ import { a as arcCorePlugin, i as _default, n as ArcCorePluginOptions, r as PluginMeta, t as ArcCore } from "../fastify-augmentation-Bk_9PoiV.mjs";
7
7
  import { _ as CachingRule, a as MetricsCollector, c as metricsPlugin, d as _default$6, f as realtimePlugin, g as CachingOptions, h as ssePlugin, i as MetricEntry, l as ChangeOperation, m as _default$9, n as _default$10, 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-DEs-_hFi.mjs";
8
8
  import { t as TracingOptions } from "../tracing-Dro5eH6j.mjs";
9
9
  import { PaginatedResult } from "@classytic/repo-core/pagination";
@@ -1,20 +1,20 @@
1
- /*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
2
- import { p as MUTATION_OPERATIONS } from "../constants-BhzLXCfN.mjs";
1
+ /*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
2
+ import { p as MUTATION_OPERATIONS } from "../constants-DUoKAGYD.mjs";
3
3
  import { arcLog } from "../logger/index.mjs";
4
- import { c as getOrgId } from "../types-GY4kATJb.mjs";
5
- import { n as requestContext } from "../requestContext-DzOUGNdY.mjs";
6
- import { t as hasEvents } from "../typeGuards-B-_jqaMi.mjs";
7
- import { t as HookSystem } from "../HookSystem-LlPm3Anm.mjs";
8
- import { t as ResourceRegistry } from "../ResourceRegistry-yuD1Ra53.mjs";
9
- import { a as requestIdPlugin, i as createRequestIdGenerator, n as health_default, o as requestId_default, s as sanitizeRequestId, t as healthPlugin } from "../health-_Zs3R_Sb.mjs";
10
- import { n as caching_default, t as cachingPlugin } from "../caching-cN5X9VEL.mjs";
11
- import { n as errorHandlerPlugin, t as defaultIsDuplicateKeyError } from "../errorHandler-BbQ1nQdk.mjs";
12
- import { n as metrics_default, t as metricsPlugin } from "../metrics-5LNPvL3P.mjs";
13
- import { n as realtime_default, t as realtimePlugin } from "../realtime-Cfl2bVjj.mjs";
14
- import { t as replyHelpersPlugin } from "../replyHelpers-2jfmMnnV.mjs";
15
- import { n as schedules_default, t as schedulesPlugin } from "../schedules-BLpZLWGF.mjs";
16
- import { n as sse_default, t as ssePlugin } from "../sse-DUIP1XH6.mjs";
17
- import { n as versioning_default, t as versioningPlugin } from "../versioning-BbTs4pwM.mjs";
4
+ import { c as getOrgId } from "../types-B8lwJv9Q.mjs";
5
+ import { n as requestContext } from "../requestContext-B93dmpf0.mjs";
6
+ import { t as hasEvents } from "../typeGuards-IE1laMDf.mjs";
7
+ import { t as HookSystem } from "../HookSystem-DgwxNZTx.mjs";
8
+ import { t as ResourceRegistry } from "../ResourceRegistry-DNuYVbmv.mjs";
9
+ import { a as requestIdPlugin, i as createRequestIdGenerator, n as health_default, o as requestId_default, s as sanitizeRequestId, t as healthPlugin } from "../health-k6NODS8f.mjs";
10
+ import { n as caching_default, t as cachingPlugin } from "../caching-CP3GLJ7U.mjs";
11
+ import { n as errorHandlerPlugin, t as defaultIsDuplicateKeyError } from "../errorHandler-2RT0hLSI.mjs";
12
+ import { n as metrics_default, t as metricsPlugin } from "../metrics-7_1GbJpl.mjs";
13
+ import { n as realtime_default, t as realtimePlugin } from "../realtime-BBoC91Bz.mjs";
14
+ import { t as replyHelpersPlugin } from "../replyHelpers-BN16KPHr.mjs";
15
+ import { n as schedules_default, t as schedulesPlugin } from "../schedules-CKKEL21P.mjs";
16
+ import { n as sse_default, t as ssePlugin } from "../sse-Bxt03Hk5.mjs";
17
+ import { n as versioning_default, t as versioningPlugin } from "../versioning-COpAyfpZ.mjs";
18
18
  import fp from "fastify-plugin";
19
19
  import { performance as performance$1 } from "node:perf_hooks";
20
20
  //#region src/core/arcCorePlugin.ts
@@ -1,5 +1,5 @@
1
- /*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
2
- import { t as hasEvents } from "../typeGuards-B-_jqaMi.mjs";
1
+ /*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
2
+ import { t as hasEvents } from "../typeGuards-IE1laMDf.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.35.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.36.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.35.0";
62
+ const resolvedVersion = serviceVersion ?? "2.36.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.35.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
2
2
  //#region src/utils/pluralize.ts
3
3
  /**
4
4
  * Lightweight English pluralization for the Arc CLI.
@@ -1,5 +1,5 @@
1
1
 
2
- import { It as Authenticator } from "./index-C5K78SXo.mjs";
2
+ import { It as Authenticator } from "./index-C01wWGJt.mjs";
3
3
  import { r as CacheStore } from "./interface-BOk3YnTz.mjs";
4
4
  import { n as ElevationOptions } from "./elevation-BXCfVcNG.mjs";
5
5
  import { a as EventTransport } from "./EventTransport-BEVP50ka.mjs";
@@ -1,12 +1,12 @@
1
- /*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
2
- import { t as __exportAll } from "./rolldown-runtime-CEvvVXTC.mjs";
1
+ /*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
2
+ import { t as __exportAll } from "./rolldown-runtime-JJWfp8rp.mjs";
3
3
  import { arcLog, configureArcLogger, createPinoWriter, enterArcLoggerScope, runWithArcLogger } from "./logger/index.mjs";
4
- import { n as PUBLIC_SCOPE } from "./types-GY4kATJb.mjs";
5
- import { t as auditRuntimeCapabilities } from "./runtimeCapabilities-BagWc3TI.mjs";
6
- import { t as createTenantKeyGenerator } from "./rateLimitKey-pyevMUVf.mjs";
7
- import { i as createRequestIdGenerator, r as mergeHealthChecks } from "./health-_Zs3R_Sb.mjs";
8
- import { t as parseJsonBody } from "./jsonBody-CVKA7C5m.mjs";
9
- import { r as wrapWithBoundary } from "./subscribe-helpers-Dh2BnzJf.mjs";
4
+ import { n as PUBLIC_SCOPE } from "./types-B8lwJv9Q.mjs";
5
+ import { t as auditRuntimeCapabilities } from "./runtimeCapabilities-jK99Ciw_.mjs";
6
+ import { t as createTenantKeyGenerator } from "./rateLimitKey-Bma8VXDO.mjs";
7
+ import { i as createRequestIdGenerator, r as mergeHealthChecks } from "./health-k6NODS8f.mjs";
8
+ import { t as parseJsonBody } from "./jsonBody-CiHih3ZU.mjs";
9
+ import { r as wrapWithBoundary } from "./subscribe-helpers-B4fNHRNc.mjs";
10
10
  import { isProductionEnv } from "@classytic/primitives/environment";
11
11
  import Fastify from "fastify";
12
12
  import qs from "qs";
@@ -48,6 +48,56 @@ const PLUGIN_REGISTRY = {
48
48
  optional: true
49
49
  }
50
50
  };
51
+ /**
52
+ * Fail ONCE with every missing package, before any plugin registers.
53
+ *
54
+ * Without this the first absent package throws and the operator installs it,
55
+ * restarts, hits the next one, and repeats — six restarts to discover a peer
56
+ * set that was pruned as a unit. These are OPTIONAL peers of arc, so nothing
57
+ * at install or build time says they are gone; the first signal is a boot
58
+ * crash naming exactly one of them.
59
+ *
60
+ * Required-ness is read from `PLUGIN_REGISTRY` (`!optional`), never a second
61
+ * list — a hand-maintained copy is what goes stale the day a plugin is added.
62
+ * Optional plugins are deliberately NOT preflighted: their absence is a
63
+ * supported configuration, and `loadPlugin` already warns and skips.
64
+ *
65
+ * A plugin the host disabled (`{ helmet: false }`) is not checked — refusing to
66
+ * boot over a package for a plugin nobody asked for would be the opposite of
67
+ * helpful.
68
+ */
69
+ async function preflightPlugins(config, options = {}) {
70
+ const { load } = options;
71
+ const required = Object.entries(PLUGIN_REGISTRY).filter(([name, entry]) => !entry.optional && config[name] !== false);
72
+ const results = await Promise.allSettled(required.map(([name, entry]) => load ? load(name) : entry.loader()));
73
+ const missing = [];
74
+ for (const [i, result] of results.entries()) {
75
+ if (result.status === "fulfilled") continue;
76
+ const [name, entry] = required[i];
77
+ if (!isModuleNotFound(result.reason)) throw new Error(`Failed to load plugin '${name}': ${result.reason.message}`);
78
+ missing.push({
79
+ name,
80
+ package: entry.package
81
+ });
82
+ }
83
+ if (missing.length === 0) return;
84
+ const packages = missing.map((m) => m.package);
85
+ throw new Error(`arc cannot start: ${missing.length} required plugin package(s) are not installed.\n` + missing.map((m) => ` - ${m.package} (plugin '${m.name}')`).join("\n") + `\n\nInstall all of them:\n npm install ${packages.join(" ")}\n\nOr disable the plugins you do not need in createApp options: ` + missing.map((m) => `${m.name}: false`).join(", "));
86
+ }
87
+ /** Shared by the preflight and the per-plugin loader so they agree on what "missing" means. */
88
+ function isModuleNotFound(err) {
89
+ /**
90
+ * CODE first, message second. Node sets `ERR_MODULE_NOT_FOUND` (ESM) or
91
+ * `MODULE_NOT_FOUND` (CJS) on a real resolution failure; the message text
92
+ * varies by Node version, loader and bundler, so matching it alone is a
93
+ * predicate that silently stops matching after an upgrade — and this one
94
+ * decides between "install a package" and "your plugin crashed".
95
+ */
96
+ const code = err?.code;
97
+ if (code === "ERR_MODULE_NOT_FOUND" || code === "MODULE_NOT_FOUND") return true;
98
+ const m = err?.message ?? "";
99
+ return m.includes("Cannot find module") || m.includes("Cannot find package") || m.includes("MODULE_NOT_FOUND") || m.includes("Could not resolve");
100
+ }
51
101
  async function loadPlugin(name, logger) {
52
102
  const entry = PLUGIN_REGISTRY[name];
53
103
  if (!entry) throw new Error(`Unknown plugin: ${name}`);
@@ -55,12 +105,12 @@ async function loadPlugin(name, logger) {
55
105
  return await entry.loader();
56
106
  } catch (error) {
57
107
  const err = error;
58
- const isModuleNotFound = err.message.includes("Cannot find module") || err.message.includes("Cannot find package") || err.message.includes("MODULE_NOT_FOUND") || err.message.includes("Could not resolve");
59
- if (isModuleNotFound && entry.optional) {
108
+ const notFound = isModuleNotFound(err);
109
+ if (notFound && entry.optional) {
60
110
  logger?.warn(`Optional plugin '${name}' skipped (${entry.package} not installed)`);
61
111
  return null;
62
112
  }
63
- if (isModuleNotFound) throw new Error(`Plugin '${name}' requires package '${entry.package}' which is not installed.\nInstall it with: npm install ${entry.package}\nOr disable this plugin by setting ${name}: false in createApp options.`);
113
+ if (notFound) throw new Error(`Plugin '${name}' requires package '${entry.package}' which is not installed.\nInstall it with: npm install ${entry.package}\nOr disable this plugin by setting ${name}: false in createApp options.`);
64
114
  throw new Error(`Failed to load plugin '${name}': ${err.message}`);
65
115
  }
66
116
  }
@@ -801,7 +851,7 @@ async function registerArcCore(fastify, config, trackPlugin) {
801
851
  await fastify.register(arcCorePlugin, { emitEvents: config.arcPlugins?.emitEvents !== false });
802
852
  trackPlugin("arc-core");
803
853
  if (config.arcPlugins?.events !== false) {
804
- const { default: eventPlugin } = await import("./eventPlugin-ClPn5kjn.mjs").then((n) => n.n);
854
+ const { default: eventPlugin } = await import("./eventPlugin-c3YwGzz9.mjs").then((n) => n.n);
805
855
  const eventOpts = typeof config.arcPlugins?.events === "object" ? config.arcPlugins.events : {};
806
856
  await fastify.register(eventPlugin, {
807
857
  /**
@@ -860,15 +910,15 @@ async function registerArcPlugins(fastify, config, trackPlugin, modules, moduleH
860
910
  trackPlugin("arc-graceful-shutdown");
861
911
  }
862
912
  if (config.arcPlugins?.caching) {
863
- const { default: cachingPlugin } = await import("./caching-cN5X9VEL.mjs").then((n) => n.r);
913
+ const { default: cachingPlugin } = await import("./caching-CP3GLJ7U.mjs").then((n) => n.r);
864
914
  const opts = config.arcPlugins.caching === true ? {} : config.arcPlugins.caching;
865
915
  await fastify.register(cachingPlugin, opts);
866
916
  trackPlugin("arc-caching", opts);
867
917
  }
868
918
  if (config.arcPlugins?.queryCache) {
869
- const { queryCachePlugin } = await import("./queryCachePlugin-BI7Z88Cx.mjs").then((n) => n.n);
919
+ const { queryCachePlugin } = await import("./queryCachePlugin-DHueQT9O.mjs").then((n) => n.n);
870
920
  const opts = config.arcPlugins.queryCache === true ? {} : config.arcPlugins.queryCache;
871
- const store = config.stores?.queryCache ?? new (await (import("./memory-BwedEXau.mjs").then((n) => n.n))).MemoryCacheStore();
921
+ const store = config.stores?.queryCache ?? new (await (import("./memory-BU-C-MV3.mjs").then((n) => n.n))).MemoryCacheStore();
872
922
  await fastify.register(queryCachePlugin, {
873
923
  store,
874
924
  ...opts
@@ -878,7 +928,7 @@ async function registerArcPlugins(fastify, config, trackPlugin, modules, moduleH
878
928
  if (config.arcPlugins?.sse) {
879
929
  if (config.arcPlugins?.events === false) fastify.log.warn("SSE plugin requires events plugin (arcPlugins.events). SSE disabled.");
880
930
  else {
881
- const { default: ssePlugin } = await import("./sse-DUIP1XH6.mjs").then((n) => n.r);
931
+ const { default: ssePlugin } = await import("./sse-Bxt03Hk5.mjs").then((n) => n.r);
882
932
  const opts = config.arcPlugins.sse === true ? {} : config.arcPlugins.sse;
883
933
  await fastify.register(ssePlugin, opts);
884
934
  trackPlugin("arc-sse", opts);
@@ -887,20 +937,20 @@ async function registerArcPlugins(fastify, config, trackPlugin, modules, moduleH
887
937
  if (config.arcPlugins?.realtime) {
888
938
  if (config.arcPlugins?.events === false) fastify.log.warn("Realtime plugin requires events plugin (arcPlugins.events). Realtime disabled.");
889
939
  else {
890
- const { default: realtimePlugin } = await import("./realtime-Cfl2bVjj.mjs").then((n) => n.r);
940
+ const { default: realtimePlugin } = await import("./realtime-BBoC91Bz.mjs").then((n) => n.r);
891
941
  const opts = config.arcPlugins.realtime === true ? {} : config.arcPlugins.realtime;
892
942
  await fastify.register(realtimePlugin, opts);
893
943
  trackPlugin("arc-realtime", opts);
894
944
  }
895
945
  }
896
946
  if (config.arcPlugins?.metrics) {
897
- const { default: metricsPlugin } = await import("./metrics-5LNPvL3P.mjs").then((n) => n.r);
947
+ const { default: metricsPlugin } = await import("./metrics-7_1GbJpl.mjs").then((n) => n.r);
898
948
  const opts = config.arcPlugins.metrics === true ? {} : config.arcPlugins.metrics;
899
949
  await fastify.register(metricsPlugin, opts);
900
950
  trackPlugin("arc-metrics", opts);
901
951
  }
902
952
  if (config.arcPlugins?.versioning) {
903
- const { default: versioningPlugin } = await import("./versioning-BbTs4pwM.mjs").then((n) => n.r);
953
+ const { default: versioningPlugin } = await import("./versioning-COpAyfpZ.mjs").then((n) => n.r);
904
954
  await fastify.register(versioningPlugin, config.arcPlugins.versioning);
905
955
  trackPlugin("arc-versioning", config.arcPlugins.versioning);
906
956
  }
@@ -977,7 +1027,7 @@ async function registerAuth(fastify, config, trackPlugin) {
977
1027
  */
978
1028
  async function registerElevation(fastify, config, trackPlugin) {
979
1029
  if (!config.elevation) return;
980
- const { elevationPlugin } = await import("./elevation-tGIAldco.mjs").then((n) => n.r);
1030
+ const { elevationPlugin } = await import("./elevation-D_cmo80j.mjs").then((n) => n.r);
981
1031
  await fastify.register(elevationPlugin, config.elevation);
982
1032
  trackPlugin("arc-elevation", config.elevation);
983
1033
  fastify.log.debug("Elevation plugin enabled");
@@ -992,7 +1042,7 @@ async function registerElevation(fastify, config, trackPlugin) {
992
1042
  */
993
1043
  async function registerErrorHandler(fastify, config, trackPlugin, moduleErrorMappers) {
994
1044
  if (config.errorHandler === false) return;
995
- const { errorHandlerPlugin } = await import("./errorHandler-BbQ1nQdk.mjs").then((n) => n.r);
1045
+ const { errorHandlerPlugin } = await import("./errorHandler-2RT0hLSI.mjs").then((n) => n.r);
996
1046
  /**
997
1047
  * DISCLOSURE DEFAULTS MERGE — they used to be REPLACED, and that was two bugs.
998
1048
  *
@@ -1216,7 +1266,7 @@ async function registerResources(fastify, config, preResolvedModules) {
1216
1266
  let discoveryPath;
1217
1267
  let discoveryYieldedZero = false;
1218
1268
  if (resolvedResources === void 0 && config.resourceDir) {
1219
- const { loadResources } = await import("./loadResources-DdQb0qgV.mjs").then((n) => n.n);
1269
+ const { loadResources } = await import("./loadResources-DGlfRQc9.mjs").then((n) => n.n);
1220
1270
  const { resolve, dirname } = await import("node:path");
1221
1271
  const { fileURLToPath } = await import("node:url");
1222
1272
  const rawDir = config.resourceDir;
@@ -1342,7 +1392,7 @@ Resources supplied by "${m.name}": ${provided}.`);
1342
1392
  if (fastify.hasDecorator("getScheduleStats")) throw new Error("[arc] modules declare scheduledJobs but schedulesPlugin was already registered manually. Configure their runner through arcPlugins.schedules so Arc can compose one schedule table.");
1343
1393
  const frozenJobs = Object.freeze(scheduledJobs.map((job) => Object.freeze({ ...job })));
1344
1394
  const scheduleOptions = typeof config.arcPlugins?.schedules === "object" ? config.arcPlugins.schedules : {};
1345
- const { default: schedulesPlugin } = await import("./schedules-BLpZLWGF.mjs").then((n) => n.r);
1395
+ const { default: schedulesPlugin } = await import("./schedules-CKKEL21P.mjs").then((n) => n.r);
1346
1396
  await fastify.register(schedulesPlugin, {
1347
1397
  ...scheduleOptions,
1348
1398
  schedules: frozenJobs
@@ -1552,6 +1602,11 @@ function compilePathMatcher(patterns) {
1552
1602
  * All enabled by default — set to `false` to opt out.
1553
1603
  */
1554
1604
  async function registerSecurityPlugins(fastify, config) {
1605
+ /**
1606
+ * Resolve every enabled plugin's package FIRST, so a pruned peer set is one
1607
+ * error listing all of them rather than one restart per package.
1608
+ */
1609
+ await preflightPlugins(config);
1555
1610
  if (config.helmet !== false) {
1556
1611
  const helmet = await loadPlugin("helmet");
1557
1612
  await fastify.register(helmet, config.helmet ?? {});
@@ -1944,7 +1999,7 @@ async function buildApp(options, loggerScope, onInstance) {
1944
1999
  await registerErrorHandler(fastify, config, trackPlugin, moduleErrorMappers);
1945
2000
  await registerResources(fastify, config, resolvedModules);
1946
2001
  if (config.replyHelpers) {
1947
- const { replyHelpersPlugin } = await import("./replyHelpers-2jfmMnnV.mjs").then((n) => n.n);
2002
+ const { replyHelpersPlugin } = await import("./replyHelpers-BN16KPHr.mjs").then((n) => n.n);
1948
2003
  await fastify.register(replyHelpersPlugin);
1949
2004
  }
1950
2005
  if (config.serializeBigInt) {
@@ -1,7 +1,7 @@
1
1
 
2
2
  import { i as RequestScope } from "../types-Ddl9OjmE.mjs";
3
- import { l as PermissionCheck } from "../base-GZU3LlzP.mjs";
4
- import { Y as PresetResult } from "../index-C5K78SXo.mjs";
3
+ import { l as PermissionCheck } from "../base-C-NL2fTi.mjs";
4
+ import { Y as PresetResult } from "../index-C01wWGJt.mjs";
5
5
  import { a as StorageReadResult, i as StorageReadRange, n as StorageContext, o as StorageUploadInput, r as StorageFile, t as Storage } from "../storage-Cx9Sz3Ou.mjs";
6
6
  //#region src/presets/filesUpload.d.ts
7
7
  interface FilesUploadPresetRoutes {
@@ -1,8 +1,8 @@
1
- /*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
2
- import { i as NotFoundError, u as ValidationError } from "../errors-CLid6atr.mjs";
3
- import { c as getOrgId, g as getUserId } from "../types-GY4kATJb.mjs";
4
- import { B as requireAuth, F as allowPublic } from "../permissions-CpSBlFXZ.mjs";
5
- import { t as multipartBody } from "../multipartBody-DjilSDAT.mjs";
1
+ /*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
2
+ import { i as NotFoundError, u as ValidationError } from "../errors-DDKni6Tz.mjs";
3
+ import { c as getOrgId, g as getUserId } from "../types-B8lwJv9Q.mjs";
4
+ import { B as requireAuth, F as allowPublic } from "../permissions-DgPrZsJh.mjs";
5
+ import { t as multipartBody } from "../multipartBody-Bi5yqW0M.mjs";
6
6
  //#region src/presets/filesUpload.ts
7
7
  const DEFAULT_FIELD_NAME = "file";
8
8
  const DEFAULT_MAX_FILE_SIZE = 10485760;
@@ -1,6 +1,6 @@
1
1
 
2
- import { t as AnyRecord } from "../base-GZU3LlzP.mjs";
3
- import { Fn as IControllerResponse, In as IRequestContext, U as ResourceConfig, Y as PresetResult, d as PaginationResult } from "../index-C5K78SXo.mjs";
2
+ import { t as AnyRecord } from "../base-C-NL2fTi.mjs";
3
+ import { Fn as IControllerResponse, In as IRequestContext, U as ResourceConfig, Y as PresetResult, d as PaginationResult } from "../index-C01wWGJt.mjs";
4
4
  import { FilesUploadPresetOptions, FilesUploadPresetPermissions, FilesUploadPresetRoutes, filesUploadPreset } from "./filesUpload.mjs";
5
5
  import { MultiTenantOptions, TenantFieldSpec, multiTenantPreset } from "./multiTenant.mjs";
6
6
  import { SearchHandler, SearchPresetOptions, SearchRouteConfig, searchPreset } from "./search.mjs";
@@ -1,6 +1,6 @@
1
- /*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
1
+ /*! @classytic/arc v2.36.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-Bi0Z6Iq8.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-CsGg8B58.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,5 +1,5 @@
1
1
 
2
- import { X as CrudRouteKey, Y as PresetResult } from "../index-C5K78SXo.mjs";
2
+ import { X as CrudRouteKey, Y as PresetResult } from "../index-C01wWGJt.mjs";
3
3
  //#region src/presets/multiTenant.d.ts
4
4
  /**
5
5
  * One tenant dimension for multi-field filtering. Discriminated by source:
@@ -1,6 +1,6 @@
1
- /*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
2
- import "../constants-BhzLXCfN.mjs";
3
- import { b as isElevated, c as getOrgId, d as getScopeContext, m as getTeamId, u as getRequestScope, v as hasOrgAccess } from "../types-GY4kATJb.mjs";
1
+ /*! @classytic/arc v2.36.0 | MIT | https://classytic.com */
2
+ import "../constants-DUoKAGYD.mjs";
3
+ import { b as isElevated, c as getOrgId, d as getScopeContext, m as getTeamId, u as getRequestScope, v as hasOrgAccess } from "../types-B8lwJv9Q.mjs";
4
4
  //#region src/presets/multiTenant.ts
5
5
  /**
6
6
  * Resolve a single TenantFieldSpec against the current scope.
@@ -1,6 +1,6 @@
1
1
 
2
- import { l as PermissionCheck } from "../base-GZU3LlzP.mjs";
3
- import { At as RouteDefinition, Y as PresetResult, jn as ControllerHandler, jt as RouteMcpConfig } from "../index-C5K78SXo.mjs";
2
+ import { l as PermissionCheck } from "../base-C-NL2fTi.mjs";
3
+ import { At as RouteDefinition, Y as PresetResult, jn as ControllerHandler, jt as RouteMcpConfig } from "../index-C01wWGJt.mjs";
4
4
  //#region src/presets/search.d.ts
5
5
  /**
6
6
  * Search Preset — backend-agnostic search / vector / embed routes