@classytic/arc 2.20.0 → 2.22.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 (143) hide show
  1. package/dist/{BaseController-D-MHZ27_.mjs → BaseController-C6FlRWxF.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 +35 -14
  9. package/dist/auth/index.mjs +6 -3
  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-b6fgFgnd.mjs} +129 -17
  20. package/dist/{createActionRouter-HlQso0jO.mjs → createActionRouter-h1cEEaEX.mjs} +10 -6
  21. package/dist/{createAggregationRouter-5LzPzgw1.mjs → createAggregationRouter-B1C0kvTL.mjs} +3 -3
  22. package/dist/{createApp-D6uwzCKu.mjs → createApp-Ci7yG5gv.mjs} +390 -192
  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/encryption/index.mjs +9 -5
  29. package/dist/{errorHandler-Dxf6P_kV.mjs → errorHandler-BTzXSwIg.mjs} +24 -3
  30. package/dist/{errorHandler-BtUUDPEa.d.mts → errorHandler-C6yv4ZTW.d.mts} +13 -1
  31. package/dist/{errors-DOHkjQlD.d.mts → errors-DHcHVAgk.d.mts} +0 -1
  32. package/dist/{eventPlugin-DbBFd3x_.d.mts → eventPlugin-A6EbthXR.d.mts} +10 -6
  33. package/dist/events/index.d.mts +9 -6
  34. package/dist/events/transports/redis-stream-entry.d.mts +1 -1
  35. package/dist/events/transports/redis.d.mts +1 -2
  36. package/dist/factory/index.d.mts +30 -9
  37. package/dist/factory/index.mjs +35 -4
  38. package/dist/{fastify-augmentation-CCQJEDgh.d.mts → fastify-augmentation-9_fuetB4.d.mts} +2 -3
  39. package/dist/fields-D3lhgzhD.d.mts +121 -0
  40. package/dist/health-ScyjIVo5.mjs +202 -0
  41. package/dist/hooks/index.d.mts +1 -1
  42. package/dist/idempotency/index.d.mts +4 -3
  43. package/dist/idempotency/index.mjs +2 -0
  44. package/dist/idempotency/redis.d.mts +1 -1
  45. package/dist/{types-BHMKlMBU.d.mts → index-BEu4wjbL.d.mts} +241 -80
  46. package/dist/{index-DUa8WHz3.d.mts → index-D8MKYGDa.d.mts} +88 -7
  47. package/dist/{index-_--GyzcO.d.mts → index-DbtgCOCj.d.mts} +1324 -1228
  48. package/dist/{index-CdFkIMEd.d.mts → index-ogIHvOjo.d.mts} +36 -7
  49. package/dist/index.d.mts +8 -7
  50. package/dist/index.mjs +6 -6
  51. package/dist/{init-YH_nslQR.mjs → init-DleK3p9f.mjs} +272 -139
  52. package/dist/integrations/event-gateway.d.mts +2 -3
  53. package/dist/integrations/index.d.mts +2 -2
  54. package/dist/integrations/jobs.d.mts +0 -1
  55. package/dist/integrations/mcp/index.d.mts +6 -7
  56. package/dist/integrations/mcp/index.mjs +1 -1
  57. package/dist/integrations/mcp/testing.d.mts +1 -2
  58. package/dist/integrations/mcp/testing.mjs +1 -1
  59. package/dist/integrations/streamline.d.mts +2 -2
  60. package/dist/integrations/webhooks.d.mts +8 -5
  61. package/dist/integrations/webhooks.mjs +9 -5
  62. package/dist/integrations/websocket-pushref-redis.d.mts +1 -2
  63. package/dist/integrations/websocket-redis.d.mts +1 -2
  64. package/dist/integrations/websocket.d.mts +2 -2
  65. package/dist/jsonBody-BlzAoGCe.mjs +43 -0
  66. package/dist/{loadResources-B8UmpITt.mjs → loadResources-DpU8pfjV.mjs} +4 -3
  67. package/dist/logger/index.d.mts +26 -1
  68. package/dist/logger/index.mjs +39 -1
  69. package/dist/{mcpPlugin-CuW6L_uD.mjs → mcpPlugin-ByA2tf6D.mjs} +8 -4
  70. package/dist/middleware/index.d.mts +1 -2
  71. package/dist/{module-JYH9V0I8.d.mts → module-B4u10iOJ.d.mts} +71 -1
  72. package/dist/{openapi-Dq6RbEGK.mjs → openapi-BRpMZD7C.mjs} +3 -3
  73. package/dist/permissions/index.d.mts +4 -3
  74. package/dist/permissions/index.mjs +2 -2
  75. package/dist/{permissions-CgbOLJZG.mjs → permissions-BJMuKMl7.mjs} +33 -1
  76. package/dist/pipeline/index.d.mts +1 -2
  77. package/dist/plugins/index.d.mts +96 -7
  78. package/dist/plugins/index.mjs +86 -268
  79. package/dist/plugins/response-cache.d.mts +5 -3
  80. package/dist/plugins/response-cache.mjs +1 -0
  81. package/dist/plugins/tracing-entry.d.mts +1 -1
  82. package/dist/plugins/tracing-entry.mjs +7 -4
  83. package/dist/presets/filesUpload.d.mts +4 -5
  84. package/dist/presets/filesUpload.mjs +1 -1
  85. package/dist/presets/index.d.mts +1 -2
  86. package/dist/presets/index.mjs +1 -1
  87. package/dist/presets/multiTenant.d.mts +1 -2
  88. package/dist/presets/search.d.mts +2 -3
  89. package/dist/presets/search.mjs +1 -1
  90. package/dist/{presets-DWsYQdbV.mjs → presets-gw0ciIUD.mjs} +1 -1
  91. package/dist/{pushref-registry-DnCqL3aa.d.mts → pushref-registry-BbcnpNTm.d.mts} +4 -2
  92. package/dist/{queryCachePlugin-xzFyKAjT.d.mts → queryCachePlugin-CfYWq-Ak.d.mts} +1 -2
  93. package/dist/rateLimitKey-BoWRH3e7.mjs +14 -0
  94. package/dist/{redis-C3W0qbz8.d.mts → redis-UDtLaNj6.d.mts} +0 -1
  95. package/dist/{redis-stream-DsP1vqZB.d.mts → redis-stream-iVR2l7aS.d.mts} +1 -2
  96. package/dist/{registerRoute-DGSREwPw.mjs → registerRoute-xHc42fwB.mjs} +38 -18
  97. package/dist/registry/index.d.mts +2 -2
  98. package/dist/requestId-5BhTVzBv.mjs +113 -0
  99. package/dist/schemaConverter-Ds5reSGs.mjs +168 -0
  100. package/dist/{schemaIR-ajetw3Fv.mjs → schemaIR-B-6SPe7g.mjs} +2 -2
  101. package/dist/schemas/index.d.mts +0 -1
  102. package/dist/scim/index.d.mts +0 -1
  103. package/dist/scim/index.mjs +6 -7
  104. package/dist/scope/index.d.mts +2 -3
  105. package/dist/scope/index.mjs +2 -76
  106. package/dist/scope-k15RXfcq.mjs +64 -0
  107. package/dist/{sessionManager-BXG-HGwG.d.mts → sessionManager-BHOM3N_0.d.mts} +10 -6
  108. package/dist/{storage-Co_PQpeQ.d.mts → storage-DLUZ04kK.d.mts} +8 -4
  109. package/dist/testing/index.d.mts +83 -4
  110. package/dist/testing/index.mjs +74 -4
  111. package/dist/testing/storageContract.d.mts +1 -2
  112. package/dist/{tracing-D8jlGXP7.d.mts → tracing-CsGKQJGg.d.mts} +0 -1
  113. package/dist/types/index.d.mts +4 -4
  114. package/dist/types/storage.d.mts +1 -1
  115. package/dist/{types-C9b2HR5W.d.mts → types-Bc42CUyk.d.mts} +1 -2
  116. package/dist/types-Cc91nXuA.d.mts +132 -0
  117. package/dist/{fields-C7ahdGYf.d.mts → types-Csxga7d3.d.mts} +2 -123
  118. package/dist/{types-LNebCoJx.d.mts → types-DH0GupI7.d.mts} +8 -4
  119. package/dist/usage/index.d.mts +142 -0
  120. package/dist/usage/index.mjs +0 -0
  121. package/dist/utils/index.d.mts +220 -144
  122. package/dist/utils/index.mjs +3 -3
  123. package/dist/{utils-ChjYQpjn.mjs → utils-FhJ88TJE.mjs} +129 -39
  124. package/dist/{versioning-D_eBCfNr.d.mts → versioning-DLwklPlG.d.mts} +1 -7
  125. package/dist/{websocket-MlYlrYq0.d.mts → websocket-uuWqM6UY.d.mts} +5 -4
  126. package/llms.txt +39 -0
  127. package/package.json +453 -447
  128. package/skills/arc/SKILL.md +14 -8
  129. package/skills/arc/references/api-reference.md +34 -0
  130. package/skills/arc/references/auth.md +21 -4
  131. package/skills/arc/references/mcp.md +1 -1
  132. package/skills/arc/references/production.md +44 -2
  133. package/skills/arc-code-review/SKILL.md +1 -1
  134. package/skills/arc-code-review/references/anti-patterns.md +71 -18
  135. package/skills/arc-code-review/references/arc-cheatsheet.md +15 -2
  136. package/skills/arc-code-review/references/migration-recipes.md +7 -7
  137. package/skills/arc-code-review/references/mongokit-migration.md +4 -3
  138. package/skills/arc-module-publishing/SKILL.md +243 -0
  139. package/skills/arc-module-publishing/references/authoring-modules.md +327 -0
  140. package/skills/arc-module-publishing/references/package-manifest.md +157 -0
  141. package/skills/arc-module-publishing/references/publishing-workflow.md +182 -0
  142. package/dist/preloadResources-CHw3_oA_.mjs +0 -45
  143. package/dist/schemaConverter-U0MnO9vd.mjs +0 -110
