@classytic/arc 2.18.1 → 2.18.3

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 (153) hide show
  1. package/dist/{BaseController-DPwe89qs.mjs → BaseController-B-uXzf6I.mjs} +403 -216
  2. package/dist/{QueryCache-8YmAQ-zW.d.mts → QueryCache-Dsyv2mLS.d.mts} +1 -1
  3. package/dist/audit/index.d.mts +1 -1
  4. package/dist/auth/index.d.mts +4 -4
  5. package/dist/auth/index.mjs +4 -4
  6. package/dist/auth/redis-session.d.mts +1 -1
  7. package/dist/{betterAuthOpenApi-ClWxaceA.mjs → betterAuthOpenApi-DAAhMZff.mjs} +1 -1
  8. package/dist/{buildHandler-C_SkBNF3.mjs → buildHandler-Cvrc2p7r.mjs} +1 -1
  9. package/dist/cache/index.d.mts +3 -3
  10. package/dist/cache/index.mjs +3 -3
  11. package/dist/cli/commands/describe.d.mts +1 -1
  12. package/dist/cli/commands/describe.mjs +1 -1
  13. package/dist/cli/commands/docs.mjs +2 -2
  14. package/dist/cli/commands/generate.d.mts +1 -1
  15. package/dist/cli/commands/generate.mjs +1 -1
  16. package/dist/cli/commands/init.d.mts +1 -1
  17. package/dist/cli/commands/init.mjs +1 -1
  18. package/dist/cli/commands/introspect.mjs +1 -1
  19. package/dist/cli/index.d.mts +2 -2
  20. package/dist/cli/index.mjs +2 -2
  21. package/dist/core/index.d.mts +2 -2
  22. package/dist/core/index.mjs +3 -3
  23. package/dist/{core-B41eZxyM.mjs → core-C88uIwd3.mjs} +161 -103
  24. package/dist/{createActionRouter-CRaIwB5S.mjs → createActionRouter-DGCCp-kP.mjs} +4 -2
  25. package/dist/{createAggregationRouter-n3O6WdLO.mjs → createAggregationRouter-Ca77b8iK.mjs} +3 -3
  26. package/dist/{createApp-DZvrb587.mjs → createApp-DLuUGVZQ.mjs} +11 -11
  27. package/dist/{defineEvent-NPKUJRt8.mjs → defineEvent-DC981g-o.mjs} +1 -1
  28. package/dist/docs/index.d.mts +2 -2
  29. package/dist/docs/index.mjs +2 -2
  30. package/dist/{elevation-6mfTLBC-.mjs → elevation-BzhyVWfn.mjs} +1 -1
  31. package/dist/{eventPlugin-Dxp9JlKK.mjs → eventPlugin-Bw4bUDEO.mjs} +2 -2
  32. package/dist/{eventPlugin-DjEx_J3j.d.mts → eventPlugin-C1W1CRbf.d.mts} +1 -1
  33. package/dist/events/index.d.mts +8 -5
  34. package/dist/events/index.mjs +26 -7
  35. package/dist/events/transports/redis-stream-entry.d.mts +1 -1
  36. package/dist/events/transports/redis-stream-entry.mjs +52 -5
  37. package/dist/events/transports/redis.d.mts +1 -1
  38. package/dist/factory/index.d.mts +1 -1
  39. package/dist/factory/index.mjs +3 -3
  40. package/dist/{fastify-augmentation-CL48B6gW.d.mts → fastify-augmentation-BdCl_eNo.d.mts} +2 -2
  41. package/dist/{fields-DqZLp5d6.d.mts → fields-CKLrhyOb.d.mts} +1 -1
  42. package/dist/{generate-CcM24hoq.mjs → generate-BaxDdmJ8.mjs} +1 -1
  43. package/dist/hooks/index.d.mts +1 -1
  44. package/dist/hooks/index.mjs +1 -1
  45. package/dist/idempotency/index.d.mts +2 -2
  46. package/dist/idempotency/index.mjs +1 -1
  47. package/dist/idempotency/redis.d.mts +1 -1
  48. package/dist/{index-CNiryUMN.d.mts → index-Cvo1u9n6.d.mts} +3 -3
  49. package/dist/{index-C000faom.d.mts → index-QYma8mdC.d.mts} +215 -241
  50. package/dist/{index-3L-adFJO.d.mts → index-vcWUGkwf.d.mts} +3 -3
  51. package/dist/index.d.mts +5 -5
  52. package/dist/index.mjs +5 -5
  53. package/dist/{init-DQ_rY1J7.mjs → init-DSsdRfk9.mjs} +3 -3
  54. package/dist/integrations/event-gateway.d.mts +2 -2
  55. package/dist/integrations/event-gateway.mjs +1 -1
  56. package/dist/integrations/index.d.mts +2 -2
  57. package/dist/integrations/jobs.mjs +66 -1
  58. package/dist/integrations/mcp/index.d.mts +4 -4
  59. package/dist/integrations/mcp/index.mjs +1 -1
  60. package/dist/integrations/mcp/testing.d.mts +1 -1
  61. package/dist/integrations/mcp/testing.mjs +1 -1
  62. package/dist/integrations/streamline.d.mts +16 -1
  63. package/dist/integrations/streamline.mjs +35 -4
  64. package/dist/integrations/websocket-pushref-redis.d.mts +1 -1
  65. package/dist/integrations/websocket-redis.d.mts +1 -1
  66. package/dist/integrations/websocket.d.mts +2 -2
  67. package/dist/{loadResourcesFromEntry-DCjYMgfC.mjs → loadResourcesFromEntry-XHNeUWpu.mjs} +1 -1
  68. package/dist/{mcpPlugin-BrepZ0cV.mjs → mcpPlugin-CzKdt3B8.mjs} +9 -9
  69. package/dist/middleware/index.d.mts +1 -1
  70. package/dist/middleware/index.mjs +1 -1
  71. package/dist/{openapi-CLZx9bwS.mjs → openapi-ButnRyOM.mjs} +5 -5
  72. package/dist/permissions/index.d.mts +2 -2
  73. package/dist/permissions/index.mjs +2 -2
  74. package/dist/{permissions-B1Qy55fg.mjs → permissions-3uzwkbQt.mjs} +99 -99
  75. package/dist/pipeline/index.d.mts +1 -1
  76. package/dist/pipeline/index.mjs +1 -1
  77. package/dist/pipeline-D4sqiokR.mjs +336 -0
  78. package/dist/plugins/index.d.mts +5 -5
  79. package/dist/plugins/index.mjs +9 -9
  80. package/dist/plugins/response-cache.mjs +1 -1
  81. package/dist/plugins/tracing-entry.d.mts +1 -1
  82. package/dist/plugins/tracing-entry.mjs +1 -1
  83. package/dist/presets/filesUpload.d.mts +4 -4
  84. package/dist/presets/filesUpload.mjs +2 -2
  85. package/dist/presets/index.d.mts +1 -1
  86. package/dist/presets/index.mjs +1 -1
  87. package/dist/presets/multiTenant.d.mts +1 -1
  88. package/dist/presets/search.d.mts +2 -2
  89. package/dist/presets/search.mjs +1 -1
  90. package/dist/{presets-BYbPobbF.mjs → presets-CF79RHEo.mjs} +1 -1
  91. package/dist/{queryCachePlugin-Do4P_WBC.d.mts → queryCachePlugin-Bd2tYgh5.d.mts} +2 -2
  92. package/dist/{queryCachePlugin-B4XMSSe7.mjs → queryCachePlugin-CnAeFqju.mjs} +3 -3
  93. package/dist/rateLimit-yKvxWAky.mjs +207 -0
  94. package/dist/{redis-cpqVb85w.d.mts → redis-3hqH_Qk_.d.mts} +1 -1
  95. package/dist/{redis-stream-BuiAS3aE.d.mts → redis-stream-BtEUtjxZ.d.mts} +5 -4
  96. package/dist/registerRoute-BEYn0ylk.mjs +108 -0
  97. package/dist/registry/index.d.mts +1 -1
  98. package/dist/registry/index.mjs +2 -2
  99. package/dist/{schemaIR-Bk6Tns82.mjs → schemaIR-CE6USIRi.mjs} +1 -1
  100. package/dist/scope/index.d.mts +2 -2
  101. package/dist/scope/index.mjs +2 -2
  102. package/dist/testing/index.d.mts +2 -2
  103. package/dist/testing/index.mjs +12 -2
  104. package/dist/testing/storageContract.d.mts +1 -1
  105. package/dist/types/index.d.mts +4 -4
  106. package/dist/types/storage.d.mts +1 -1
  107. package/dist/{types-DH-7WO64.d.mts → types-BWBcb88c.d.mts} +1 -1
  108. package/dist/{types-DEEWwQFR.d.mts → types-WVlAVp8T.d.mts} +10 -10
  109. package/dist/utils/index.d.mts +3 -3
  110. package/dist/utils/index.mjs +3 -3
  111. package/dist/{utils-BMQK8mRl.mjs → utils-xAQeDyU_.mjs} +1 -1
  112. package/dist/{validate-DFIP2VrM.mjs → validate-0__MuUsK.mjs} +201 -190
  113. package/dist/{versioning-5H4930tj.d.mts → versioning-BSEDGXKC.d.mts} +1 -1
  114. package/dist/{websocket-BZMUP7Gr.d.mts → websocket-BFBT5rH-.d.mts} +1 -1
  115. package/package.json +5 -5
  116. package/skills/arc/references/api-reference.md +1 -1
  117. package/dist/routerShared-Dl0A77Ba.mjs +0 -724
  118. /package/dist/{EventTransport-ClEDfiMS.mjs → EventTransport-7LPXLEUX.mjs} +0 -0
  119. /package/dist/{EventTransport-B1GFiYUy.d.mts → EventTransport-CaaXM5Y1.d.mts} +0 -0
  120. /package/dist/{HookSystem-Cmf7-Etp.mjs → HookSystem-BfCpWbwM.mjs} +0 -0
  121. /package/dist/{ResourceRegistry-CzSzVK1m.mjs → ResourceRegistry-CWmOggxS.mjs} +0 -0
  122. /package/dist/{actionPermissions-Bjmvn7Eb.mjs → actionPermissions-CX9QIMTd.mjs} +0 -0
  123. /package/dist/{caching-8MfrrUYU.mjs → caching-C0DdKiYB.mjs} +0 -0
  124. /package/dist/{elevation-DvwtjDwu.d.mts → elevation-DW90z5bT.d.mts} +0 -0
  125. /package/dist/{errorHandler-wQejMBT3.mjs → errorHandler-Bua97SEt.mjs} +0 -0
  126. /package/dist/{errorHandler-DuqTqeqn.d.mts → errorHandler-_Lp2k9M3.d.mts} +0 -0
  127. /package/dist/{errors-4ZloYFvm.d.mts → errors-DZOemeGa.d.mts} +0 -0
  128. /package/dist/{externalPaths-ClykOQqa.d.mts → externalPaths-DLle0R07.d.mts} +0 -0
  129. /package/dist/{generate-cRnsafMS.d.mts → generate-Dmk8cfvX.d.mts} +0 -0
  130. /package/dist/{init-D-vrTZ1G.d.mts → init-BS4Daqnv.d.mts} +0 -0
  131. /package/dist/{interface-DoE6UoC2.d.mts → interface-CsrGR8LF.d.mts} +0 -0
  132. /package/dist/{interface-BVkZsvEe.d.mts → interface-DL7LlWS5.d.mts} +0 -0
  133. /package/dist/{keys-DopsCuyQ.mjs → keys-B3yyBEyH.mjs} +0 -0
  134. /package/dist/{loadResources-fol6JuvW.mjs → loadResources-CwXt9MCh.mjs} +0 -0
  135. /package/dist/{memory-QOLe11D5.mjs → memory-TdTHCS9-.mjs} +0 -0
  136. /package/dist/{metrics-B-PU4-Yu.mjs → metrics-Da2EUPi9.mjs} +0 -0
  137. /package/dist/{multipartBody-VjVWmZl8.mjs → multipartBody-709YcXi1.mjs} +0 -0
  138. /package/dist/{pipe-DiCyvyPN.mjs → pipe-9Tl-OAus.mjs} +0 -0
  139. /package/dist/{pluralize-B9M8xvy-.mjs → pluralize-BxdUl2P4.mjs} +0 -0
  140. /package/dist/{preloadResources-BOXzPhKU.mjs → preloadResources-B-j-iqo-.mjs} +0 -0
  141. /package/dist/{pushref-registry-Bq_-EVsC.d.mts → pushref-registry-Dqclzjy7.d.mts} +0 -0
  142. /package/dist/{registry-BrlHkrRS.mjs → registry-Br15xdGM.mjs} +0 -0
  143. /package/dist/{replyHelpers-boS5Rx26.mjs → replyHelpers-DXHVxrrj.mjs} +0 -0
  144. /package/dist/{schemaConverter-De34B1ZG.mjs → schemaConverter-DatAaVNj.mjs} +0 -0
  145. /package/dist/{sessionManager-DlmaHUAl.d.mts → sessionManager-CyHpYXoB.d.mts} +0 -0
  146. /package/dist/{sse-jh5OqFjR.mjs → sse-Xq8UtuQx.mjs} +0 -0
  147. /package/dist/{storage-BFmamN5m.d.mts → storage-C5q8fuEt.d.mts} +0 -0
  148. /package/dist/{store-helpers-5JgaxieH.mjs → store-helpers-DjSYI2uP.mjs} +0 -0
  149. /package/dist/{tracing-BYQ3hsbM.d.mts → tracing-Bnb1-YVd.d.mts} +0 -0
  150. /package/dist/{typeGuards-BzkXkvVv.mjs → typeGuards-CcFZXgU7.mjs} +0 -0
  151. /package/dist/{types-CfapW2t8.d.mts → types-BJwJN2Pg.d.mts} +0 -0
  152. /package/dist/{types-DV9WDfeg.mjs → types-D57iXYb8.mjs} +0 -0
  153. /package/dist/{versioning-CuIwUQZ2.mjs → versioning-C0K8KQLx.mjs} +0 -0
