@classytic/arc 2.20.0 → 2.21.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 (111) hide show
  1. package/dist/{BaseController-D-MHZ27_.mjs → BaseController-BnLYgE9A.mjs} +2 -2
  2. package/dist/{EventTransport-IEn7Tn-Q.d.mts → EventTransport-QmY7A258.d.mts} +0 -1
  3. package/dist/{QueryCache-TRfXau3W.d.mts → QueryCache-Z1B38koh.d.mts} +0 -1
  4. package/dist/{actionPermissions-C9RMiIpc.mjs → actionPermissions-ze70xXJi.mjs} +1 -1
  5. package/dist/audit/index.d.mts +9 -5
  6. package/dist/auth/audit.d.mts +7 -4
  7. package/dist/auth/audit.mjs +5 -0
  8. package/dist/auth/index.d.mts +7 -14
  9. package/dist/auth/index.mjs +1 -1
  10. package/dist/auth/redis-session.d.mts +1 -2
  11. package/dist/cache/index.d.mts +2 -3
  12. package/dist/cli/commands/describe.d.mts +1 -2
  13. package/dist/cli/commands/docs.mjs +1 -1
  14. package/dist/cli/commands/init.mjs +1 -1
  15. package/dist/cli/index.mjs +1 -1
  16. package/dist/context/index.d.mts +2 -2
  17. package/dist/core/index.d.mts +3 -3
  18. package/dist/core/index.mjs +4 -4
  19. package/dist/{core-CWhyGkiM.mjs → core-DZ6Xe1jR.mjs} +65 -10
  20. package/dist/{createActionRouter-HlQso0jO.mjs → createActionRouter-BWMDW-dL.mjs} +2 -2
  21. package/dist/{createAggregationRouter-5LzPzgw1.mjs → createAggregationRouter-l5mNdYrZ.mjs} +1 -1
  22. package/dist/{createApp-D6uwzCKu.mjs → createApp-Bi61XxqU.mjs} +149 -137
  23. package/dist/discovery/index.d.mts +0 -1
  24. package/dist/docs/index.d.mts +1 -2
  25. package/dist/docs/index.mjs +1 -1
  26. package/dist/{elevation-xGUBq6p_.d.mts → elevation-C9s5hFP_.d.mts} +0 -1
  27. package/dist/encryption/index.d.mts +2 -144
  28. package/dist/{errorHandler-BtUUDPEa.d.mts → errorHandler-B0e-bq-O.d.mts} +0 -1
  29. package/dist/{errors-DOHkjQlD.d.mts → errors-DHcHVAgk.d.mts} +0 -1
  30. package/dist/{eventPlugin-DbBFd3x_.d.mts → eventPlugin-A6EbthXR.d.mts} +10 -6
  31. package/dist/events/index.d.mts +9 -6
  32. package/dist/events/transports/redis-stream-entry.d.mts +1 -1
  33. package/dist/events/transports/redis.d.mts +1 -2
  34. package/dist/factory/index.d.mts +4 -4
  35. package/dist/factory/index.mjs +2 -2
  36. package/dist/{fastify-augmentation-CCQJEDgh.d.mts → fastify-augmentation-DafigGQp.d.mts} +2 -3
  37. package/dist/{fields-C7ahdGYf.d.mts → fields-BGqrAa_u.d.mts} +1 -2
  38. package/dist/hooks/index.d.mts +1 -1
  39. package/dist/idempotency/index.d.mts +4 -3
  40. package/dist/idempotency/redis.d.mts +1 -1
  41. package/dist/{index-DUa8WHz3.d.mts → index-B5N-NaHs.d.mts} +88 -7
  42. package/dist/{index-CdFkIMEd.d.mts → index-B5PoNbfu.d.mts} +36 -7
  43. package/dist/{index-_--GyzcO.d.mts → index-Dtrj6XZk.d.mts} +62 -28
  44. package/dist/index.d.mts +7 -7
  45. package/dist/index.mjs +6 -6
  46. package/dist/{init-YH_nslQR.mjs → init-0YhHkXGk.mjs} +154 -137
  47. package/dist/integrations/event-gateway.d.mts +2 -3
  48. package/dist/integrations/index.d.mts +2 -2
  49. package/dist/integrations/jobs.d.mts +0 -1
  50. package/dist/integrations/mcp/index.d.mts +6 -7
  51. package/dist/integrations/mcp/index.mjs +1 -1
  52. package/dist/integrations/mcp/testing.d.mts +1 -2
  53. package/dist/integrations/mcp/testing.mjs +1 -1
  54. package/dist/integrations/streamline.d.mts +2 -2
  55. package/dist/integrations/webhooks.d.mts +0 -1
  56. package/dist/integrations/websocket-pushref-redis.d.mts +1 -2
  57. package/dist/integrations/websocket-redis.d.mts +1 -2
  58. package/dist/integrations/websocket.d.mts +2 -2
  59. package/dist/{loadResources-B8UmpITt.mjs → loadResources-DpU8pfjV.mjs} +4 -3
  60. package/dist/{mcpPlugin-CuW6L_uD.mjs → mcpPlugin-B9XjjNVG.mjs} +3 -3
  61. package/dist/middleware/index.d.mts +1 -2
  62. package/dist/{module-JYH9V0I8.d.mts → module-WeuU5jfd.d.mts} +46 -1
  63. package/dist/{openapi-Dq6RbEGK.mjs → openapi-Kyod_di6.mjs} +2 -2
  64. package/dist/permissions/index.d.mts +3 -3
  65. package/dist/permissions/index.mjs +2 -2
  66. package/dist/{permissions-CgbOLJZG.mjs → permissions-BJMuKMl7.mjs} +33 -1
  67. package/dist/pipeline/index.d.mts +1 -2
  68. package/dist/plugins/index.d.mts +79 -7
  69. package/dist/plugins/index.mjs +88 -1
  70. package/dist/plugins/response-cache.d.mts +5 -3
  71. package/dist/plugins/tracing-entry.d.mts +1 -1
  72. package/dist/plugins/tracing-entry.mjs +1 -1
  73. package/dist/presets/filesUpload.d.mts +4 -5
  74. package/dist/presets/filesUpload.mjs +1 -1
  75. package/dist/presets/index.d.mts +1 -2
  76. package/dist/presets/index.mjs +1 -1
  77. package/dist/presets/multiTenant.d.mts +1 -2
  78. package/dist/presets/search.d.mts +2 -3
  79. package/dist/presets/search.mjs +1 -1
  80. package/dist/{presets-DWsYQdbV.mjs → presets-gw0ciIUD.mjs} +1 -1
  81. package/dist/{pushref-registry-DnCqL3aa.d.mts → pushref-registry-BbcnpNTm.d.mts} +4 -2
  82. package/dist/{queryCachePlugin-xzFyKAjT.d.mts → queryCachePlugin-CfYWq-Ak.d.mts} +1 -2
  83. package/dist/{redis-C3W0qbz8.d.mts → redis-UDtLaNj6.d.mts} +0 -1
  84. package/dist/{redis-stream-DsP1vqZB.d.mts → redis-stream-iVR2l7aS.d.mts} +1 -2
  85. package/dist/{registerRoute-DGSREwPw.mjs → registerRoute-oGAl0oA8.mjs} +1 -1
  86. package/dist/registry/index.d.mts +2 -2
  87. package/dist/schemas/index.d.mts +0 -1
  88. package/dist/scim/index.d.mts +0 -1
  89. package/dist/scope/index.d.mts +2 -3
  90. package/dist/{sessionManager-BXG-HGwG.d.mts → sessionManager-BHOM3N_0.d.mts} +10 -6
  91. package/dist/{storage-Co_PQpeQ.d.mts → storage-DLUZ04kK.d.mts} +8 -4
  92. package/dist/testing/index.d.mts +2 -3
  93. package/dist/testing/index.mjs +5 -2
  94. package/dist/testing/storageContract.d.mts +1 -2
  95. package/dist/{tracing-D8jlGXP7.d.mts → tracing-CsGKQJGg.d.mts} +0 -1
  96. package/dist/types/index.d.mts +4 -4
  97. package/dist/types/storage.d.mts +1 -1
  98. package/dist/types-Cc91nXuA.d.mts +132 -0
  99. package/dist/{types-LNebCoJx.d.mts → types-DH0GupI7.d.mts} +8 -4
  100. package/dist/{types-C9b2HR5W.d.mts → types-DRj-Ut4n.d.mts} +1 -2
  101. package/dist/{types-BHMKlMBU.d.mts → types-DpxoNX5v.d.mts} +61 -21
  102. package/dist/utils/index.d.mts +182 -128
  103. package/dist/utils/index.mjs +2 -2
  104. package/dist/{utils-ChjYQpjn.mjs → utils-CO8a3B_1.mjs} +70 -26
  105. package/dist/{versioning-D_eBCfNr.d.mts → versioning-DQ4mCvg0.d.mts} +1 -2
  106. package/dist/{websocket-MlYlrYq0.d.mts → websocket-uuWqM6UY.d.mts} +5 -4
  107. package/package.json +7 -7
  108. package/skills/arc-module-publishing/SKILL.md +242 -0
  109. package/skills/arc-module-publishing/references/authoring-modules.md +272 -0
  110. package/skills/arc-module-publishing/references/package-manifest.md +155 -0
  111. package/skills/arc-module-publishing/references/publishing-workflow.md +182 -0