@@ -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 { At as RouteDefinition, J as PresetHook, Q as MiddlewareConfig, et as RouteSchemaOptions, qt as AnyRecord } from "../index-DbtgCOCj.mjs";
2
+ import { i as errorHandlerPlugin, n as ErrorMapper, r as defaultIsDuplicateKeyError, t as ErrorHandlerOptions } from "../errorHandler-C6yv4ZTW.mjs";
3
+ import { a as arcCorePlugin, i as _default, n as ArcCorePluginOptions, r as PluginMeta, t as ArcCore } from "../fastify-augmentation-9_fuetB4.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-DLwklPlG.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) */
@@ -146,7 +145,97 @@ declare module "fastify" {
146
145
  };
147
146
  }
148
147
  }
148
+ /**
149
+ * Sanitize an incoming request-id header value: max 128 chars, alphanumeric
150
+ * plus dashes/underscores/dots/colons only. Returns `undefined` for anything
151
+ * else (crafted values could pollute logs or response headers). Array values
152
+ * (repeated headers) are rejected outright — a client sending multiple
153
+ * request-id headers is not tracing in good faith.
154
+ */
155
+ declare function sanitizeRequestId(value: unknown): string | undefined;
156
+ /**
157
+ * Build a Fastify `genReqId` function: adopt a sanitized incoming request-id
158
+ * header, or generate one. Wire this into the `Fastify()` constructor so
159
+ * `request.id`, `request.log`'s `reqId` binding, and the echoed response
160
+ * header all agree — `createApp` does this automatically.
161
+ */
162
+ declare function createRequestIdGenerator(opts?: Pick<RequestIdOptions, "header" | "generator">): (req: {
163
+ headers: Record<string, string | string[] | undefined>;
164
+ }) => string;
149
165
  declare const requestIdPlugin: FastifyPluginAsync<RequestIdOptions>;