@@ -1,4 +1,4 @@
1
- import { r as CacheStore } from "./interface-BVkZsvEe.mjs";
1
+ import { r as CacheStore } from "./interface-DL7LlWS5.mjs";
2
2
 
3
3
  //#region src/cache/QueryCache.d.ts
4
4
  /** Metadata wrapper stored in CacheStore */
@@ -1,4 +1,4 @@
1
- import { d as UserBase } from "../fields-DqZLp5d6.mjs";
1
+ import { d as UserBase } from "../fields-CKLrhyOb.mjs";
2
2
  import { FastifyPluginAsync } from "fastify";
3
3
  import { RepositoryLike } from "@classytic/repo-core/adapter";
4
4
 
@@ -1,7 +1,7 @@
1
- import { Bt as AuthHelpers, Vt as AuthPluginOptions } from "../index-C000faom.mjs";
2
- import { c as PermissionCheck } from "../fields-DqZLp5d6.mjs";
3
- import { t as ExternalOpenApiPaths } from "../externalPaths-ClykOQqa.mjs";
4
- import { a as SessionManagerOptions, c as createSessionManager, i as SessionData, n as MemorySessionStoreOptions, o as SessionManagerResult, r as SessionCookieOptions, s as SessionStore, t as MemorySessionStore } from "../sessionManager-DlmaHUAl.mjs";
1
+ import { Bt as AuthHelpers, Vt as AuthPluginOptions } from "../index-QYma8mdC.mjs";
2
+ import { c as PermissionCheck } from "../fields-CKLrhyOb.mjs";
3
+ import { t as ExternalOpenApiPaths } from "../externalPaths-DLle0R07.mjs";
4
+ import { a as SessionManagerOptions, c as createSessionManager, i as SessionData, n as MemorySessionStoreOptions, o as SessionManagerResult, r as SessionCookieOptions, s as SessionStore, t as MemorySessionStore } from "../sessionManager-CyHpYXoB.mjs";
5
5
  import { FastifyPluginAsync, FastifyReply as FastifyReply$1, FastifyRequest } from "fastify";