@@ -1,6 +1,5 @@
1
- import { I as MiddlewareHandler, L as RequestWithExtras, Q as MiddlewareConfig } from "../index-_--GyzcO.mjs";
1
+ import { I as MiddlewareHandler, L as RequestWithExtras, Q as MiddlewareConfig } from "../index-Dtrj6XZk.mjs";
2
2
  import { RouteHandlerMethod } from "fastify";
3
-
4
3
  //#region src/middleware/middleware.d.ts
5
4
  interface NamedMiddleware {
6
5
  /** Unique name for debugging/introspection */
@@ -1,5 +1,5 @@
1
+ import { n as ErrorMapper } from "./errorHandler-B0e-bq-O.mjs";
1
2
  import { FastifyInstance } from "fastify";
2
-
3
3
  //#region src/factory/loadResources.d.ts
4
4
  /**
5
5
  * loadResources — Auto-discover resource files from a directory.
@@ -142,6 +142,31 @@ interface LoadResourcesOptions<TContext = unknown> {
142
142
  * ```
143
143
  */
144
144
  include?: string[];
145
+ /**
146
+ * Path-level gate, called for every discovered file BEFORE it is imported.
147
+ * Return `false` to skip the file entirely — its module never evaluates,
148
+ * so top-level side effects (engine construction, model registration) of
149
+ * gated-off features never fire. That's the difference from
150
+ * `include`/`exclude`, which match resource NAMES after import.
151
+ *
152
+ * The feature-flag → resource-dir manifest every tiered SaaS host carries
153
+ * becomes one callback:
154
+ *
155
+ * ```ts
156
+ * await loadResources(import.meta.url, {
157
+ * filter: (path) => {
158
+ * if (path.includes(`${sep}loyalty${sep}`)) return isFeatureEnabled('loyalty');
159
+ * if (path.includes(`${sep}pos${sep}`)) return isFeatureEnabled('pos');
160
+ * return true;
161
+ * },
162
+ * });
163
+ * ```
164
+ *
165
+ * Receives the ABSOLUTE file path. Gating everything is legitimate — the
166
+ * result is an empty array (interacts with `strictResourceDir` like any
167
+ * other empty discovery).
168
+ */
169
+ filter?: (absolutePath: string) => boolean;
145
170
  /**
146
171
  * Optional logger override for diagnostics. When omitted, warnings flow
147
172
  * through arc's standard logger (`arcLog('loadResources')`) — same path
@@ -243,6 +268,26 @@ interface ArcModule<TExports = unknown> {
243
268
  * inside `bootstrap` still works — this slot just makes the two distinct.
244
269
  */
245
270
  plugins?: (fastify: FastifyInstance) => void | Promise<void>;
271
+ /**
272
+ * Domain error mappers this module ships (see `defineErrorMapper`). Merged
273
+ * into the app's error handler at boot, AFTER any host-declared mappers —
274
+ * host config keeps priority; module mappers follow in composition order.
275
+ *
276
+ * Closes the "composition root must know every domain's error classes"
277
+ * coupling: before this slot, adding `@classytic/arc-shipping` meant
278
+ * remembering to also register its `ShippingError` mapper in the host's
279
+ * `errorHandler.errorMappers` — forget it and the domain error crossed the
280
+ * wire as an opaque 500. Now the module carries its own mapper:
281
+ *
282
+ * ```ts
283
+ * defineModule({
284
+ * name: 'shipping',
285
+ * errorMappers: [shippingErrorMapper],
286
+ * ...
287
+ * })
288
+ * ```
289
+ */
290
+ readonly errorMappers?: readonly ErrorMapper[];
246
291
  /**
247
292
  * Domain init — runs in the `bootstrap` phase (after all `plugins`, before
248
293
  * resources). Initialize engines / singletons / event subscriptions here so
@@ -1,8 +1,8 @@
1
1
  import { t as getUserRoles } from "./types-XTApa8b6.mjs";
2
2
  import { n as convertRouteSchema } from "./schemaConverter-U0MnO9vd.mjs";
3
- import { t as resolveActionPermission } from "./actionPermissions-C9RMiIpc.mjs";
3
+ import { t as resolveActionPermission } from "./actionPermissions-ze70xXJi.mjs";
4
4
  import { t as pluralize } from "./pluralize-BhrgwZb9.mjs";
5
- import { t as buildActionBodySchema } from "./createActionRouter-HlQso0jO.mjs";
5
+ import { t as buildActionBodySchema } from "./createActionRouter-BWMDW-dL.mjs";
6
6
  import fp from "fastify-plugin";
7
7
  //#region src/docs/openapi/canonical-schemas.ts
8
8
  /**
@@ -1,3 +1,3 @@
1
- import { a as applyFieldWritePermissions, c as PermissionCheck, d as UserBase, f as getUserRoles, i as applyFieldReadPermissions, l as PermissionContext, n as FieldPermissionMap, o as fields, p as normalizeRoles, r as FieldPermissionType, s as resolveEffectiveRoles, t as FieldPermission, u as PermissionResult } from "../fields-C7ahdGYf.mjs";
2
- import { A as requireRoles, C as allOf, D as not, E as denyAll, F as RequireAgentScopeOptions, I as RequireMandateOptions, L as requireAgentScope, M as when, N as applyPermissionResult, O as requireAuth, P as normalizePermissionResult, R as requireDPoP, S as createOrgPermissions, T as anyOf, _ as ConnectEventsOptions, a as presets_d_exports, b as PermissionEventBus, c as readOnly, d as requireOrgRole, f as requireScopeContext, g as createRoleHierarchy, h as RoleHierarchy, i as ownerWithAdminBypass, j as roles, k as requireOwnership, l as requireOrgInScope, m as requireTeamMembership, n as authenticated, o as publicRead, p as requireServiceScope, r as fullPublic, s as publicReadAdminWrite, t as adminOnly, u as requireOrgMembership, v as DynamicPermissionMatrix, w as allowPublic, x as createDynamicPermissionMatrix, y as DynamicPermissionMatrixConfig, z as requireMandate } from "../index-CdFkIMEd.mjs";
3
- export { type ConnectEventsOptions, type DynamicPermissionMatrix, type DynamicPermissionMatrixConfig, type FieldPermission, type FieldPermissionMap, type FieldPermissionType, type PermissionCheck, type PermissionContext, type PermissionEventBus, type PermissionResult, type RequireAgentScopeOptions, type RequireMandateOptions, type RoleHierarchy, type UserBase, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, applyPermissionResult, authenticated, createDynamicPermissionMatrix, createOrgPermissions, createRoleHierarchy, denyAll, fields, fullPublic, getUserRoles, normalizePermissionResult, normalizeRoles, not, ownerWithAdminBypass, presets_d_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAgentScope, requireAuth, requireDPoP, requireMandate, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, resolveEffectiveRoles, roles, when };
1
+ import { a as applyFieldWritePermissions, c as PermissionCheck, d as UserBase, f as getUserRoles, i as applyFieldReadPermissions, l as PermissionContext, n as FieldPermissionMap, o as fields, p as normalizeRoles, r as FieldPermissionType, s as resolveEffectiveRoles, t as FieldPermission, u as PermissionResult } from "../fields-BGqrAa_u.mjs";
2
+ import { A as requireOwnership, B as requireMandate, C as createOrgPermissions, D as denyAll, E as anyOf, F as normalizePermissionResult, I as RequireAgentScopeOptions, L as RequireMandateOptions, M as roles, N as when, O as not, P as applyPermissionResult, R as requireAgentScope, S as createDynamicPermissionMatrix, T as allowPublic, _ as createRoleHierarchy, a as permissionMatrix, b as DynamicPermissionMatrixConfig, c as publicReadAdminWrite, d as requireOrgMembership, f as requireOrgRole, g as RoleHierarchy, h as requireTeamMembership, i as ownerWithAdminBypass, j as requireRoles, k as requireAuth, l as readOnly, m as requireServiceScope, n as authenticated, o as presets_d_exports, p as requireScopeContext, r as fullPublic, s as publicRead, t as adminOnly, u as requireOrgInScope, v as ConnectEventsOptions, w as allOf, x as PermissionEventBus, y as DynamicPermissionMatrix, z as requireDPoP } from "../index-B5PoNbfu.mjs";
3
+ export { type ConnectEventsOptions, type DynamicPermissionMatrix, type DynamicPermissionMatrixConfig, type FieldPermission, type FieldPermissionMap, type FieldPermissionType, type PermissionCheck, type PermissionContext, type PermissionEventBus, type PermissionResult, type RequireAgentScopeOptions, type RequireMandateOptions, type RoleHierarchy, type UserBase, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, applyPermissionResult, authenticated, createDynamicPermissionMatrix, createOrgPermissions, createRoleHierarchy, denyAll, fields, fullPublic, getUserRoles, normalizePermissionResult, normalizeRoles, not, ownerWithAdminBypass, permissionMatrix, presets_d_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAgentScope, requireAuth, requireDPoP, requireMandate, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, resolveEffectiveRoles, roles, when };
@@ -1,3 +1,3 @@
1
- import { A as requireMandate, C as requireAuth, D as when, E as roles, F as applyFieldWritePermissions, I as fields, L as resolveEffectiveRoles, N as normalizePermissionResult, O as requireAgentScope, P as applyFieldReadPermissions, S as not, T as requireRoles, _ as requireTeamMembership, a as presets_exports, b as anyOf, c as readOnly, d as createOrgPermissions, f as requireOrgInScope, g as requireServiceScope, h as requireScopeContext, i as ownerWithAdminBypass, j as applyPermissionResult, k as requireDPoP, l as createRoleHierarchy, m as requireOrgRole, n as authenticated, o as publicRead, p as requireOrgMembership, r as fullPublic, s as publicReadAdminWrite, t as adminOnly, u as createDynamicPermissionMatrix, v as allOf, w as requireOwnership, x as denyAll, y as allowPublic } from "../permissions-CgbOLJZG.mjs";
1
+ import { A as requireDPoP, C as not, D as roles, E as requireRoles, F as applyFieldReadPermissions, I as applyFieldWritePermissions, L as fields, M as applyPermissionResult, O as when, P as normalizePermissionResult, R as resolveEffectiveRoles, S as denyAll, T as requireOwnership, _ as requireServiceScope, a as permissionMatrix, b as allowPublic, c as publicReadAdminWrite, d as createDynamicPermissionMatrix, f as createOrgPermissions, g as requireScopeContext, h as requireOrgRole, i as ownerWithAdminBypass, j as requireMandate, k as requireAgentScope, l as readOnly, m as requireOrgMembership, n as authenticated, o as presets_exports, p as requireOrgInScope, r as fullPublic, s as publicRead, t as adminOnly, u as createRoleHierarchy, v as requireTeamMembership, w as requireAuth, x as anyOf, y as allOf } from "../permissions-BJMuKMl7.mjs";
2
2
  import { n as normalizeRoles, t as getUserRoles } from "../types-XTApa8b6.mjs";
3
- export { adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, applyPermissionResult, authenticated, createDynamicPermissionMatrix, createOrgPermissions, createRoleHierarchy, denyAll, fields, fullPublic, getUserRoles, normalizePermissionResult, normalizeRoles, not, ownerWithAdminBypass, presets_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAgentScope, requireAuth, requireDPoP, requireMandate, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, resolveEffectiveRoles, roles, when };
3
+ export { adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, applyPermissionResult, authenticated, createDynamicPermissionMatrix, createOrgPermissions, createRoleHierarchy, denyAll, fields, fullPublic, getUserRoles, normalizePermissionResult, normalizeRoles, not, ownerWithAdminBypass, permissionMatrix, presets_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAgentScope, requireAuth, requireDPoP, requireMandate, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, resolveEffectiveRoles, roles, when };
@@ -1382,6 +1382,7 @@ var presets_exports = /* @__PURE__ */ __exportAll({
1382
1382
  authenticated: () => authenticated,
1383
1383
  fullPublic: () => fullPublic,
1384
1384
  ownerWithAdminBypass: () => ownerWithAdminBypass,
1385
+ permissionMatrix: () => permissionMatrix,
1385
1386
  publicRead: () => publicRead,
1386
1387
  publicReadAdminWrite: () => publicReadAdminWrite,
1387
1388
  readOnly: () => readOnly
@@ -1450,6 +1451,37 @@ function adminOnly(roles = ["admin"], overrides) {
1450
1451
  }, overrides);
1451
1452
  }
1452
1453
  /**
1454
+ * Arbitrary-gate CRUD matrix — the generalization every host and arc-*
1455
+ * module hand-rolls as `{ list: view, get: view, create: manage, ... }`.
1456
+ *
1457
+ * Unlike the fixed presets above, the gates are caller-supplied
1458
+ * `PermissionCheck`s, so ANY combinator plugs in — org roles, ownership,
1459
+ * `anyOf(...)`, service scopes, custom async checks. `delete` defaults to
1460
+ * the `write` gate.
1461
+ *
1462
+ * @example
1463
+ * ```typescript
1464
+ * // Two-gate (view/manage) — the arc-* module convention:
1465
+ * permissionMatrix({ read: requireAuth(), write: requireOrgRole('manager') })
1466
+ *
1467
+ * // Three-gate with a stricter delete:
1468
+ * permissionMatrix({
1469
+ * read: allowPublic(),
1470
+ * write: requireOrgRole('manager'),
1471
+ * delete: requireOrgRole('owner'),
1472
+ * })
1473
+ * ```
1474
+ */
1475
+ function permissionMatrix(gates, overrides) {
1476
+ return withOverrides({
1477
+ list: gates.read,
1478
+ get: gates.read,
1479
+ create: gates.write,
1480
+ update: gates.write,
1481
+ delete: gates.delete ?? gates.write
1482
+ }, overrides);
1483
+ }
1484
+ /**
1453
1485
  * Owner-scoped with admin bypass.
1454
1486
  * list = auth (scoped to owner), get = auth, create = auth,
1455
1487
  * update + delete = ownership check with admin bypass.
@@ -1498,4 +1530,4 @@ function readOnly(overrides) {
1498
1530
  }, overrides);
1499
1531
  }
1500
1532
  //#endregion
1501
- export { requireMandate as A, requireAuth as C, when as D, roles as E, applyFieldWritePermissions as F, fields as I, resolveEffectiveRoles as L, evaluateAndApplyPermission as M, normalizePermissionResult as N, requireAgentScope as O, applyFieldReadPermissions as P, not as S, requireRoles as T, requireTeamMembership as _, presets_exports as a, anyOf as b, readOnly as c, createOrgPermissions as d, requireOrgInScope as f, requireServiceScope as g, requireScopeContext as h, ownerWithAdminBypass as i, applyPermissionResult as j, requireDPoP as k, createRoleHierarchy as l, requireOrgRole as m, authenticated as n, publicRead as o, requireOrgMembership as p, fullPublic as r, publicReadAdminWrite as s, adminOnly as t, createDynamicPermissionMatrix as u, allOf as v, requireOwnership as w, denyAll as x, allowPublic as y };
1533
+ export { requireDPoP as A, not as C, roles as D, requireRoles as E, applyFieldReadPermissions as F, applyFieldWritePermissions as I, fields as L, applyPermissionResult as M, evaluateAndApplyPermission as N, when as O, normalizePermissionResult as P, resolveEffectiveRoles as R, denyAll as S, requireOwnership as T, requireServiceScope as _, permissionMatrix as a, allowPublic as b, publicReadAdminWrite as c, createDynamicPermissionMatrix as d, createOrgPermissions as f, requireScopeContext as g, requireOrgRole as h, ownerWithAdminBypass as i, requireMandate as j, requireAgentScope as k, readOnly as l, requireOrgMembership as m, authenticated as n, presets_exports as o, requireOrgInScope as p, fullPublic as r, publicRead as s, adminOnly as t, createRoleHierarchy as u, requireTeamMembership as v, requireAuth as w, anyOf as x, allOf as y };
@@ -1,5 +1,4 @@
1
- import { Bt as Transform, Ft as NextFunction, It as OperationFilter, Lt as PipelineConfig, Nt as Guard, Pt as Interceptor, Rt as PipelineContext, bt as IControllerResponse, zt as PipelineStep } from "../index-_--GyzcO.mjs";
2
-
1
+ import { Bt as Transform, Ft as NextFunction, It as OperationFilter, Lt as PipelineConfig, Nt as Guard, Pt as Interceptor, Rt as PipelineContext, bt as IControllerResponse, zt as PipelineStep } from "../index-Dtrj6XZk.mjs";
3
2
  //#region src/pipeline/guard.d.ts
4
3
  interface GuardOptions {
5
4
  operations?: OperationFilter;
@@ -1,11 +1,10 @@
1
- import { Q as MiddlewareConfig, ft as RouteDefinition, ht as RouteSchemaOptions, nt as PresetHook, qt as AnyRecord } from "../index-_--GyzcO.mjs";
2
- import { a as arcCorePlugin, i as _default, n as ArcCorePluginOptions, r as PluginMeta, t as ArcCore } from "../fastify-augmentation-CCQJEDgh.mjs";
3
- import { _ as HealthOptions, a as MetricsCollector, c as metricsPlugin, d as ssePlugin, f as CachingOptions, g as HealthCheck, h as cachingPlugin, i as MetricEntry, l as SSEOptions, m as _default$1, n as _default$7, o as MetricsOptions, p as CachingRule, r as versioningPlugin, s as _default$4, t as VersioningOptions, u as _default$6, v as _default$3, y as healthPlugin } from "../versioning-D_eBCfNr.mjs";
4
- import { i as errorHandlerPlugin, n as ErrorMapper, r as defaultIsDuplicateKeyError, t as ErrorHandlerOptions } from "../errorHandler-BtUUDPEa.mjs";
5
- import { t as TracingOptions } from "../tracing-D8jlGXP7.mjs";
1
+ import { Q as MiddlewareConfig, ft as RouteDefinition, ht as RouteSchemaOptions, nt as PresetHook, qt as AnyRecord } from "../index-Dtrj6XZk.mjs";
2
+ import { i as errorHandlerPlugin, n as ErrorMapper, r as defaultIsDuplicateKeyError, t as ErrorHandlerOptions } from "../errorHandler-B0e-bq-O.mjs";
3
+ import { a as arcCorePlugin, i as _default, n as ArcCorePluginOptions, r as PluginMeta, t as ArcCore } from "../fastify-augmentation-DafigGQp.mjs";
4
+ import { _ as HealthOptions, a as MetricsCollector, c as metricsPlugin, d as ssePlugin, f as CachingOptions, g as HealthCheck, h as cachingPlugin, i as MetricEntry, l as SSEOptions, m as _default$1, n as _default$8, o as MetricsOptions, p as CachingRule, r as versioningPlugin, s as _default$4, t as VersioningOptions, u as _default$7, v as _default$3, y as healthPlugin } from "../versioning-DQ4mCvg0.mjs";
5
+ import { t as TracingOptions } from "../tracing-CsGKQJGg.mjs";
6
6
  import { PaginatedResult } from "@classytic/repo-core/pagination";
7
7
  import { FastifyInstance, FastifyPluginAsync } from "fastify";
8
-
9
8
  //#region src/plugins/createPlugin.d.ts
10
9
  interface PluginResourceResult {
11
10
  /** Additional routes to add to the resource (v2.8 `RouteDefinition` shape) */
@@ -149,4 +148,77 @@ declare module "fastify" {
149
148
  declare const requestIdPlugin: FastifyPluginAsync<RequestIdOptions>;
150
149
  declare const _default$5: FastifyPluginAsync<RequestIdOptions>;
151
150
  //#endregion
152
- export { type ArcCore, type ArcCorePluginOptions, type ArcPlugin, type CachingOptions, type CachingRule, type CreatePluginDefinition, type ErrorHandlerOptions, type ErrorMapper, type GracefulShutdownOptions, type HealthCheck, type HealthOptions, type MetricEntry, type MetricsCollector, type MetricsOptions, type PluginMeta, type PluginResourceResult, type RequestIdOptions, type SSEOptions, type TracingOptions, type VersioningOptions, _default as arcCorePlugin, arcCorePlugin as arcCorePluginFn, _default$1 as cachingPlugin, cachingPlugin as cachingPluginFn, createPlugin, defaultIsDuplicateKeyError, errorHandlerPlugin, errorHandlerPlugin as errorHandlerPluginFn, _default$2 as gracefulShutdownPlugin, gracefulShutdownPlugin as gracefulShutdownPluginFn, _default$3 as healthPlugin, healthPlugin as healthPluginFn, _default$4 as metricsPlugin, metricsPlugin as metricsPluginFn, replyHelpersPlugin, _default$5 as requestIdPlugin, requestIdPlugin as requestIdPluginFn, _default$6 as ssePlugin, ssePlugin as ssePluginFn, _default$7 as versioningPlugin, versioningPlugin as versioningPluginFn };
151
+ //#region src/plugins/schedules.d.ts
152
+ /**
153
+ * Structural view of the ecosystem lock contract — matches
154
+ * `LockAdapter` from `@classytic/repo-core/lock` (and every kit
155
+ * implementation) WITHOUT importing the subpath, so arc's emitted
156
+ * declarations carry no repo-core@>=0.8 subpath reference and the
157
+ * peer floor stays honest. Any conforming adapter assigns.
158
+ */
159
+ interface ScheduleLockLike {
160
+ tryAcquire(name: string, holderId: string, leaseMs: number): Promise<boolean> | boolean;
161
+ release(name: string, holderId: string): Promise<boolean> | boolean;
162
+ }
163
+ interface ScheduleDefinition {
164
+ /** Unique name — also the lock key (`arc:schedule:<name>`). */
165
+ name: string;
166
+ /** Interval in milliseconds between the END of one run and the next tick. */
167
+ every: number;
168
+ /** The work. Receives the Fastify instance; errors are logged, never fatal. */
169
+ handler: (fastify: FastifyInstance) => void | Promise<void>;
170
+ /** Fire once immediately when the app becomes ready (default: false). */
171
+ runOnStart?: boolean;
172
+ /**
173
+ * Random extra delay in `[0, jitterMs)` added to the FIRST tick only.
174
+ * Spreads boot-aligned jobs so multiple same-cadence schedules don't all
175
+ * fire at exactly `boot + every` after every restart (and, with a lock,
176
+ * de-synchronizes replicas competing for the same lease). Ignored when
177
+ * `runOnStart` is true.
178
+ */
179
+ jitterMs?: number;
180
+ /**
181
+ * Lease duration when a `lock` is configured. Default: `every * 0.9`
182
+ * (capped at 5 minutes) — long enough that other replicas skip the same
183
+ * tick, short enough that a crashed leader fails over within one cycle.
184
+ */
185
+ leaseMs?: number;
186
+ /** Per-schedule kill switch (default: true). */
187
+ enabled?: boolean;
188
+ }
189
+ interface SchedulesPluginOptions {
190
+ schedules: ScheduleDefinition[];
191
+ /**
192
+ * Ecosystem lock adapter for multi-replica deployments. Omit for
193
+ * single-instance apps — every tick runs locally.
194
+ */
195
+ lock?: ScheduleLockLike;
196
+ /**
197
+ * Identity of this replica for lease ownership. Default: a random id per
198
+ * process (repo-core's `getInstanceId()` is a good explicit value).
199
+ */
200
+ holderId?: string;
201
+ /**
202
+ * Master switch — `false` registers a typed no-op (config-gated
203
+ * environments), same pattern as `idempotencyPlugin`.
204
+ */
205
+ enabled?: boolean;
206
+ }
207
+ /** Per-schedule runtime counters, readable via `fastify.getScheduleStats()`. */
208
+ interface ScheduleStats {
209
+ name: string;
210
+ runs: number;
211
+ failures: number;
212
+ skippedByLock: number;
213
+ lastRunAt: string | null;
214
+ lastError: string | null;
215
+ }
216
+ declare module "fastify" {
217
+ interface FastifyInstance {
218
+ getScheduleStats?: () => ScheduleStats[];
219
+ }
220
+ }
221
+ declare const schedulesPlugin: FastifyPluginAsync<SchedulesPluginOptions>;
222
+ declare const _default$6: FastifyPluginAsync<SchedulesPluginOptions>;
223
+ //#endregion
224
+ export { type ArcCore, type ArcCorePluginOptions, type ArcPlugin, type CachingOptions, type CachingRule, type CreatePluginDefinition, type ErrorHandlerOptions, type ErrorMapper, type GracefulShutdownOptions, type HealthCheck, type HealthOptions, type MetricEntry, type MetricsCollector, type MetricsOptions, type PluginMeta, type PluginResourceResult, type RequestIdOptions, type SSEOptions, type ScheduleDefinition, type ScheduleLockLike, type ScheduleStats, type SchedulesPluginOptions, type TracingOptions, type VersioningOptions, _default as arcCorePlugin, arcCorePlugin as arcCorePluginFn, _default$1 as cachingPlugin, cachingPlugin as cachingPluginFn, createPlugin, defaultIsDuplicateKeyError, errorHandlerPlugin, errorHandlerPlugin as errorHandlerPluginFn, _default$2 as gracefulShutdownPlugin, gracefulShutdownPlugin as gracefulShutdownPluginFn, _default$3 as healthPlugin, healthPlugin as healthPluginFn, _default$4 as metricsPlugin, metricsPlugin as metricsPluginFn, replyHelpersPlugin, _default$5 as requestIdPlugin, requestIdPlugin as requestIdPluginFn, _default$6 as schedulesPlugin, schedulesPlugin as schedulesPluginFn, _default$7 as ssePlugin, ssePlugin as ssePluginFn, _default$8 as versioningPlugin, versioningPlugin as versioningPluginFn };
@@ -469,4 +469,91 @@ var requestId_default = fp(requestIdPlugin, {
469
469
  fastify: "5.x"
470
470
  });
471
471
  //#endregion
472
- export { arcCorePlugin_default as arcCorePlugin, arcCorePlugin as arcCorePluginFn, caching_default as cachingPlugin, cachingPlugin as cachingPluginFn, createPlugin, defaultIsDuplicateKeyError, errorHandlerPlugin, errorHandlerPlugin as errorHandlerPluginFn, gracefulShutdown_default as gracefulShutdownPlugin, gracefulShutdownPlugin as gracefulShutdownPluginFn, health_default as healthPlugin, healthPlugin as healthPluginFn, metrics_default as metricsPlugin, metricsPlugin as metricsPluginFn, replyHelpersPlugin, requestId_default as requestIdPlugin, requestIdPlugin as requestIdPluginFn, sse_default as ssePlugin, ssePlugin as ssePluginFn, versioning_default as versioningPlugin, versioningPlugin as versioningPluginFn };
472
+ //#region src/plugins/schedules.ts
473
+ const MIN_SAFE_INTERVAL_MS = 1e3;
474
+ const MAX_DEFAULT_LEASE_MS = 3e5;
475
+ const schedulesPlugin = async (fastify, opts) => {
476
+ const { schedules, lock, enabled = true } = opts;
477
+ const holderId = opts.holderId ?? `arc-${process.pid}-${Math.random().toString(36).slice(2, 10)}`;
478
+ const stats = /* @__PURE__ */ new Map();
479
+ fastify.decorate("getScheduleStats", () => [...stats.values()].map((s) => ({ ...s })));
480
+ if (!enabled) {
481
+ fastify.log.debug("schedulesPlugin disabled — registered as no-op");
482
+ return;
483
+ }
484
+ const seen = /* @__PURE__ */ new Set();
485
+ for (const s of schedules) {
486
+ if (!s.name) throw new TypeError("[arc-schedules] every schedule needs a name");
487
+ if (seen.has(s.name)) throw new TypeError(`[arc-schedules] duplicate schedule name "${s.name}"`);
488
+ seen.add(s.name);
489
+ if (!Number.isFinite(s.every) || s.every <= 0) throw new TypeError(`[arc-schedules] "${s.name}": \`every\` must be a positive number of ms`);
490
+ if (s.every < MIN_SAFE_INTERVAL_MS) fastify.log.warn(`[arc-schedules] "${s.name}" runs every ${s.every}ms — sub-second schedules are almost always a bug in production (DB pressure, lock churn). Intended for tests only.`);
491
+ }
492
+ const timers = /* @__PURE__ */ new Map();
493
+ const inFlight = /* @__PURE__ */ new Map();
494
+ let closing = false;
495
+ async function tick(s) {
496
+ const stat = stats.get(s.name);
497
+ if (!stat) return;
498
+ try {
499
+ if (lock) {
500
+ const leaseMs = s.leaseMs ?? Math.min(Math.floor(s.every * .9), MAX_DEFAULT_LEASE_MS);
501
+ if (!await lock.tryAcquire(`arc:schedule:${s.name}`, holderId, leaseMs)) {
502
+ stat.skippedByLock++;
503
+ return;
504
+ }
505
+ }
506
+ stat.runs++;
507
+ stat.lastRunAt = (/* @__PURE__ */ new Date()).toISOString();
508
+ await s.handler(fastify);
509
+ stat.lastError = null;
510
+ } catch (err) {
511
+ stat.failures++;
512
+ stat.lastError = err instanceof Error ? err.message : String(err);
513
+ fastify.log.error({
514
+ err,
515
+ schedule: s.name
516
+ }, "[arc-schedules] schedule run failed");
517
+ }
518
+ }
519
+ function scheduleNext(s, delay) {
520
+ if (closing) return;
521
+ const timer = setTimeout(() => {
522
+ const run = tick(s).finally(() => {
523
+ inFlight.delete(s.name);
524
+ scheduleNext(s, s.every);
525
+ });
526
+ inFlight.set(s.name, run);
527
+ }, delay);
528
+ timer.unref?.();
529
+ timers.set(s.name, timer);
530
+ }
531
+ fastify.addHook("onReady", async () => {
532
+ for (const s of schedules) {
533
+ if (s.enabled === false) continue;
534
+ stats.set(s.name, {
535
+ name: s.name,
536
+ runs: 0,
537
+ failures: 0,
538
+ skippedByLock: 0,
539
+ lastRunAt: null,
540
+ lastError: null
541
+ });
542
+ const jitter = !s.runOnStart && s.jitterMs ? Math.floor(Math.random() * s.jitterMs) : 0;
543
+ scheduleNext(s, s.runOnStart ? 0 : s.every + jitter);
544
+ }
545
+ if (stats.size > 0) fastify.log.debug(`[arc-schedules] ${stats.size} schedule(s) armed${lock ? ` (leader-safe, holder ${holderId})` : ""}`);
546
+ });
547
+ fastify.addHook("onClose", async () => {
548
+ closing = true;
549
+ for (const timer of timers.values()) clearTimeout(timer);
550
+ timers.clear();
551
+ await Promise.allSettled([...inFlight.values()]);
552
+ });
553
+ };
554
+ var schedules_default = fp(schedulesPlugin, {
555
+ name: "arc-schedules",
556
+ fastify: "5.x"
557
+ });
558
+ //#endregion
559
+ export { arcCorePlugin_default as arcCorePlugin, arcCorePlugin as arcCorePluginFn, caching_default as cachingPlugin, cachingPlugin as cachingPluginFn, createPlugin, defaultIsDuplicateKeyError, errorHandlerPlugin, errorHandlerPlugin as errorHandlerPluginFn, gracefulShutdown_default as gracefulShutdownPlugin, gracefulShutdownPlugin as gracefulShutdownPluginFn, health_default as healthPlugin, healthPlugin as healthPluginFn, metrics_default as metricsPlugin, metricsPlugin as metricsPluginFn, replyHelpersPlugin, requestId_default as requestIdPlugin, requestIdPlugin as requestIdPluginFn, schedules_default as schedulesPlugin, schedulesPlugin as schedulesPluginFn, sse_default as ssePlugin, ssePlugin as ssePluginFn, versioning_default as versioningPlugin, versioningPlugin as versioningPluginFn };
@@ -1,5 +1,4 @@
1
1
  import { FastifyPluginAsync, FastifyRequest } from "fastify";
2
-
3
2
  //#region src/plugins/response-cache.d.ts
4
3
  interface ResponseCacheRule {
5
4
  /** Path prefix to match (e.g., '/api/products') */
@@ -57,8 +56,11 @@ interface ResponseCacheStats {
57
56
  declare module "fastify" {
58
57
  interface FastifyInstance {
59
58
  responseCache: {
60
- /** Invalidate all cached responses matching a path prefix */invalidate: (pathPrefix: string) => number; /** Clear the entire cache */
61
- invalidateAll: () => void; /** Get cache statistics */
59
+ /** Invalidate all cached responses matching a path prefix */
60
+ invalidate: (pathPrefix: string) => number;
61
+ /** Clear the entire cache */
62
+ invalidateAll: () => void;
63
+ /** Get cache statistics */
62
64
  stats: () => ResponseCacheStats;
63
65
  /**
64
66
  * Route-level preHandler for cache lookup.
@@ -1,2 +1,2 @@
1
- import { a as traced, i as isTracingAvailable, n as _default, r as createSpan, t as TracingOptions } from "../tracing-D8jlGXP7.mjs";
1
+ import { a as traced, i as isTracingAvailable, n as _default, r as createSpan, t as TracingOptions } from "../tracing-CsGKQJGg.mjs";
2
2
  export { type TracingOptions, createSpan, isTracingAvailable, traced, _default as tracingPlugin };
@@ -58,7 +58,7 @@ try {
58
58
  function createTracerProvider(options) {
59
59
  if (!isAvailable || !NodeTracerProvider || !BatchSpanProcessor || !OTLPTraceExporter) return null;
60
60
  const { serviceName = "@classytic/arc", serviceVersion, exporterUrl = "http://localhost:4318/v1/traces" } = options;
61
- const resolvedVersion = serviceVersion ?? "2.20.0";
61
+ const resolvedVersion = serviceVersion ?? "2.21.0";
62
62
  const exporter = new OTLPTraceExporter({ url: exporterUrl });
63
63
  const provider = new NodeTracerProvider({ resource: { attributes: {
64
64
  "service.name": serviceName,
@@ -1,8 +1,7 @@
1
- import { rt as PresetResult } from "../index-_--GyzcO.mjs";
2
- import { i as RequestScope } from "../types-LNebCoJx.mjs";
3
- import { c as PermissionCheck } from "../fields-C7ahdGYf.mjs";
4
- import { a as StorageReadResult, i as StorageReadRange, n as StorageContext, o as StorageUploadInput, r as StorageFile, t as Storage } from "../storage-Co_PQpeQ.mjs";
5
-
1
+ import { rt as PresetResult } from "../index-Dtrj6XZk.mjs";
2
+ import { i as RequestScope } from "../types-DH0GupI7.mjs";
3
+ import { c as PermissionCheck } from "../fields-BGqrAa_u.mjs";
4
+ import { a as StorageReadResult, i as StorageReadRange, n as StorageContext, o as StorageUploadInput, r as StorageFile, t as Storage } from "../storage-DLUZ04kK.mjs";
6
5
  //#region src/presets/filesUpload.d.ts
7
6
  interface FilesUploadPresetRoutes {
8
7
  upload?: boolean;
@@ -1,6 +1,6 @@
1
1
  import { i as NotFoundError, u as ValidationError } from "../errors-DkO8Nk6-.mjs";
2
2
  import { c as getOrgId, g as getUserId } from "../types-bHblZ9YN.mjs";
3
- import { C as requireAuth, y as allowPublic } from "../permissions-CgbOLJZG.mjs";
3
+ import { b as allowPublic, w as requireAuth } from "../permissions-BJMuKMl7.mjs";
4
4
  import { t as multipartBody } from "../multipartBody-CHEQSZ6G.mjs";
5
5
  //#region src/presets/filesUpload.ts
6
6
  const DEFAULT_FIELD_NAME = "file";
@@ -1,8 +1,7 @@
1
- import { bt as IControllerResponse, d as PaginationResult, qt as AnyRecord, rt as PresetResult, st as ResourceConfig, xt as IRequestContext } from "../index-_--GyzcO.mjs";
1
+ import { bt as IControllerResponse, d as PaginationResult, qt as AnyRecord, rt as PresetResult, st as ResourceConfig, xt as IRequestContext } from "../index-Dtrj6XZk.mjs";
2
2
  import { FilesUploadPresetOptions, FilesUploadPresetPermissions, FilesUploadPresetRoutes, filesUploadPreset } from "./filesUpload.mjs";
3
3
  import { MultiTenantOptions, TenantFieldSpec, multiTenantPreset } from "./multiTenant.mjs";
4
4
  import { SearchHandler, SearchPresetOptions, SearchRouteConfig, searchPreset } from "./search.mjs";
5
-
6
5
  //#region src/presets/ownedByUser.d.ts
7
6
  interface OwnedByUserOptions {
8
7
  ownerField?: string;
@@ -1,5 +1,5 @@
1
1
  import { multiTenantPreset } from "./multiTenant.mjs";
2
- 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-DWsYQdbV.mjs";
2
+ 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-gw0ciIUD.mjs";
3
3
  import { filesUploadPreset } from "./filesUpload.mjs";
4
4
  import { searchPreset } from "./search.mjs";
5
5
  export { applyPresets, auditedPreset, bulkPreset, filesUploadPreset, flexibleMultiTenantPreset, getAvailablePresets, getPreset, multiTenantPreset, ownedByUserPreset, registerPreset, searchPreset, slugLookupPreset, softDeletePreset, treePreset };
@@ -1,5 +1,4 @@
1
- import { J as CrudRouteKey, rt as PresetResult } from "../index-_--GyzcO.mjs";
2
-
1
+ import { J as CrudRouteKey, rt as PresetResult } from "../index-Dtrj6XZk.mjs";
3
2
  //#region src/presets/multiTenant.d.ts
4
3
  /**
5
4
  * One tenant dimension for multi-field filtering. Discriminated by source:
@@ -1,6 +1,5 @@
1
- import { ft as RouteDefinition, gt as ControllerHandler, pt as RouteMcpConfig, rt as PresetResult } from "../index-_--GyzcO.mjs";
2
- import { c as PermissionCheck } from "../fields-C7ahdGYf.mjs";
3
-
1
+ import { ft as RouteDefinition, gt as ControllerHandler, pt as RouteMcpConfig, rt as PresetResult } from "../index-Dtrj6XZk.mjs";
2
+ import { c as PermissionCheck } from "../fields-BGqrAa_u.mjs";
4
3
  //#region src/presets/search.d.ts
5
4
  /**
6
5
  * Search Preset — backend-agnostic search / vector / embed routes
@@ -1,4 +1,4 @@
1
- import { C as requireAuth, y as allowPublic } from "../permissions-CgbOLJZG.mjs";
1
+ import { b as allowPublic, w as requireAuth } from "../permissions-BJMuKMl7.mjs";
2
2
  //#region src/presets/search.ts
3
3
  const BUILTINS = [
4
4
  {
@@ -1,5 +1,5 @@
1
1
  import { b as isElevated, n as PUBLIC_SCOPE } from "./types-bHblZ9YN.mjs";
2
- import { C as requireAuth, T as requireRoles, y as allowPublic } from "./permissions-CgbOLJZG.mjs";
2
+ import { E as requireRoles, b as allowPublic, w as requireAuth } from "./permissions-BJMuKMl7.mjs";
3
3
  import { multiTenantPreset } from "./presets/multiTenant.mjs";
4
4
  //#region src/presets/ownedByUser.ts
5
5
  /**
@@ -244,8 +244,10 @@ interface PushRefStore {
244
244
  * pre-compute it without re-introducing the very race we're closing.
245
245
  */
246
246
  stageIfInactive(args: {
247
- pushRef: string; /** Raw payload (NOT pre-wrapped). The store assigns seq + wraps atomically. */
248
- payload: unknown; /** Server timestamp (ms) — passed in so tests can pin the clock. */
247
+ pushRef: string;
248
+ /** Raw payload (NOT pre-wrapped). The store assigns seq + wraps atomically. */
249
+ payload: unknown;
250
+ /** Server timestamp (ms) — passed in so tests can pin the clock. */
249
251
  timestamp: number;
250
252
  expiresAt: number;
251
253
  }): Promise<"ok" | "missing" | "active" | "raw">;
@@ -1,7 +1,6 @@
1
1
  import { r as CacheStore } from "./interface-C1_WLTMK.mjs";
2
- import { i as QueryCache } from "./QueryCache-TRfXau3W.mjs";
2
+ import { i as QueryCache } from "./QueryCache-Z1B38koh.mjs";
3
3
  import { FastifyPluginAsync } from "fastify";
4
-
5
4
  //#region src/cache/queryCachePlugin.d.ts
6
5
  interface QueryCachePluginOptions {
7
6
  /** CacheStore instance. Default: MemoryCacheStore with default options. */
@@ -1,5 +1,4 @@
1
1
  import { n as IdempotencyResult, r as IdempotencyStore } from "./interface-Uk8ONJv7.mjs";
2
-
3
2
  //#region src/idempotency/stores/redis.d.ts
4
3
  interface RedisClient {
5
4
  get(key: string): Promise<string | null>;
@@ -1,5 +1,4 @@
1
- import { a as EventTransport, i as EventLogger, n as DomainEvent, r as EventHandler } from "./EventTransport-IEn7Tn-Q.mjs";
2
-
1
+ import { a as EventTransport, i as EventLogger, n as DomainEvent, r as EventHandler } from "./EventTransport-QmY7A258.mjs";
3
2
  //#region src/events/transports/redis-stream.d.ts
4
3
  interface RedisStreamLike {
5
4
  xadd(key: string, id: string, ...fieldValues: string[]): Promise<string | null>;
@@ -1,6 +1,6 @@
1
1
  import { f as createError } from "./errors-DkO8Nk6-.mjs";
2
2
  import { n as requestContext } from "./requestContext-BZKOr13H.mjs";
3
- import { M as evaluateAndApplyPermission } from "./permissions-CgbOLJZG.mjs";
3
+ import { N as evaluateAndApplyPermission } from "./permissions-BJMuKMl7.mjs";
4
4
  //#region src/core/middlewares/arcDecorator.ts
5
5
  /**
6
6
  * Build the `arcDecorator` preHandler for a resource.
@@ -1,7 +1,7 @@
1
- import { J as CrudRouteKey, R as RegisterOptions, V as ResourceDefinition, at as ResolvedTenantPurge, k as IntrospectionPluginOptions, p as RegistryEntry, z as ResourceRegistry } from "../index-_--GyzcO.mjs";
1
+ import { J as CrudRouteKey, R as RegisterOptions, V as ResourceDefinition, at as ResolvedTenantPurge, k as IntrospectionPluginOptions, p as RegistryEntry, z as ResourceRegistry } from "../index-Dtrj6XZk.mjs";
2
+ import "../fastify-augmentation-DafigGQp.mjs";
2
3
  import { FastifyPluginAsync } from "fastify";
3
4
  import { TenantPurgeProgress, TenantPurgeStrategy } from "@classytic/repo-core/repository";
4
-
5
5
  //#region src/registry/assertNoTenantData.d.ts
6
6
  interface AssertNoTenantDataOptions {
7
7
  readonly organizationId: string;
@@ -1,7 +1,6 @@
1
1
  import { ErrorContract, ErrorDetail } from "@classytic/repo-core/errors";
2
2
  import { FastifyPluginAsyncTypebox, FastifyPluginCallbackTypebox, TypeBoxTypeProvider, TypeBoxValidatorCompiler } from "@fastify/type-provider-typebox";
3
3
  import { Static, TObject, TSchema, TSchema as TSchema$1, Type } from "@sinclair/typebox";
4
-
5
4
  //#region src/schemas/index.d.ts
6
5
  /**
7
6
  * Paginated list response — full union of every wire shape `toCanonicalList`
@@ -1,6 +1,5 @@
1
1
  import { FastifyPluginAsync, FastifyRequest } from "fastify";
2
2
  import { RepositoryLike } from "@classytic/repo-core/adapter";
3
-
4
3
  //#region src/scim/mapping.d.ts
5
4
  /**
6
5
  * SCIM 2.0 ↔ arc resource mapping
@@ -1,7 +1,6 @@
1
- import { C as isMember, D as requireOrgId, E as requireClientId, O as requireTeamId, S as isElevated, T as isService, _ as getTenantFromRequest, a as getAncestorOrgIds, b as hasOrgAccess, c as getMandate, d as getOrgRoles, f as getRequestScope, g as getTeamId, h as getServiceScopes, i as RequestScope, k as requireUserId, l as getOrgContext, m as getScopeContextMap, n as Mandate, o as getClientId, p as getScopeContext, r as PUBLIC_SCOPE, s as getDPoPJkt, t as AUTHENTICATED_SCOPE, u as getOrgId, v as getUserId, w as isOrgInScope, x as isAuthenticated, y as getUserRoles } from "../types-LNebCoJx.mjs";
2
- import { i as elevationPlugin, n as ElevationOptions, r as _default, t as ElevationEvent } from "../elevation-xGUBq6p_.mjs";
1
+ import { C as isMember, D as requireOrgId, E as requireClientId, O as requireTeamId, S as isElevated, T as isService, _ as getTenantFromRequest, a as getAncestorOrgIds, b as hasOrgAccess, c as getMandate, d as getOrgRoles, f as getRequestScope, g as getTeamId, h as getServiceScopes, i as RequestScope, k as requireUserId, l as getOrgContext, m as getScopeContextMap, n as Mandate, o as getClientId, p as getScopeContext, r as PUBLIC_SCOPE, s as getDPoPJkt, t as AUTHENTICATED_SCOPE, u as getOrgId, v as getUserId, w as isOrgInScope, x as isAuthenticated, y as getUserRoles } from "../types-DH0GupI7.mjs";
2
+ import { i as elevationPlugin, n as ElevationOptions, r as _default, t as ElevationEvent } from "../elevation-C9s5hFP_.mjs";
3
3
  import { FastifyReply, FastifyRequest } from "fastify";
4
-
5
4
  //#region src/scope/rateLimitKey.d.ts
6
5
  interface RateLimitKeyContext {
7
6
  ip: string;
@@ -1,5 +1,4 @@
1
1
  import { FastifyPluginAsync, FastifyReply, FastifyRequest } from "fastify";
2
-
3
2
  //#region src/auth/sessionManager.d.ts
4
3
  /**
5
4
  * Session data stored in the session store.
@@ -81,13 +80,18 @@ declare module "fastify" {
81
80
  authenticate: (request: FastifyRequest, reply: FastifyReply) => Promise<void>;
82
81
  /** Session management helpers */
83
82
  sessionManager: {
84
- /** Create a new session for a user */createSession: (userId: string, metadata?: Record<string, unknown>) => Promise<{
83
+ /** Create a new session for a user */
84
+ createSession: (userId: string, metadata?: Record<string, unknown>) => Promise<{
85
85
  sessionId: string;
86
86
  cookie: string;
87
- }>; /** Revoke a specific session */
88
- revokeSession: (sessionId: string) => Promise<void>; /** Revoke all sessions for a user */
89
- revokeAllSessions: (userId: string) => Promise<void>; /** Revoke all sessions except the current one */
90
- revokeOtherSessions: (userId: string, currentSessionId: string) => Promise<void>; /** Refresh a session (reset updatedAt, extend expiry if needed) */
87
+ }>;
88
+ /** Revoke a specific session */
89
+ revokeSession: (sessionId: string) => Promise<void>;
90
+ /** Revoke all sessions for a user */
91
+ revokeAllSessions: (userId: string) => Promise<void>;
92
+ /** Revoke all sessions except the current one */
93
+ revokeOtherSessions: (userId: string, currentSessionId: string) => Promise<void>;
94
+ /** Refresh a session (reset updatedAt, extend expiry if needed) */
91
95
  refreshSession: (sessionId: string) => Promise<SessionData | null>;
92
96
  };
93
97
  }