150
166
  declare const _default$5: FastifyPluginAsync<RequestIdOptions>;
151
167
  //#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 };
168
+ //#region src/plugins/schedules.d.ts
169
+ /**
170
+ * Structural view of the ecosystem lock contract — matches
171
+ * `LockAdapter` from `@classytic/repo-core/lock` (and every kit
172
+ * implementation) WITHOUT importing the subpath, so arc's emitted
173
+ * declarations carry no repo-core@>=0.8 subpath reference and the
174
+ * peer floor stays honest. Any conforming adapter assigns.
175
+ */
176
+ interface ScheduleLockLike {
177
+ tryAcquire(name: string, holderId: string, leaseMs: number): Promise<boolean> | boolean;
178
+ release(name: string, holderId: string): Promise<boolean> | boolean;
179
+ }
180
+ interface ScheduleDefinition {
181
+ /** Unique name — also the lock key (`arc:schedule:<name>`). */
182
+ name: string;
183
+ /** Interval in milliseconds between the END of one run and the next tick. */
184
+ every: number;
185
+ /** The work. Receives the Fastify instance; errors are logged, never fatal. */
186
+ handler: (fastify: FastifyInstance) => void | Promise<void>;
187
+ /** Fire once immediately when the app becomes ready (default: false). */
188
+ runOnStart?: boolean;
189
+ /**
190
+ * Random extra delay in `[0, jitterMs)` added to the FIRST tick only.
191
+ * Spreads boot-aligned jobs so multiple same-cadence schedules don't all
192
+ * fire at exactly `boot + every` after every restart (and, with a lock,
193
+ * de-synchronizes replicas competing for the same lease). Ignored when
194
+ * `runOnStart` is true.
195
+ */
196
+ jitterMs?: number;
197
+ /**
198
+ * Lease duration when a `lock` is configured. Default: `every * 0.9`
199
+ * (capped at 5 minutes) — long enough that other replicas skip the same
200
+ * tick, short enough that a crashed leader fails over within one cycle.
201
+ */
202
+ leaseMs?: number;
203
+ /** Per-schedule kill switch (default: true). */
204
+ enabled?: boolean;
205
+ }
206
+ interface SchedulesPluginOptions {
207
+ schedules: ScheduleDefinition[];
208
+ /**
209
+ * Ecosystem lock adapter for multi-replica deployments. Omit for
210
+ * single-instance apps — every tick runs locally.
211
+ */
212
+ lock?: ScheduleLockLike;
213
+ /**
214
+ * Identity of this replica for lease ownership. Default: a random id per
215
+ * process (repo-core's `getInstanceId()` is a good explicit value).
216
+ */
217
+ holderId?: string;
218
+ /**
219
+ * Master switch — `false` registers a typed no-op (config-gated
220
+ * environments), same pattern as `idempotencyPlugin`.
221
+ */
222
+ enabled?: boolean;
223
+ }
224
+ /** Per-schedule runtime counters, readable via `fastify.getScheduleStats()`. */
225
+ interface ScheduleStats {
226
+ name: string;
227
+ runs: number;
228
+ failures: number;
229
+ skippedByLock: number;
230
+ lastRunAt: string | null;
231
+ lastError: string | null;
232
+ }
233
+ declare module "fastify" {
234
+ interface FastifyInstance {
235
+ getScheduleStats?: () => ScheduleStats[];
236
+ }
237
+ }
238
+ declare const schedulesPlugin: FastifyPluginAsync<SchedulesPluginOptions>;
239
+ declare const _default$6: FastifyPluginAsync<SchedulesPluginOptions>;
240
+ //#endregion
241
+ 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, createRequestIdGenerator, 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, sanitizeRequestId, _default$6 as schedulesPlugin, schedulesPlugin as schedulesPluginFn, _default$7 as ssePlugin, ssePlugin as ssePluginFn, _default$8 as versioningPlugin, versioningPlugin as versioningPluginFn };
@@ -4,13 +4,14 @@ import { n as requestContext } from "../requestContext-BZKOr13H.mjs";
4
4
  import { t as hasEvents } from "../typeGuards-C9KXUly6.mjs";