6
6
 
7
7
  //#region src/auth/authPlugin.d.ts
@@ -1,7 +1,7 @@
1
1
  import { d as createDomainError, l as UnauthorizedError, p as isArcError, t as ArcError } from "../errors-j4aJm1Wg.mjs";
2
- import { _ as requireTeamMembership, m as requireOrgRole, p as requireOrgMembership } from "../permissions-B1Qy55fg.mjs";
3
- import { n as normalizeRoles, t as getUserRoles } from "../types-DV9WDfeg.mjs";
4
- import { n as extractBetterAuthOpenApi } from "../betterAuthOpenApi-ClWxaceA.mjs";
2
+ import { _ as requireTeamMembership, m as requireOrgRole, p as requireOrgMembership } from "../permissions-3uzwkbQt.mjs";
3
+ import { n as normalizeRoles, t as getUserRoles } from "../types-D57iXYb8.mjs";
4
+ import { n as extractBetterAuthOpenApi } from "../betterAuthOpenApi-DAAhMZff.mjs";
5
5
  import { createHmac, randomUUID, timingSafeEqual } from "node:crypto";
6
6
  import fp from "fastify-plugin";
7
7
  //#region src/auth/authPlugin.ts
@@ -611,7 +611,7 @@ function createBetterAuthAdapter(options) {
611
611
  if (!fastify.hasDecorator("authenticate")) fastify.decorate("authenticate", authenticate);
612
612
  if (!fastify.hasDecorator("optionalAuthenticate")) fastify.decorate("optionalAuthenticate", optionalAuthenticate);
613
613
  if (!extractedOpenApi && openapiOpt !== false && auth.api && typeof auth.api === "object") {
614
- const { extractBetterAuthOpenApi } = await import("../betterAuthOpenApi-ClWxaceA.mjs").then((n) => n.t);
614
+ const { extractBetterAuthOpenApi } = await import("../betterAuthOpenApi-DAAhMZff.mjs").then((n) => n.t);
615
615
  extractedOpenApi = extractBetterAuthOpenApi(auth.api, {
616
616
  basePath,
617
617
  userFields
@@ -1,4 +1,4 @@
1
- import { i as SessionData, s as SessionStore } from "../sessionManager-DlmaHUAl.mjs";
1
+ import { i as SessionData, s as SessionStore } from "../sessionManager-CyHpYXoB.mjs";
2
2
 
3
3
  //#region src/auth/redis-session.d.ts
4
4
  /** Minimal Redis client interface — compatible with ioredis */
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
2
- import { a as toJsonSchema } from "./schemaConverter-De34B1ZG.mjs";
2
+ import { a as toJsonSchema } from "./schemaConverter-DatAaVNj.mjs";
3
3
  //#region src/auth/betterAuthOpenApi.ts
4
4
  var betterAuthOpenApi_exports = /* @__PURE__ */ __exportAll({ extractBetterAuthOpenApi: () => extractBetterAuthOpenApi });
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { n as compileAggRequest, t as adapterSupportsAggregate } from "./validate-DFIP2VrM.mjs";
1
+ import { i as compileAggRequest, t as adapterSupportsAggregate } from "./validate-0__MuUsK.mjs";
2
2
  //#region src/core/aggregation/buildHandler.ts
3
3
  /**
4
4
  * Framework-agnostic aggregation execution. Runs safety guards,
@@ -1,6 +1,6 @@
1
- import { n as CacheStats, r as CacheStore, t as CacheLogger } from "../interface-BVkZsvEe.mjs";
2
- import { a as QueryCacheConfig, i as QueryCache, n as CacheResult, r as CacheStatus, t as CacheEnvelope } from "../QueryCache-8YmAQ-zW.mjs";
3
- import { i as queryCachePlugin, n as QueryCacheDefaults, r as QueryCachePluginOptions, t as CrossResourceRule } from "../queryCachePlugin-Do4P_WBC.mjs";
1
+ import { n as CacheStats, r as CacheStore, t as CacheLogger } from "../interface-DL7LlWS5.mjs";
2
+ import { a as QueryCacheConfig, i as QueryCache, n as CacheResult, r as CacheStatus, t as CacheEnvelope } from "../QueryCache-Dsyv2mLS.mjs";
3
+ import { i as queryCachePlugin, n as QueryCacheDefaults, r as QueryCachePluginOptions, t as CrossResourceRule } from "../queryCachePlugin-Bd2tYgh5.mjs";
4
4
 
5
5
  //#region src/cache/keys.d.ts
6
6
  /**
@@ -1,6 +1,6 @@
1
- import { t as MemoryCacheStore } from "../memory-QOLe11D5.mjs";
2
- import { i as versionKey, n as hashParams, r as tagVersionKey, t as buildQueryKey } from "../keys-DopsCuyQ.mjs";
3
- import { r as QueryCache, t as queryCachePlugin } from "../queryCachePlugin-B4XMSSe7.mjs";
1
+ import { t as MemoryCacheStore } from "../memory-TdTHCS9-.mjs";
2
+ import { i as versionKey, n as hashParams, r as tagVersionKey, t as buildQueryKey } from "../keys-B3yyBEyH.mjs";
3
+ import { r as QueryCache, t as queryCachePlugin } from "../queryCachePlugin-CnAeFqju.mjs";
4
4
  //#region src/cache/redis.ts
5
5
  /**
6
6
  * Redis-backed cache store.
@@ -1,4 +1,4 @@
1
- import { V as ResourceDefinition, it as RateLimitConfig, mt as RouteSchemaOptions } from "../../index-C000faom.mjs";
1
+ import { V as ResourceDefinition, it as RateLimitConfig, mt as RouteSchemaOptions } from "../../index-QYma8mdC.mjs";
2
2
 
3
3
  //#region src/cli/commands/describe.d.ts
4
4
  interface DescribedResource {
@@ -1,5 +1,5 @@
1
1
  import { t as CRUD_OPERATIONS } from "../../constants-TrJVIJl0.mjs";
2
- import { n as stringifyMeasureMap } from "../../ResourceRegistry-CzSzVK1m.mjs";
2
+ import { n as stringifyMeasureMap } from "../../ResourceRegistry-CWmOggxS.mjs";
3
3
  import { resolve } from "node:path";
4
4
  import { pathToFileURL } from "node:url";
5
5
  //#region src/cli/commands/describe.ts
@@ -1,5 +1,5 @@
1
- import { t as buildOpenApiSpec } from "../../openapi-CLZx9bwS.mjs";
2
- import { t as loadResourcesFromEntry } from "../../loadResourcesFromEntry-DCjYMgfC.mjs";
1
+ import { t as buildOpenApiSpec } from "../../openapi-ButnRyOM.mjs";
2
+ import { t as loadResourcesFromEntry } from "../../loadResourcesFromEntry-XHNeUWpu.mjs";
3
3
  import { dirname, resolve } from "node:path";
4
4
  import { mkdirSync, writeFileSync } from "node:fs";
5
5
  //#region src/cli/commands/docs.ts
@@ -1,2 +1,2 @@
1
- import { n as generate, t as ArcProjectConfig } from "../../generate-cRnsafMS.mjs";
1
+ import { n as generate, t as ArcProjectConfig } from "../../generate-Dmk8cfvX.mjs";
2
2
  export { ArcProjectConfig, generate };
@@ -1,2 +1,2 @@
1
- import { t as generate } from "../../generate-CcM24hoq.mjs";
1
+ import { t as generate } from "../../generate-BaxDdmJ8.mjs";
2
2
  export { generate };
@@ -1,2 +1,2 @@
1
- import { a as ProjectConfig, i as PackageManager, n as DependencyManifest, r as InitOptions, t as init } from "../../init-D-vrTZ1G.mjs";
1
+ import { a as ProjectConfig, i as PackageManager, n as DependencyManifest, r as InitOptions, t as init } from "../../init-BS4Daqnv.mjs";
2
2
  export { DependencyManifest, InitOptions, PackageManager, ProjectConfig, init };
@@ -1,2 +1,2 @@
1
- import { t as init } from "../../init-DQ_rY1J7.mjs";
1
+ import { t as init } from "../../init-DSsdRfk9.mjs";
2
2
  export { init };
@@ -1,4 +1,4 @@
1
- import { t as loadResourcesFromEntry } from "../../loadResourcesFromEntry-DCjYMgfC.mjs";
1
+ import { t as loadResourcesFromEntry } from "../../loadResourcesFromEntry-XHNeUWpu.mjs";
2
2
  //#region src/cli/commands/introspect.ts
3
3
  function describePermission(value) {
4
4
  if (!value) return "none";
@@ -1,7 +1,7 @@
1
1
  import { describe } from "./commands/describe.mjs";
2
2
  import { exportDocs } from "./commands/docs.mjs";
3
3
  import { doctor } from "./commands/doctor.mjs";
4
- import { n as generate } from "../generate-cRnsafMS.mjs";
5
- import { t as init } from "../init-D-vrTZ1G.mjs";
4
+ import { n as generate } from "../generate-Dmk8cfvX.mjs";
5
+ import { t as init } from "../init-BS4Daqnv.mjs";
6
6
  import { introspect } from "./commands/introspect.mjs";
7
7
  export { describe, doctor, exportDocs, generate, init, introspect };
@@ -1,7 +1,7 @@
1
1
  import { describe } from "./commands/describe.mjs";
2
2
  import { exportDocs } from "./commands/docs.mjs";
3
3
  import { doctor } from "./commands/doctor.mjs";
4
- import { t as generate } from "../generate-CcM24hoq.mjs";
5
- import { t as init } from "../init-DQ_rY1J7.mjs";
4
+ import { t as generate } from "../generate-BaxDdmJ8.mjs";
5
+ import { t as init } from "../init-DSsdRfk9.mjs";
6
6
  import { introspect } from "./commands/introspect.mjs";
7
7
  export { describe, doctor, exportDocs, generate, init, introspect };
@@ -1,3 +1,3 @@
1
- import { $t as BaseController, At as AggregationRateLimit, B as defineResource, Cn as AccessControlConfig, Ct as AggMeasureShorthand, Dt as AggregationIndexHint, Et as AggregationDateRangeRequirement, Ot as AggregationMaterializedContext, Sn as AccessControl, St as AggMeasureInput, Tt as AggregationConfig, V as ResourceDefinition, an as SlugMixin, bn as BodySanitizer, cn as BaseControllerOptions, dn as ControllerConstructionOptions, en as SoftDeleteExt, fn as QueryResolver, in as SlugExt, jt as AggregationsMap, kt as AggregationMaterializedResult, ln as BaseCrudController, nn as TreeExt, on as BulkExt, pn as QueryResolverConfig, rn as TreeMixin, sn as BulkMixin, tn as SoftDeleteMixin, un as ControllerConfigurableOptions, wt as AggregationCacheConfig, xn as BodySanitizerConfig, yn as ListResult } from "../index-C000faom.mjs";
2
- import { A as MAX_FILTER_DEPTH, C as DEFAULT_SORT, D as HOOK_PHASES, E as HOOK_OPERATIONS, F as RESERVED_QUERY_PARAMS, I as SYSTEM_FIELDS, M as MAX_SEARCH_LENGTH, N as MUTATION_OPERATIONS, O as HookOperation, P as MutationOperation, S as DEFAULT_MAX_LIMIT, T as DEFAULT_UPDATE_METHOD, _ as defineAggregation, a as createRequestContext, b as DEFAULT_ID_FIELD, c as sendControllerResponse, d as getEntityQuery, f as defineResourceVariants, g as createPermissionMiddleware, h as createCrudRouter, i as createFastifyHandler, j as MAX_REGEX_LENGTH, k as HookPhase, l as getEntityId, m as defineAction, n as isFieldReadable, o as getControllerContext, p as DefineActionConfig, r as createCrudHandlers, s as getControllerScope, t as collectReadBlockedFields, u as getEntityIdField, v as CRUD_OPERATIONS, w as DEFAULT_TENANT_FIELD, x as DEFAULT_LIMIT, y as CrudOperation } from "../index-CNiryUMN.mjs";
1
+ import { $t as BaseController, At as AggregationRateLimit, B as defineResource, Ct as AggMeasureShorthand, Dt as AggregationIndexHint, Et as AggregationDateRangeRequirement, Fn as ControllerConfigurableOptions, In as ControllerConstructionOptions, Ln as ListResult, Ot as AggregationMaterializedContext, Pn as BaseControllerOptions, Rn as BodySanitizer, St as AggMeasureInput, Tt as AggregationConfig, V as ResourceDefinition, an as SlugMixin, cn as BaseCrudController, dn as AccessControl, en as SoftDeleteExt, fn as AccessControlConfig, in as SlugExt, jt as AggregationsMap, kt as AggregationMaterializedResult, ln as QueryResolver, nn as TreeExt, on as BulkExt, rn as TreeMixin, sn as BulkMixin, tn as SoftDeleteMixin, un as QueryResolverConfig, wt as AggregationCacheConfig, zn as BodySanitizerConfig } from "../index-QYma8mdC.mjs";
2
+ import { A as MAX_FILTER_DEPTH, C as DEFAULT_SORT, D as HOOK_PHASES, E as HOOK_OPERATIONS, F as RESERVED_QUERY_PARAMS, I as SYSTEM_FIELDS, M as MAX_SEARCH_LENGTH, N as MUTATION_OPERATIONS, O as HookOperation, P as MutationOperation, S as DEFAULT_MAX_LIMIT, T as DEFAULT_UPDATE_METHOD, _ as defineAggregation, a as createRequestContext, b as DEFAULT_ID_FIELD, c as sendControllerResponse, d as getEntityQuery, f as defineResourceVariants, g as createPermissionMiddleware, h as createCrudRouter, i as createFastifyHandler, j as MAX_REGEX_LENGTH, k as HookPhase, l as getEntityId, m as defineAction, n as isFieldReadable, o as getControllerContext, p as DefineActionConfig, r as createCrudHandlers, s as getControllerScope, t as collectReadBlockedFields, u as getEntityIdField, v as CRUD_OPERATIONS, w as DEFAULT_TENANT_FIELD, x as DEFAULT_LIMIT, y as CrudOperation } from "../index-Cvo1u9n6.mjs";
3
3
  export { AccessControl, AccessControlConfig, AggMeasureInput, AggMeasureShorthand, AggregationCacheConfig, AggregationConfig, AggregationDateRangeRequirement, AggregationIndexHint, AggregationMaterializedContext, AggregationMaterializedResult, AggregationRateLimit, AggregationsMap, BaseController, BaseControllerOptions, BaseCrudController, BodySanitizer, BodySanitizerConfig, BulkExt, BulkMixin, CRUD_OPERATIONS, ControllerConfigurableOptions, ControllerConstructionOptions, CrudOperation, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, DefineActionConfig, HOOK_OPERATIONS, HOOK_PHASES, HookOperation, HookPhase, ListResult, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, MutationOperation, QueryResolver, QueryResolverConfig, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, SlugExt, SlugMixin, SoftDeleteExt, SoftDeleteMixin, TreeExt, TreeMixin, collectReadBlockedFields, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineAction, defineAggregation, defineResource, defineResourceVariants, getControllerContext, getControllerScope, getEntityId, getEntityIdField, getEntityQuery, isFieldReadable, sendControllerResponse };
@@ -1,5 +1,5 @@
1
1
  import { a as DEFAULT_SORT, c as HOOK_OPERATIONS, d as MAX_REGEX_LENGTH, f as MAX_SEARCH_LENGTH, h as SYSTEM_FIELDS, i as DEFAULT_MAX_LIMIT, l as HOOK_PHASES, m as RESERVED_QUERY_PARAMS, n as DEFAULT_ID_FIELD, o as DEFAULT_TENANT_FIELD, p as MUTATION_OPERATIONS, r as DEFAULT_LIMIT, s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS, u as MAX_FILTER_DEPTH } from "../constants-TrJVIJl0.mjs";
2
- import { a as BulkMixin, c as collectReadBlockedFields, i as SlugMixin, l as isFieldReadable, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, s as QueryResolver, t as BaseController, u as AccessControl } from "../BaseController-DPwe89qs.mjs";
3
- import { S as sendControllerResponse, _ as createCrudHandlers, b as getControllerContext, v as createFastifyHandler, w as BodySanitizer, x as getControllerScope, y as createRequestContext } from "../routerShared-Dl0A77Ba.mjs";
4
- import { a as defineResource, c as createCrudRouter, i as defineResourceVariants, l as createPermissionMiddleware, n as getEntityIdField, o as ResourceDefinition, r as getEntityQuery, s as defineAction, t as getEntityId, u as defineAggregation } from "../core-B41eZxyM.mjs";
2
+ import { a as BulkMixin, c as collectReadBlockedFields, f as AccessControl, i as SlugMixin, l as isFieldReadable, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, s as QueryResolver, t as BaseController, u as BodySanitizer } from "../BaseController-B-uXzf6I.mjs";
3
+ import { a as defineResource, c as createCrudRouter, i as defineResourceVariants, l as createPermissionMiddleware, n as getEntityIdField, o as ResourceDefinition, r as getEntityQuery, s as defineAction, t as getEntityId, u as defineAggregation } from "../core-C88uIwd3.mjs";
4
+ import { a as createFastifyHandler, c as getControllerScope, i as createCrudHandlers, l as sendControllerResponse, o as createRequestContext, s as getControllerContext } from "../pipeline-D4sqiokR.mjs";
5
5
  export { AccessControl, BaseController, BaseCrudController, BodySanitizer, BulkMixin, CRUD_OPERATIONS, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, HOOK_OPERATIONS, HOOK_PHASES, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, QueryResolver, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, SlugMixin, SoftDeleteMixin, TreeMixin, collectReadBlockedFields, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineAction, defineAggregation, defineResource, defineResourceVariants, getControllerContext, getControllerScope, getEntityId, getEntityIdField, getEntityQuery, isFieldReadable, sendControllerResponse };
@@ -1,13 +1,58 @@
1
1
  import { s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS } from "./constants-TrJVIJl0.mjs";
2
2
  import { arcLog } from "./logger/index.mjs";
3
- import { N as assertValidConfig, f as getDefaultCrudSchemas, i as pipeUIMessageStreamToReply, r as isReadableStream } from "./utils-BMQK8mRl.mjs";
4
- import { t as BaseController } from "./BaseController-DPwe89qs.mjs";
5
- import { t as applyPresets } from "./presets-BYbPobbF.mjs";
6
- import { n as convertRouteSchema, t as convertOpenApiSchemas } from "./schemaConverter-De34B1ZG.mjs";
7
- import { t as hasEvents } from "./typeGuards-BzkXkvVv.mjs";
8
- import { C as buildRequestScopeProjection, _ as createCrudHandlers, c as buildPipelineHandler, d as methodCarriesBody, f as resolvePipelineSteps, g as tryRegisterRoute, h as selectPluginMw, i as buildAuthMiddleware, l as buildPreHandlerChain, m as resolveRouterPluginMw, o as buildCrudPermissionMw, p as resolveRoutePreHandlers, r as buildArcDecorator, s as buildFieldWritePreHandler, u as buildRateLimitConfig, v as createFastifyHandler, y as createRequestContext } from "./routerShared-Dl0A77Ba.mjs";
9
- import { t as pluralize } from "./pluralize-B9M8xvy-.mjs";
10
- import { t as resolveActionPermission } from "./actionPermissions-Bjmvn7Eb.mjs";
3
+ import { r as ForbiddenError } from "./errors-j4aJm1Wg.mjs";
4
+ import { b as isElevated, n as PUBLIC_SCOPE, x as isMember } from "./types-Bi0r0vjG.mjs";
5
+ import { N as assertValidConfig, f as getDefaultCrudSchemas, i as pipeUIMessageStreamToReply, r as isReadableStream } from "./utils-xAQeDyU_.mjs";
6
+ import { d as DEFAULT_FIELD_WRITE_DENIAL_POLICY, t as BaseController } from "./BaseController-B-uXzf6I.mjs";
7
+ import { a as resolveRoutePreHandlers, c as buildArcDecorator, i as buildPreHandlerChain, n as resolveRouterPluginMw, o as buildAuthMiddleware, r as selectPluginMw, t as buildRateLimitConfig } from "./rateLimit-yKvxWAky.mjs";
8
+ import { F as applyFieldWritePermissions, L as resolveEffectiveRoles } from "./permissions-3uzwkbQt.mjs";
9
+ import { t as getUserRoles } from "./types-D57iXYb8.mjs";
10
+ import { r as buildCrudPermissionMw, t as tryRegisterRoute } from "./registerRoute-BEYn0ylk.mjs";
11
+ import { t as applyPresets } from "./presets-CF79RHEo.mjs";
12
+ import { n as convertRouteSchema, t as convertOpenApiSchemas } from "./schemaConverter-DatAaVNj.mjs";
13
+ import { t as hasEvents } from "./typeGuards-CcFZXgU7.mjs";
14
+ import { a as createFastifyHandler, i as createCrudHandlers, n as buildPipelineHandler, o as createRequestContext, r as resolvePipelineSteps, u as buildRequestScopeProjection } from "./pipeline-D4sqiokR.mjs";
15
+ import { t as pluralize } from "./pluralize-BxdUl2P4.mjs";
16
+ import { t as resolveActionPermission } from "./actionPermissions-CX9QIMTd.mjs";
17
+ //#region src/core/middlewares/fieldWrite.ts
18
+ /**
19
+ * Build a preHandler that enforces field-write permissions on the request body.
20
+ *
21
+ * Auto-CRUD's create/update routes get this for free via `BodySanitizer.sanitize()`
22
+ * inside `BaseController`. Custom routes (`config.routes`, presets, action endpoints)
23
+ * never went through that path — so a host that declared
24
+ * `fields: { role: fields.writableBy(['admin']) }` and a custom
25
+ * `POST /users/promote` happily accepted `{ role: 'admin' }` from any caller.
26
+ *
27
+ * This preHandler closes that gap. It applies ONLY the `applyFieldWritePermissions`
28
+ * step — no `SYSTEM_FIELDS` strip, no `fieldRules` strip — because custom-route
29
+ * bodies don't necessarily mirror the resource's adapter shape, and we'd
30
+ * generate surprising 403s by enforcing rules tied to that shape.
31
+ *
32
+ * Returns `null` when the resource has no field permissions configured — the
33
+ * caller should then skip wiring it into the preHandler chain.
34
+ */
35
+ function buildFieldWritePreHandler(fieldPermissions, policy = DEFAULT_FIELD_WRITE_DENIAL_POLICY) {
36
+ if (!fieldPermissions || Object.keys(fieldPermissions).length === 0) return null;
37
+ return async (request, _reply) => {
38
+ const body = request.body;
39
+ if (!body || typeof body !== "object" || Array.isArray(body)) return;
40
+ const scope = request.scope ?? PUBLIC_SCOPE;
41
+ if (isElevated(scope)) return;
42
+ const { body: filtered, deniedFields } = applyFieldWritePermissions(body, fieldPermissions, resolveEffectiveRoles(getUserRoles(request.user), isMember(scope) ? scope.orgRoles : []));
43
+ if (deniedFields.length > 0 && policy === "reject") throw new ForbiddenError(`Not permitted to write field${deniedFields.length === 1 ? "" : "s"}: ${deniedFields.join(", ")}`);
44
+ request.body = filtered;
45
+ };
46
+ }
47
+ /**
48
+ * True for HTTP methods that carry a request body and should run the
49
+ * field-write preHandler. GET/DELETE/HEAD/OPTIONS skip enforcement.
50
+ */
51
+ function methodCarriesBody(method) {
52
+ const m = method.toUpperCase();
53
+ return m === "POST" || m === "PUT" || m === "PATCH";
54
+ }
55
+ //#endregion
11
56
  //#region src/core/aggregation/defineAggregation.ts
12
57
  /**
13
58
  * Declare a single resource aggregation. Exported configs flow into
@@ -597,6 +642,111 @@ function resolveIdField(config, repository) {
597
642
  return config;
598
643
  }
599
644
  //#endregion
645
+ //#region src/core/defineResource/normalizeConfig.ts
646
+ /**
647
+ * Run all Phase-0 expansions in order and return the canonical config.
648
+ *
649
+ * The `crud:` allow-list resolves LAST and is lifted BEFORE validation
650
+ * so the validator sees the resolved shape: `crud: false` looks like
651
+ * `disableDefaultRoutes: true` (no adapter required) instead of "CRUD
652
+ * enabled but no adapter" (a confusing false-positive error).
653
+ */
654
+ function normalizeResourceConfig(config) {
655
+ return resolveCrudAllowList(expandCustomRoutesOnly(expandReferenceData(config)));
656
+ }
657
+ /**
658
+ * Expand the `referenceData: true` shorthand. Reference data is the
659
+ * recurring "small static catalogue" shape (currencies, plans,
660
+ * pipeline stages, credential types) where callers want "fetch all"
661
+ * semantics and aggressive caching — pre-2.17.0 hosts hand-wired
662
+ * `crud` + `defaultLimit` + `maxLimit` + `cache` on every such
663
+ * resource. The shorthand pins canonical defaults; explicit narrow
664
+ * settings always win so a host can opt INTO mutations
665
+ * (`referenceData: true, crud: { list: true, get: true, create: true }`)
666
+ * or override the cache window without giving up the read-only +
667
+ * fetch-all defaults.
668
+ */
669
+ function expandReferenceData(config) {
670
+ if (config.referenceData !== true) return config;
671
+ return {
672
+ ...config,
673
+ crud: config.crud ?? {
674
+ list: true,
675
+ get: true
676
+ },
677
+ defaultLimit: config.defaultLimit ?? 1e3,
678
+ maxLimit: config.maxLimit ?? 1e3,
679
+ cache: config.cache ?? {
680
+ staleTime: 300,
681
+ gcTime: 600
682
+ }
683
+ };
684
+ }
685
+ /**
686
+ * Expand the `customRoutesOnly: true` shorthand into its three primitive
687
+ * flags. The shorthand exists because hosts wiring a "service resource"
688
+ * (custom routes only, no adapter, no auto-CRUD) had to remember to set
689
+ * `disableDefaultRoutes` + `skipValidation` + `skipRegistry` in lockstep —
690
+ * forgetting any one of them produced confusing errors ("controller
691
+ * required when CRUD routes are enabled" for a resource that ships none).
692
+ *
693
+ * Explicit narrow settings always win — the shorthand only fills in
694
+ * flags that were not set so power users can opt back into a specific
695
+ * primitive (`customRoutesOnly: true, skipRegistry: false` keeps OpenAPI
696
+ * docs while still skipping CRUD + validation).
697
+ */
698
+ function expandCustomRoutesOnly(config) {
699
+ if (config.customRoutesOnly !== true) return config;
700
+ return {
701
+ ...config,
702
+ customRoutesOnly: void 0,
703
+ disableDefaultRoutes: config.disableDefaultRoutes ?? true,
704
+ skipValidation: config.skipValidation ?? true,
705
+ skipRegistry: config.skipRegistry ?? true
706
+ };
707
+ }
708
+ /**
709
+ * Normalise the 2.16 `crud:` positive-form allow-list into the canonical
710
+ * `{ disabledRoutes, disableDefaultRoutes }` pair the rest of arc reads.
711
+ *
712
+ * Three input forms collapse to one output:
713
+ * - `crud: false` → `disableDefaultRoutes: true`
714
+ * - `crud: { list: true }` → `disabledRoutes: [get,create,update,delete]`
715
+ * - legacy `disabledRoutes` → passed through unchanged
716
+ *
717
+ * Mutually exclusive: `crud` + `disabledRoutes` together is a config bug
718
+ * (the host meant ONE of two intents) — throw rather than pick.
719
+ *
720
+ * Lifted out of the `ResourceDefinition` constructor in 2.16 so the
721
+ * validator (Phase 1) observes the post-resolve shape — `crud: false`
722
+ * now looks like `disableDefaultRoutes: true` to the validator, so it
723
+ * doesn't false-positive "Data adapter required when CRUD routes are
724
+ * enabled" on a host that explicitly opted CRUD out.
725
+ */
726
+ function resolveCrudAllowList(config) {
727
+ const { crud, disabledRoutes: legacyDisabled, disableDefaultRoutes: legacyDisableAll } = config;
728
+ if (crud === void 0) return config;
729
+ if (legacyDisabled !== void 0) throw new Error(`[Arc] Resource '${config.name}': pass either \`crud\` (positive allow-list) or \`disabledRoutes\` (negative opt-out), not both. The positive form is the documented default going forward; drop \`disabledRoutes\` when both are set.`);
730
+ if (crud === false) return {
731
+ ...config,
732
+ crud: void 0,
733
+ disableDefaultRoutes: true
734
+ };
735
+ const disabled = [
736
+ "list",
737
+ "get",
738
+ "create",
739
+ "update",
740
+ "delete"
741
+ ].filter((op) => crud[op] !== true);
742
+ return {
743
+ ...config,
744
+ crud: void 0,
745
+ disabledRoutes: disabled,
746
+ disableDefaultRoutes: legacyDisableAll ?? false
747
+ };
748
+ }
749
+ //#endregion
600
750
  //#region src/core/schemaOptions.ts
601
751
  /**
602
752
  * Inject the tenant-scoping field rule into `schemaOptions.fieldRules`:
@@ -1096,7 +1246,7 @@ function buildResourcePlugin(resource) {
1096
1246
  idField: resource.idField
1097
1247
  });
1098
1248
  if (resource.actions && Object.keys(resource.actions).length > 0) {
1099
- const { createActionRouter } = await import("./createActionRouter-CRaIwB5S.mjs").then((n) => n.n);
1249
+ const { createActionRouter } = await import("./createActionRouter-DGCCp-kP.mjs").then((n) => n.n);
1100
1250
  createActionRouter(typedInstance, {
1101
1251
  ...normalizeActionsToRouterConfig(resource.actions, resource.actionPermissions, resource.tag, resource.permissions, resource.name, typedInstance.log),
1102
1252
  resourceName: resource.name,
@@ -1110,7 +1260,7 @@ function buildResourcePlugin(resource) {
1110
1260
  });
1111
1261
  }
1112
1262
  if (resource.aggregations && Object.keys(resource.aggregations).length > 0) {
1113
- const [{ createAggregationRouter }, { adapterSupportsAggregate, ArcAggregationConfigError }] = await Promise.all([import("./createAggregationRouter-n3O6WdLO.mjs"), import("./validate-DFIP2VrM.mjs").then((n) => n.i)]);
1263
+ const [{ createAggregationRouter }, { adapterSupportsAggregate, ArcAggregationConfigError }] = await Promise.all([import("./createAggregationRouter-Ca77b8iK.mjs"), import("./validate-0__MuUsK.mjs").then((n) => n.r)]);
1114
1264
  const repoForAgg = resource.controller?.repository ?? resource.repository;
1115
1265
  if (!adapterSupportsAggregate(repoForAgg)) {
1116
1266
  const undispatchable = Object.entries(resource.aggregations).filter(([, cfg]) => !cfg.materialized).map(([name]) => name);
@@ -1659,7 +1809,7 @@ function validateActionsShape(config) {
1659
1809
  //#endregion
1660
1810
  //#region src/core/defineResource.ts
1661
1811
  function defineResource(config) {
1662
- const normalisedConfig = resolveCrudAllowList(expandCustomRoutesOnly(expandReferenceData(config)));
1812
+ const normalisedConfig = normalizeResourceConfig(config);
1663
1813
  let diagnostics = [];
1664
1814
  if (!normalisedConfig.skipValidation) diagnostics = validateDefineResourceConfig(normalisedConfig);
1665
1815
  const repository = normalisedConfig.adapter?.repository;
@@ -1683,98 +1833,6 @@ function defineResource(config) {
1683
1833
  if (diagnostics.length > 0) resource._diagnostics = diagnostics;
1684
1834
  return resource;
1685
1835
  }
1686
- /**
1687
- * Normalise the 2.16 `crud:` positive-form allow-list into the canonical
1688
- * `{ disabledRoutes, disableDefaultRoutes }` pair the rest of arc reads.
1689
- *
1690
- * Three input forms collapse to one output:
1691
- * - `crud: false` → `disableDefaultRoutes: true`
1692
- * - `crud: { list: true }` → `disabledRoutes: [get,create,update,delete]`
1693
- * - legacy `disabledRoutes` → passed through unchanged
1694
- *
1695
- * Mutually exclusive: `crud` + `disabledRoutes` together is a config bug
1696
- * (the host meant ONE of two intents) — throw rather than pick.
1697
- *
1698
- * Lifted out of the `ResourceDefinition` constructor in 2.16 so the
1699
- * validator (Phase 1) observes the post-resolve shape — `crud: false`
1700
- * now looks like `disableDefaultRoutes: true` to the validator, so it
1701
- * doesn't false-positive "Data adapter required when CRUD routes are
1702
- * enabled" on a host that explicitly opted CRUD out.
1703
- */
1704
- /**
1705
- * Expand the `referenceData: true` shorthand. Reference data is the
1706
- * recurring "small static catalogue" shape (currencies, plans,
1707
- * pipeline stages, credential types) where callers want "fetch all"
1708
- * semantics and aggressive caching — pre-2.17.0 hosts hand-wired
1709
- * `crud` + `defaultLimit` + `maxLimit` + `cache` on every such
1710
- * resource. The shorthand pins canonical defaults; explicit narrow
1711
- * settings always win so a host can opt INTO mutations
1712
- * (`referenceData: true, crud: { list: true, get: true, create: true }`)
1713
- * or override the cache window without giving up the read-only +
1714
- * fetch-all defaults.
1715
- */
1716
- function expandReferenceData(config) {
1717
- if (config.referenceData !== true) return config;
1718
- return {
1719
- ...config,
1720
- crud: config.crud ?? {
1721
- list: true,
1722
- get: true
1723
- },
1724
- defaultLimit: config.defaultLimit ?? 1e3,
1725
- maxLimit: config.maxLimit ?? 1e3,
1726
- cache: config.cache ?? {
1727
- staleTime: 300,
1728
- gcTime: 600
1729
- }
1730
- };
1731
- }
1732
- /**
1733
- * Expand the `customRoutesOnly: true` shorthand into its three primitive
1734
- * flags. The shorthand exists because hosts wiring a "service resource"
1735
- * (custom routes only, no adapter, no auto-CRUD) had to remember to set
1736
- * `disableDefaultRoutes` + `skipValidation` + `skipRegistry` in lockstep —
1737
- * forgetting any one of them produced confusing errors ("controller
1738
- * required when CRUD routes are enabled" for a resource that ships none).
1739
- *
1740
- * Explicit narrow settings always win — the shorthand only fills in
1741
- * flags that were not set so power users can opt back into a specific
1742
- * primitive (`customRoutesOnly: true, skipRegistry: false` keeps OpenAPI
1743
- * docs while still skipping CRUD + validation).
1744
- */
1745
- function expandCustomRoutesOnly(config) {
1746
- if (config.customRoutesOnly !== true) return config;
1747
- return {
1748
- ...config,
1749
- customRoutesOnly: void 0,
1750
- disableDefaultRoutes: config.disableDefaultRoutes ?? true,
1751
- skipValidation: config.skipValidation ?? true,
1752
- skipRegistry: config.skipRegistry ?? true
1753
- };
1754
- }
1755
- function resolveCrudAllowList(config) {
1756
- const { crud, disabledRoutes: legacyDisabled, disableDefaultRoutes: legacyDisableAll } = config;
1757
- if (crud === void 0) return config;
1758
- if (legacyDisabled !== void 0) throw new Error(`[Arc] Resource '${config.name}': pass either \`crud\` (positive allow-list) or \`disabledRoutes\` (negative opt-out), not both. The positive form is the documented default going forward; drop \`disabledRoutes\` when both are set.`);
1759
- if (crud === false) return {
1760
- ...config,
1761
- crud: void 0,
1762
- disableDefaultRoutes: true
1763
- };
1764
- const disabled = [
1765
- "list",
1766
- "get",
1767
- "create",
1768
- "update",
1769
- "delete"
1770
- ].filter((op) => crud[op] !== true);
1771
- return {
1772
- ...config,
1773
- crud: void 0,
1774
- disabledRoutes: disabled,
1775
- disableDefaultRoutes: legacyDisableAll ?? false
1776
- };
1777
- }
1778
1836
  //#endregion
1779
1837
  //#region src/core/defineResourceVariants.ts
1780
1838
  /**
@@ -1,8 +1,10 @@
1
1
  import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
2
2
  import "./constants-TrJVIJl0.mjs";
3
3
  import { f as createError } from "./errors-j4aJm1Wg.mjs";
4
- import { S as sendControllerResponse, a as buildAuthMiddlewareForPermissions, f as resolvePipelineSteps, g as tryRegisterRoute, h as selectPluginMw, l as buildPreHandlerChain, m as resolveRouterPluginMw, n as buildActionPipelineHandler, r as buildArcDecorator, t as buildActionPermissionMw, u as buildRateLimitConfig } from "./routerShared-Dl0A77Ba.mjs";
5
- import { n as schemaIRToJsonSchemaBranch, t as normalizeSchemaIR } from "./schemaIR-Bk6Tns82.mjs";
4
+ import { c as buildArcDecorator, i as buildPreHandlerChain, n as resolveRouterPluginMw, r as selectPluginMw, s as buildAuthMiddlewareForPermissions, t as buildRateLimitConfig } from "./rateLimit-yKvxWAky.mjs";
5
+ import { n as buildActionPermissionMw, t as tryRegisterRoute } from "./registerRoute-BEYn0ylk.mjs";
6
+ import { l as sendControllerResponse, r as resolvePipelineSteps, t as buildActionPipelineHandler } from "./pipeline-D4sqiokR.mjs";
7
+ import { n as schemaIRToJsonSchemaBranch, t as normalizeSchemaIR } from "./schemaIR-CE6USIRi.mjs";
6
8
  //#region src/core/createActionRouter.ts
7
9
  var createActionRouter_exports = /* @__PURE__ */ __exportAll({
8
10
  buildActionBodySchema: () => buildActionBodySchema,
@@ -1,7 +1,7 @@
1
1
  import { f as createError, l as UnauthorizedError, r as ForbiddenError } from "./errors-j4aJm1Wg.mjs";
2
- import { h as selectPluginMw, i as buildAuthMiddleware, l as buildPreHandlerChain, m as resolveRouterPluginMw, r as buildArcDecorator, u as buildRateLimitConfig } from "./routerShared-Dl0A77Ba.mjs";
3
- import { r as validateAggregations } from "./validate-DFIP2VrM.mjs";
4
- import { t as buildAggregationHandler } from "./buildHandler-C_SkBNF3.mjs";
2
+ import { c as buildArcDecorator, i as buildPreHandlerChain, n as resolveRouterPluginMw, o as buildAuthMiddleware, r as selectPluginMw, t as buildRateLimitConfig } from "./rateLimit-yKvxWAky.mjs";
3
+ import { n as validateAggregations } from "./validate-0__MuUsK.mjs";
4
+ import { t as buildAggregationHandler } from "./buildHandler-Cvrc2p7r.mjs";
5
5
  //#region src/core/aggregation/createAggregationRouter.ts
6
6
  /**
7
7
  * Register one Fastify route per aggregation. No-op when the map is
@@ -202,7 +202,7 @@ async function registerArcCore(fastify, config, trackPlugin) {
202
202
  await fastify.register(arcCorePlugin, { emitEvents: config.arcPlugins?.emitEvents !== false });
203
203
  trackPlugin("arc-core");
204
204
  if (config.arcPlugins?.events !== false) {
205
- const { default: eventPlugin } = await import("./eventPlugin-Dxp9JlKK.mjs").then((n) => n.n);
205
+ const { default: eventPlugin } = await import("./eventPlugin-Bw4bUDEO.mjs").then((n) => n.n);
206
206
  const eventOpts = typeof config.arcPlugins?.events === "object" ? config.arcPlugins.events : {};
207
207
  await fastify.register(eventPlugin, {
208
208
  ...eventOpts,
@@ -239,15 +239,15 @@ async function registerArcPlugins(fastify, config, trackPlugin, modules) {
239
239
  trackPlugin("arc-graceful-shutdown");
240
240
  }
241
241
  if (config.arcPlugins?.caching) {
242
- const { default: cachingPlugin } = await import("./caching-8MfrrUYU.mjs").then((n) => n.r);
242
+ const { default: cachingPlugin } = await import("./caching-C0DdKiYB.mjs").then((n) => n.r);
243
243
  const opts = config.arcPlugins.caching === true ? {} : config.arcPlugins.caching;
244
244
  await fastify.register(cachingPlugin, opts);
245
245
  trackPlugin("arc-caching", opts);
246
246
  }
247
247
  if (config.arcPlugins?.queryCache) {
248
- const { queryCachePlugin } = await import("./queryCachePlugin-B4XMSSe7.mjs").then((n) => n.n);
248
+ const { queryCachePlugin } = await import("./queryCachePlugin-CnAeFqju.mjs").then((n) => n.n);
249
249
  const opts = config.arcPlugins.queryCache === true ? {} : config.arcPlugins.queryCache;
250
- const store = config.stores?.queryCache ?? new (await (import("./memory-QOLe11D5.mjs").then((n) => n.n))).MemoryCacheStore();
250
+ const store = config.stores?.queryCache ?? new (await (import("./memory-TdTHCS9-.mjs").then((n) => n.n))).MemoryCacheStore();
251
251
  await fastify.register(queryCachePlugin, {
252
252
  store,
253
253
  ...opts
@@ -256,19 +256,19 @@ async function registerArcPlugins(fastify, config, trackPlugin, modules) {
256
256
  }
257
257
  if (config.arcPlugins?.sse) if (config.arcPlugins?.events === false) fastify.log.warn("SSE plugin requires events plugin (arcPlugins.events). SSE disabled.");
258
258
  else {
259
- const { default: ssePlugin } = await import("./sse-jh5OqFjR.mjs").then((n) => n.r);
259
+ const { default: ssePlugin } = await import("./sse-Xq8UtuQx.mjs").then((n) => n.r);
260
260
  const opts = config.arcPlugins.sse === true ? {} : config.arcPlugins.sse;
261
261
  await fastify.register(ssePlugin, opts);
262
262
  trackPlugin("arc-sse", opts);
263
263
  }
264
264
  if (config.arcPlugins?.metrics) {
265
- const { default: metricsPlugin } = await import("./metrics-B-PU4-Yu.mjs").then((n) => n.r);
265
+ const { default: metricsPlugin } = await import("./metrics-Da2EUPi9.mjs").then((n) => n.r);
266
266
  const opts = config.arcPlugins.metrics === true ? {} : config.arcPlugins.metrics;
267
267
  await fastify.register(metricsPlugin, opts);
268
268
  trackPlugin("arc-metrics", opts);
269
269
  }
270
270
  if (config.arcPlugins?.versioning) {
271
- const { default: versioningPlugin } = await import("./versioning-CuIwUQZ2.mjs").then((n) => n.r);
271
+ const { default: versioningPlugin } = await import("./versioning-C0K8KQLx.mjs").then((n) => n.r);
272
272
  await fastify.register(versioningPlugin, config.arcPlugins.versioning);
273
273
  trackPlugin("arc-versioning", config.arcPlugins.versioning);
274
274
  }
@@ -337,7 +337,7 @@ async function registerAuth(fastify, config, trackPlugin) {
337
337
  */
338
338
  async function registerElevation(fastify, config, trackPlugin) {
339
339
  if (!config.elevation) return;
340
- const { elevationPlugin } = await import("./elevation-6mfTLBC-.mjs").then((n) => n.r);
340
+ const { elevationPlugin } = await import("./elevation-BzhyVWfn.mjs").then((n) => n.r);
341
341
  await fastify.register(elevationPlugin, config.elevation);
342
342
  trackPlugin("arc-elevation", config.elevation);
343
343
  fastify.log.debug("Elevation plugin enabled");
@@ -347,7 +347,7 @@ async function registerElevation(fastify, config, trackPlugin) {
347
347
  */
348
348
  async function registerErrorHandler(fastify, config, trackPlugin) {
349
349
  if (config.errorHandler === false) return;
350
- const { errorHandlerPlugin } = await import("./errorHandler-wQejMBT3.mjs").then((n) => n.r);
350
+ const { errorHandlerPlugin } = await import("./errorHandler-Bua97SEt.mjs").then((n) => n.r);
351
351
  const errorOpts = typeof config.errorHandler === "object" ? config.errorHandler : { includeStack: config.preset !== "production" };
352
352
  await fastify.register(errorHandlerPlugin, errorOpts);
353
353
  trackPlugin("arc-error-handler", errorOpts);
@@ -448,7 +448,7 @@ async function registerResources(fastify, config) {
448
448
  let discoveryPath;
449
449
  let discoveryYieldedZero = false;
450
450
  if (resolvedResources === void 0 && config.resourceDir) {
451
- const { loadResources } = await import("./loadResources-fol6JuvW.mjs").then((n) => n.n);
451
+ const { loadResources } = await import("./loadResources-CwXt9MCh.mjs").then((n) => n.n);
452
452
  const { resolve, dirname } = await import("node:path");
453
453
  const { fileURLToPath } = await import("node:url");
454
454
  const rawDir = config.resourceDir;
@@ -896,7 +896,7 @@ async function createApp(options) {
896
896
  await registerErrorHandler(fastify, config, trackPlugin);
897
897
  await registerResources(fastify, config);
898
898
  if (config.replyHelpers) {
899
- const { replyHelpersPlugin } = await import("./replyHelpers-boS5Rx26.mjs").then((n) => n.n);
899
+ const { replyHelpersPlugin } = await import("./replyHelpers-DXHVxrrj.mjs").then((n) => n.n);
900
900
  await fastify.register(replyHelpersPlugin);
901
901
  }
902
902
  if (config.serializeBigInt) {
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
2
- import { n as createEvent } from "./EventTransport-ClEDfiMS.mjs";
2
+ import { n as createEvent } from "./EventTransport-7LPXLEUX.mjs";
3
3
  //#region src/events/defineEvent.ts
4
4
  /**
5
5
  * defineEvent — Typed Event Definitions with Optional Schema Validation