5
5
  import { t as HookSystem } from "../HookSystem-C1vB_Gc9.mjs";
6
6
  import { t as ResourceRegistry } from "../ResourceRegistry-7RnrEWNP.mjs";
7
+ import { i as sanitizeRequestId, n as requestIdPlugin, r as requestId_default, t as createRequestIdGenerator } from "../requestId-5BhTVzBv.mjs";
8
+ import { n as health_default, t as healthPlugin } from "../health-ScyjIVo5.mjs";
7
9
  import { n as caching_default, t as cachingPlugin } from "../caching-_NJeDd1_.mjs";
8
- import { n as errorHandlerPlugin, t as defaultIsDuplicateKeyError } from "../errorHandler-Dxf6P_kV.mjs";
10
+ import { n as errorHandlerPlugin, t as defaultIsDuplicateKeyError } from "../errorHandler-BTzXSwIg.mjs";
9
11
  import { n as metrics_default, t as metricsPlugin } from "../metrics-fdxI5mn_.mjs";
10
12
  import { t as replyHelpersPlugin } from "../replyHelpers-67tRawQZ.mjs";
11
13
  import { n as sse_default, t as ssePlugin } from "../sse-CfUjwjDk.mjs";
12
14
  import { n as versioning_default, t as versioningPlugin } from "../versioning-Dk-71iIz.mjs";
13
- import { randomUUID } from "node:crypto";
14
15
  import fp from "fastify-plugin";
15
16
  //#region src/core/arcCorePlugin.ts
16
17
  const arcCorePlugin = async (fastify, opts = {}) => {
@@ -24,6 +25,13 @@ const arcCorePlugin = async (fastify, opts = {}) => {
24
25
  externalOpenApiPaths: [],
25
26
  plugins: /* @__PURE__ */ new Map()
26
27
  });
28
+ for (const field of [
29
+ "_policyFilters",
30
+ "_ownershipCheck",
31
+ "fieldMask",
32
+ "policyMetadata",
33
+ "document"
34
+ ]) if (!fastify.hasRequestDecorator(field)) fastify.decorateRequest(field, void 0);
27
35
  fastify.addHook("onRequest", (request, _reply, done) => {
28
36
  const store = {
29
37
  requestId: request.id,
@@ -192,281 +200,91 @@ var gracefulShutdown_default = fp(gracefulShutdownPlugin, {
192
200
  fastify: "5.x"
193
201
  });
194
202
  //#endregion
195
- //#region src/plugins/health.ts
196
- function createHttpMetrics() {
197
- return {
198
- requestsTotal: {},
199
- requestDurations: [],
200
- _ringIndex: 0,
201
- startTime: Date.now()
202
- };
203
- }
204
- const healthPlugin = async (fastify, opts = {}) => {
205
- const { prefix = "/_health", checks = [], metrics = false, metricsCollector, version, collectHttpMetrics = metrics } = opts;
206
- const httpMetrics = createHttpMetrics();
207
- fastify.get(prefix, { schema: {
208
- tags: ["Health"],
209
- summary: "Liveness probe (alias for /live)",
210
- description: "Returns 200 if the process is alive",
211
- response: { 200: {
212
- type: "object",
213
- properties: {
214
- status: {
215
- type: "string",
216
- enum: ["ok"]
217
- },
218
- timestamp: { type: "string" },
219
- version: { type: "string" }
220
- }
221
- } }
222
- } }, async () => ({
223
- status: "ok",
224
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
225
- ...version ? { version } : {}
226
- }));
227
- fastify.get(`${prefix}/live`, { schema: {
228
- tags: ["Health"],
229
- summary: "Liveness probe",
230
- description: "Returns 200 if the process is alive",
231
- response: { 200: {
232
- type: "object",
233
- properties: {
234
- status: {
235
- type: "string",
236
- enum: ["ok"]
237
- },
238
- timestamp: { type: "string" },
239
- version: { type: "string" }
240
- }
241
- } }
242
- } }, async () => {
243
- return {
244
- status: "ok",
245
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
246
- ...version ? { version } : {}
247
- };
248
- });
249
- fastify.get(`${prefix}/ready`, { schema: {
250
- tags: ["Health"],
251
- summary: "Readiness probe",
252
- description: "Returns 200 if all dependencies are healthy",
253
- response: {
254
- 200: {
255
- type: "object",
256
- properties: {
257
- status: {
258
- type: "string",
259
- enum: ["ready", "not_ready"]
260
- },
261
- timestamp: { type: "string" },
262
- checks: {
263
- type: "array",
264
- items: {
265
- type: "object",
266
- properties: {
267
- name: { type: "string" },
268
- healthy: { type: "boolean" },
269
- duration: { type: "number" },
270
- error: { type: "string" }
271
- }
272
- }
273
- }
274
- }
275
- },
276
- 503: {
277
- type: "object",
278
- properties: {
279
- status: {
280
- type: "string",
281
- enum: ["not_ready"]
282
- },
283
- timestamp: { type: "string" },
284
- checks: { type: "array" }
203
+ //#region src/plugins/schedules.ts
204
+ const MIN_SAFE_INTERVAL_MS = 1e3;
205
+ const MAX_DEFAULT_LEASE_MS = 3e5;
206
+ const schedulesPlugin = async (fastify, opts) => {
207
+ const { schedules, lock, enabled = true } = opts;
208
+ const holderId = opts.holderId ?? `arc-${process.pid}-${Math.random().toString(36).slice(2, 10)}`;
209
+ const stats = /* @__PURE__ */ new Map();
210
+ fastify.decorate("getScheduleStats", () => [...stats.values()].map((s) => ({ ...s })));
211
+ if (!enabled) {
212
+ fastify.log.debug("schedulesPlugin disabled — registered as no-op");
213
+ return;
214
+ }
215
+ const seen = /* @__PURE__ */ new Set();
216
+ for (const s of schedules) {
217
+ if (!s.name) throw new TypeError("[arc-schedules] every schedule needs a name");
218
+ if (seen.has(s.name)) throw new TypeError(`[arc-schedules] duplicate schedule name "${s.name}"`);
219
+ seen.add(s.name);
220
+ if (!Number.isFinite(s.every) || s.every <= 0) throw new TypeError(`[arc-schedules] "${s.name}": \`every\` must be a positive number of ms`);
221
+ 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.`);
222
+ }
223
+ const timers = /* @__PURE__ */ new Map();
224
+ const inFlight = /* @__PURE__ */ new Map();
225
+ let closing = false;
226
+ async function tick(s) {
227
+ const stat = stats.get(s.name);
228
+ if (!stat) return;
229
+ try {
230
+ if (lock) {
231
+ const leaseMs = s.leaseMs ?? Math.min(Math.floor(s.every * .9), MAX_DEFAULT_LEASE_MS);
232
+ if (!await lock.tryAcquire(`arc:schedule:${s.name}`, holderId, leaseMs)) {
233
+ stat.skippedByLock++;
234
+ return;
285
235
  }
286
236
  }
237
+ stat.runs++;
238
+ stat.lastRunAt = (/* @__PURE__ */ new Date()).toISOString();
239
+ await s.handler(fastify);
240
+ stat.lastError = null;
241
+ } catch (err) {
242
+ stat.failures++;
243
+ stat.lastError = err instanceof Error ? err.message : String(err);
244
+ fastify.log.error({
245
+ err,
246
+ schedule: s.name
247
+ }, "[arc-schedules] schedule run failed");
287
248
  }
288
- } }, async (_, reply) => {
289
- const results = await runChecks(checks);
290
- const criticalFailed = results.some((r) => !r.healthy && (checks.find((c) => c.name === r.name)?.critical ?? true));
291
- const response = {
292
- status: criticalFailed ? "not_ready" : "ready",
293
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
294
- checks: results
295
- };
296
- if (criticalFailed) reply.code(503);
297
- return response;
298
- });
299
- if (metrics) fastify.get(`${prefix}/metrics`, async (_, reply) => {
300
- reply.type("text/plain; charset=utf-8");
301
- if (metricsCollector) return await metricsCollector();
302
- const uptime = process.uptime();
303
- const memory = process.memoryUsage();
304
- const cpu = process.cpuUsage();
305
- const lines = [
306
- "# HELP process_uptime_seconds Process uptime in seconds",
307
- "# TYPE process_uptime_seconds gauge",
308
- `process_uptime_seconds ${uptime.toFixed(2)}`,
309
- "",
310
- "# HELP process_memory_heap_bytes Heap memory usage in bytes",
311
- "# TYPE process_memory_heap_bytes gauge",
312
- `process_memory_heap_bytes{type="used"} ${memory.heapUsed}`,
313
- `process_memory_heap_bytes{type="total"} ${memory.heapTotal}`,
314
- "",
315
- "# HELP process_memory_rss_bytes RSS memory in bytes",
316
- "# TYPE process_memory_rss_bytes gauge",
317
- `process_memory_rss_bytes ${memory.rss}`,
318
- "",
319
- "# HELP process_memory_external_bytes External memory in bytes",
320
- "# TYPE process_memory_external_bytes gauge",
321
- `process_memory_external_bytes ${memory.external}`,
322
- "",
323
- "# HELP process_cpu_user_microseconds User CPU time in microseconds",
324
- "# TYPE process_cpu_user_microseconds counter",
325
- `process_cpu_user_microseconds ${cpu.user}`,
326
- "",
327
- "# HELP process_cpu_system_microseconds System CPU time in microseconds",
328
- "# TYPE process_cpu_system_microseconds counter",
329
- `process_cpu_system_microseconds ${cpu.system}`,
330
- ""
331
- ];
332
- if (collectHttpMetrics && Object.keys(httpMetrics.requestsTotal).length > 0) {
333
- lines.push("# HELP http_requests_total Total HTTP requests by status code", "# TYPE http_requests_total counter");
334
- for (const [status, count] of Object.entries(httpMetrics.requestsTotal)) lines.push(`http_requests_total{status="${status}"} ${count}`);
335
- lines.push("");
336
- if (httpMetrics.requestDurations.length > 0) {
337
- const sorted = [...httpMetrics.requestDurations].sort((a, b) => a - b);
338
- const p50 = sorted[Math.floor(sorted.length * .5)] || 0;
339
- const p95 = sorted[Math.floor(sorted.length * .95)] || 0;
340
- const p99 = sorted[Math.floor(sorted.length * .99)] || 0;
341
- const sum = sorted.reduce((a, b) => a + b, 0);
342
- lines.push("# HELP http_request_duration_milliseconds HTTP request duration", "# TYPE http_request_duration_milliseconds summary", `http_request_duration_milliseconds{quantile="0.5"} ${p50.toFixed(2)}`, `http_request_duration_milliseconds{quantile="0.95"} ${p95.toFixed(2)}`, `http_request_duration_milliseconds{quantile="0.99"} ${p99.toFixed(2)}`, `http_request_duration_milliseconds_sum ${sum.toFixed(2)}`, `http_request_duration_milliseconds_count ${sorted.length}`, "");
343
- }
344
- }
345
- return lines.join("\n");
346
- });
347
- if (collectHttpMetrics) {
348
- fastify.addHook("onRequest", async (request) => {
349
- request._startTime = Date.now();
350
- });
351
- fastify.addHook("onResponse", async (request, reply) => {
352
- const duration = Date.now() - (request._startTime ?? Date.now());
353
- const statusBucket = `${Math.floor(reply.statusCode / 100)}xx`;
354
- httpMetrics.requestsTotal[statusBucket] = (httpMetrics.requestsTotal[statusBucket] || 0) + 1;
355
- if (httpMetrics.requestDurations.length < 1e4) httpMetrics.requestDurations.push(duration);
356
- else httpMetrics.requestDurations[httpMetrics._ringIndex % 1e4] = duration;
357
- httpMetrics._ringIndex = httpMetrics._ringIndex + 1;
358
- });
359
249
  }
360
- fastify.log?.debug?.(`Health plugin registered at ${prefix} (alias), ${prefix}/live, ${prefix}/ready${metrics ? `, ${prefix}/metrics` : ""}`);
361
- };
362
- /**
363
- * Run all health checks with timeout
364
- */
365
- async function runChecks(checks) {
366
- const results = [];
367
- for (const check of checks) {
368
- const start = Date.now();
369
- const timeout = check.timeout ?? 5e3;
370
- let timer;
371
- try {
372
- const checkPromise = Promise.resolve(check.check());
373
- const timeoutPromise = new Promise((_, reject) => {
374
- timer = setTimeout(() => reject(/* @__PURE__ */ new Error("Health check timeout")), timeout);
375
- });
376
- const healthy = await Promise.race([checkPromise, timeoutPromise]);
377
- results.push({
378
- name: check.name,
379
- healthy: Boolean(healthy),
380
- duration: Date.now() - start
381
- });
382
- } catch (err) {
383
- results.push({
384
- name: check.name,
385
- healthy: false,
386
- duration: Date.now() - start,
387
- error: err.message
250
+ function scheduleNext(s, delay) {
251
+ if (closing) return;
252
+ const timer = setTimeout(() => {
253
+ const run = tick(s).finally(() => {
254
+ inFlight.delete(s.name);
255
+ scheduleNext(s, s.every);
388
256
  });
389
- } finally {
390
- if (timer) clearTimeout(timer);
391
- }
257
+ inFlight.set(s.name, run);
258
+ }, delay);
259
+ timer.unref?.();
260
+ timers.set(s.name, timer);
392
261
  }
393
- return results;
394
- }
395
- var health_default = fp(healthPlugin, {
396
- name: "arc-health",
397
- fastify: "5.x"
398
- });
399
- //#endregion
400
- //#region src/plugins/requestId.ts
401
- /**
402
- * Request ID Plugin
403
- *
404
- * Propagates request IDs for distributed tracing.
405
- * - Accepts incoming x-request-id header
406
- * - Generates UUID if not provided
407
- * - Attaches to request.id and response header
408
- *
409
- * @example
410
- * import { requestIdPlugin } from '@classytic/arc';
411
- *
412
- * await fastify.register(requestIdPlugin);
413
- *
414
- * // In handlers, access via request.id
415
- * fastify.get('/', async (request) => {
416
- * console.log(request.id); // UUID
417
- * });
418
- */
419
- /** W3C traceparent format: `version-traceid-parentid-flags` */
420
- const TRACEPARENT_RE = /^([0-9a-f]{2})-([0-9a-f]{32})-([0-9a-f]{16})-([0-9a-f]{2})$/i;
421
- /** W3C spec: version ff is reserved and invalid; trace/parent IDs must not be all zeros */
422
- const TRACEID_ZEROS = "0".repeat(32);
423
- const PARENTID_ZEROS = "0".repeat(16);
424
- /** tracestate: printable ASCII, <= 512 bytes */
425
- const TRACESTATE_MAX = 512;
426
- function isValidTraceparent(tp) {
427
- const m = TRACEPARENT_RE.exec(tp);
428
- if (!m) return false;
429
- const version = m[1] ?? "";
430
- const traceId = m[2] ?? "";
431
- const parentId = m[3] ?? "";
432
- if (version.toLowerCase() === "ff") return false;
433
- if (traceId.toLowerCase() === TRACEID_ZEROS) return false;
434
- if (parentId.toLowerCase() === PARENTID_ZEROS) return false;
435
- return true;
436
- }
437
- const requestIdPlugin = async (fastify, opts = {}) => {
438
- const { header = "x-request-id", generator = randomUUID, setResponseHeader = true, propagateTraceContext = true } = opts;
439
- if (!fastify.hasRequestDecorator("requestId")) fastify.decorateRequest("requestId", "");
440
- if (!fastify.hasRequestDecorator("traceContext")) fastify.decorateRequest("traceContext", void 0);
441
- fastify.addHook("onRequest", async (request, reply) => {
442
- const incomingId = request.headers[header];
443
- const sanitized = typeof incomingId === "string" ? incomingId.trim() : "";
444
- const requestId = sanitized.length > 0 && sanitized.length <= 128 && /^[\w.:-]+$/.test(sanitized) ? sanitized : generator();
445
- request.id = requestId;
446
- request.requestId = requestId;
447
- if (setResponseHeader) reply.header(header, requestId);
448
- if (propagateTraceContext) {
449
- const rawTraceparent = request.headers["traceparent"];
450
- const rawTracestate = request.headers["tracestate"];
451
- if (typeof rawTraceparent === "string") {
452
- const tp = rawTraceparent.trim();
453
- if (isValidTraceparent(tp)) {
454
- const ts = typeof rawTracestate === "string" && rawTracestate.length > 0 && rawTracestate.length <= TRACESTATE_MAX ? rawTracestate : void 0;
455
- request.traceContext = {
456
- traceparent: tp,
457
- ...ts ? { tracestate: ts } : {}
458
- };
459
- reply.header("traceparent", tp);
460
- if (ts) reply.header("tracestate", ts);
461
- }
462
- }
262
+ fastify.addHook("onReady", async () => {
263
+ for (const s of schedules) {
264
+ if (s.enabled === false) continue;
265
+ stats.set(s.name, {
266
+ name: s.name,
267
+ runs: 0,
268
+ failures: 0,
269
+ skippedByLock: 0,
270
+ lastRunAt: null,
271
+ lastError: null
272
+ });
273
+ const jitter = !s.runOnStart && s.jitterMs ? Math.floor(Math.random() * s.jitterMs) : 0;
274
+ scheduleNext(s, s.runOnStart ? 0 : s.every + jitter);
463
275
  }
276
+ if (stats.size > 0) fastify.log.debug(`[arc-schedules] ${stats.size} schedule(s) armed${lock ? ` (leader-safe, holder ${holderId})` : ""}`);
277
+ });
278
+ fastify.addHook("onClose", async () => {
279
+ closing = true;
280
+ for (const timer of timers.values()) clearTimeout(timer);
281
+ timers.clear();
282
+ await Promise.allSettled([...inFlight.values()]);
464
283
  });
465
- fastify.log?.debug?.("Request ID plugin registered");
466
284
  };
467
- var requestId_default = fp(requestIdPlugin, {
468
- name: "arc-request-id",
285
+ var schedules_default = fp(schedulesPlugin, {
286
+ name: "arc-schedules",
469
287
  fastify: "5.x"
470
288
  });
471
289
  //#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 };
290
+ export { arcCorePlugin_default as arcCorePlugin, arcCorePlugin as arcCorePluginFn, caching_default as cachingPlugin, cachingPlugin as cachingPluginFn, createPlugin, createRequestIdGenerator, 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, sanitizeRequestId, 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.
@@ -94,6 +94,7 @@ const responseCachePluginImpl = async (fastify, opts = {}) => {
94
94
  ], xCacheHeader = true, statsPath = null, keyFn } = opts;
95
95
  const cache = new LRUCache(maxEntries);
96
96
  const invalidateMethods = new Set(invalidateOn.map((m) => m.toUpperCase()));
97
+ if (!fastify.hasRequestDecorator("__arcCacheTTL")) fastify.decorateRequest("__arcCacheTTL", void 0);
97
98
  /** Find TTL for a given URL path (seconds) */
98
99
  function getTTL(url) {
99
100
  const path = url.split("?")[0] ?? url;
@@ -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.22.0";
62
62
  const exporter = new OTLPTraceExporter({ url: exporterUrl });
63
63
  const provider = new NodeTracerProvider({ resource: { attributes: {
64
64
  "service.name": serviceName,
@@ -92,8 +92,11 @@ async function tracingPlugin(fastify, options = {}) {
92
92
  }
93
93
  const tracer = otelTrace.getTracer(serviceName);
94
94
  fastify.decorateRequest("tracer", void 0);
95
- fastify.addHook("onRequest", async (request, _reply) => {
96
- if (Math.random() > sampleRate) return;
95
+ fastify.addHook("onRequest", (request, _reply, done) => {
96
+ if (Math.random() > sampleRate) {
97
+ done();
98
+ return;
99
+ }
97
100
  const span = tracer.startSpan(`HTTP ${request.method} ${request.url}`, {
98
101
  kind: 1,
99
102
  attributes: {
@@ -109,7 +112,7 @@ async function tracingPlugin(fastify, options = {}) {
109
112
  tracer,
110
113
  currentSpan: span
111
114
  };
112
- otelContext.with(otelTrace.setSpan(otelContext.active(), span), () => {});
115
+ otelContext.with(otelTrace.setSpan(otelContext.active(), span), done);
113
116
  });
114
117
  fastify.addHook("onResponse", async (request, reply) => {
115
118
  if (!request.tracer?.currentSpan) return;
@@ -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 { Y as PresetResult } from "../index-DbtgCOCj.mjs";
2
+ import { i as RequestScope } from "../types-DH0GupI7.mjs";
3
+ import { t as PermissionCheck } from "../types-Csxga7d3.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 { Rt as IControllerResponse, U as ResourceConfig, Y as PresetResult, d as PaginationResult, qt as AnyRecord, zt as IRequestContext } from "../index-DbtgCOCj.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 { X as CrudRouteKey, Y as PresetResult } from "../index-DbtgCOCj.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 { At as RouteDefinition, Pt as ControllerHandler, Y as PresetResult, jt as RouteMcpConfig } from "../index-DbtgCOCj.mjs";
2
+ import { t as PermissionCheck } from "../types-Csxga7d3.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
  {