@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,7 +1,7 @@
1
- import { a as QueryCacheConfig } from "./QueryCache-8YmAQ-zW.mjs";
2
- import { i as RequestScope } from "./types-CfapW2t8.mjs";
3
- import { c as PermissionCheck, d as UserBase, n as FieldPermissionMap } from "./fields-DqZLp5d6.mjs";
4
- import { n as DomainEvent } from "./EventTransport-B1GFiYUy.mjs";
1
+ import { a as QueryCacheConfig } from "./QueryCache-Dsyv2mLS.mjs";
2
+ import { i as RequestScope } from "./types-BJwJN2Pg.mjs";
3
+ import { c as PermissionCheck, d as UserBase, n as FieldPermissionMap } from "./fields-CKLrhyOb.mjs";
4
+ import { n as DomainEvent } from "./EventTransport-CaaXM5Y1.mjs";
5
5
  import { KeysetPaginationResult, OffsetPaginationResult } from "@classytic/repo-core/pagination";
6
6
  import { FastifyInstance, FastifyPluginAsync, FastifyReply, FastifyRequest, RouteHandlerMethod, RouteHandlerMethod as RouteHandlerMethod$1 } from "fastify";
7
7
  import * as _$_classytic_repo_core_adapter0 from "@classytic/repo-core/adapter";
@@ -10,6 +10,183 @@ import { AggDateBucket, AggMeasure, AggTopN, QueryOptions, StandardRepo, TenantP
10
10
  import { LookupSpec } from "@classytic/repo-core/lookup";
11
11
  import { FieldRule, SchemaBuilderOptions } from "@classytic/repo-core/schema";
12
12
 
13
+ //#region src/core/BodySanitizer.d.ts
14
+ /**
15
+ * Policy for handling fields the caller lacks write permission for.
16
+ *
17
+ * - `'reject'` (default, secure): throw 403 listing the denied fields so
18
+ * misconfigurations and attacks surface instead of silently disappearing.
19
+ * - `'strip'` (legacy): silently drop the field and continue. Preserved for
20
+ * apps that relied on the pre-2.9 behaviour — new code should not use it.
21
+ */
22
+ type FieldWriteDenialPolicy = "reject" | "strip";
23
+ interface BodySanitizerConfig {
24
+ /** Schema options for field sanitization */
25
+ schemaOptions: RouteSchemaOptions;
26
+ /**
27
+ * What to do when a request contains fields the caller can't write.
28
+ * Default: `'reject'` — surface the misconfiguration as a 403.
29
+ */
30
+ onFieldWriteDenied?: FieldWriteDenialPolicy;
31
+ }
32
+ declare class BodySanitizer {
33
+ private schemaOptions;
34
+ private onFieldWriteDenied;
35
+ constructor(config: BodySanitizerConfig);
36
+ /**
37
+ * Strip readonly and system-managed fields from request body.
38
+ * Prevents clients from overwriting _id, timestamps, __v, etc.
39
+ *
40
+ * Also applies field-level write permissions when the request has
41
+ * field permission metadata.
42
+ */
43
+ sanitize(body: AnyRecord, _operation: "create" | "update", req?: IRequestContext, meta?: ArcInternalMetadata): AnyRecord;
44
+ }
45
+ //#endregion
46
+ //#region src/core/controllerTypes.d.ts
47
+ /**
48
+ * Union of every return shape repo-core's `MinimalRepo.getAll()` is
49
+ * contractually allowed to produce. See repo-core's `MinimalRepo.getAll`
50
+ * docstring for the three-way split:
51
+ *
52
+ * - `OffsetPaginationResult<TDoc>` — `page` param drives pagination.
53
+ * - `KeysetPaginationResult<TDoc>` — `sort` + optional `after` drives pagination.
54
+ * - `TDoc[]` — raw array when neither drives pagination.
55
+ *
56
+ * Arc passes the kit's response verbatim; consumers narrow on shape.
57
+ */
58
+ type ListResult<TDoc> = OffsetPaginationResult<TDoc> | KeysetPaginationResult<TDoc> | TDoc[];
59
+ /**
60
+ * Discrete cache states reported via the `x-cache` response header.
61
+ *
62
+ * - `'HIT'` — fresh cache entry served, no upstream call made.
63
+ * - `'STALE'` — stale entry served, upstream refresh scheduled in the background.
64
+ * - `'MISS'` — no cache entry; upstream call ran and the result was cached.
65
+ *
66
+ * Exported as a literal union so test code and downstream clients can
67
+ * import + narrow without restating the literal triple.
68
+ */
69
+ type CacheStatus = "HIT" | "STALE" | "MISS";
70
+ /**
71
+ * Controller-shape surface that the `Arc*Result` utilities read return
72
+ * types from. Internal — exported so the utility types can reference
73
+ * the minimal shape without a circular dependency on the full
74
+ * `BaseCrudController` / `BaseController` declarations.
75
+ */
76
+ type ArcControllerLike = {
77
+ list: (...args: never[]) => unknown;
78
+ get: (...args: never[]) => unknown;
79
+ create: (...args: never[]) => unknown;
80
+ update: (...args: never[]) => unknown;
81
+ delete: (...args: never[]) => unknown;
82
+ };
83
+ /**
84
+ * Return type of the controller's `list` method.
85
+ *
86
+ * @example
87
+ * ```ts
88
+ * class ProductController extends BaseController<Product> {
89
+ * async list(ctx: IRequestContext): ArcListResult<this> {
90
+ * // return shape inferred from BaseController.list — no need to
91
+ * // restate `Promise<IControllerResponse<ListResult<Product>>>`
92
+ * return super.list(ctx);
93
+ * }
94
+ * }
95
+ * ```
96
+ */
97
+ type ArcListResult<TCtrl extends ArcControllerLike> = ReturnType<TCtrl["list"]>;
98
+ /** Return type of the controller's `get` method. See {@link ArcListResult}. */
99
+ type ArcGetResult<TCtrl extends ArcControllerLike> = ReturnType<TCtrl["get"]>;
100
+ /** Return type of the controller's `create` method. See {@link ArcListResult}. */
101
+ type ArcCreateResult<TCtrl extends ArcControllerLike> = ReturnType<TCtrl["create"]>;
102
+ /** Return type of the controller's `update` method. See {@link ArcListResult}. */
103
+ type ArcUpdateResult<TCtrl extends ArcControllerLike> = ReturnType<TCtrl["update"]>;
104
+ /** Return type of the controller's `delete` method. See {@link ArcListResult}. */
105
+ type ArcDeleteResult<TCtrl extends ArcControllerLike> = ReturnType<TCtrl["delete"]>;
106
+ /**
107
+ * Construction-only options — fields that participate in the
108
+ * controller's mixin composition / hook identity and **cannot** be
109
+ * re-tuned post-construction via `configure()`. Pass these once at
110
+ * construction; if they need to change, build a new controller.
111
+ *
112
+ * Layer split (2.15.0): keeping this distinct from the configurable
113
+ * surface makes the layer explicit at compile time — `configure()`
114
+ * can't accept these, so accidental "I'll re-name the resource at
115
+ * runtime" calls fail to typecheck.
116
+ */
117
+ interface ControllerConstructionOptions {
118
+ /** Resource name for hook execution (e.g., 'product' → 'product.created'). */
119
+ resourceName?: string;
120
+ }
121
+ /**
122
+ * Configurable options — fields arc can forward post-construction via
123
+ * `BaseController.configure(opts)`. `defineResource()` calls
124
+ * `configure()` automatically when a user-supplied controller exposes
125
+ * the method, so resource-level options reach the controller without a
126
+ * `super(repo, { ... })` dance. Everything except `resourceName` /
127
+ * `repository` lives here.
128
+ *
129
+ * Each field maps 1:1 to a resource-level option on `defineResource()`:
130
+ * the resource is the public-API source of truth, this interface is
131
+ * the controller-internal surface arc forwards into.
132
+ */
133
+ interface ControllerConfigurableOptions {
134
+ /** Schema options for field sanitization. */
135
+ schemaOptions?: RouteSchemaOptions;
136
+ /**
137
+ * Query parser instance.
138
+ * Default: Arc built-in query parser (adapter-agnostic).
139
+ * Swap in MongoKit QueryParser, pgkit parser, etc.
140
+ */
141
+ queryParser?: QueryParserInterface;
142
+ /** Maximum limit for pagination (default: 100). */
143
+ maxLimit?: number;
144
+ /** Default limit for pagination (default: 20). */
145
+ defaultLimit?: number;
146
+ /**
147
+ * Default sort applied when the request doesn't specify one.
148
+ * - `string` (default: `'-createdAt'`) — Mongo `-field` DESC convention.
149
+ * - `false` — disable the default sort entirely (SQL/Drizzle resources
150
+ * without a `createdAt` column).
151
+ */
152
+ defaultSort?: string | false;
153
+ /**
154
+ * Field name used for multi-tenant scoping (default: 'organizationId').
155
+ * Override to match your schema: 'workspaceId', 'tenantId', 'teamId', etc.
156
+ * Set to `false` to disable org filtering for platform-universal resources.
157
+ */
158
+ tenantField?: string | false;
159
+ /**
160
+ * Primary key field name (default: '_id'). Auto-derives from the repo's
161
+ * own `idField` when unset.
162
+ */
163
+ idField?: string;
164
+ /**
165
+ * Custom filter matching for policy enforcement.
166
+ * Provided by the DataAdapter for non-MongoDB databases (SQL, etc.).
167
+ */
168
+ matchesFilter?: (item: unknown, filters: Record<string, unknown>) => boolean;
169
+ /** Cache configuration for the resource. */
170
+ cache?: ResourceCacheConfig;
171
+ /** Internal preset fields map (slug, tree, etc.). */
172
+ presetFields?: {
173
+ slugField?: string;
174
+ parentField?: string;
175
+ };
176
+ /**
177
+ * Policy for requests that include fields the caller can't write.
178
+ * - `'reject'` (default): 403 with denied field names.
179
+ * - `'strip'`: legacy silent-drop.
180
+ */
181
+ onFieldWriteDenied?: FieldWriteDenialPolicy;
182
+ }
183
+ /**
184
+ * Full constructor options — union of construction-only + configurable.
185
+ * The constructor accepts everything; `configure()` accepts only
186
+ * `ControllerConfigurableOptions`.
187
+ */
188
+ interface BaseControllerOptions extends ControllerConstructionOptions, ControllerConfigurableOptions {}
189
+ //#endregion
13
190
  //#region src/hooks/HookSystem.d.ts
14
191
  type HookPhase = "before" | "around" | "after";
15
192
  type HookOperation = "create" | "update" | "delete" | "restore" | "read" | "list";
@@ -389,100 +566,6 @@ declare class AccessControl {
389
566
  private _meta;
390
567
  }
391
568
  //#endregion
392
- //#region src/core/BodySanitizer.d.ts
393
- /**
394
- * Policy for handling fields the caller lacks write permission for.
395
- *
396
- * - `'reject'` (default, secure): throw 403 listing the denied fields so
397
- * misconfigurations and attacks surface instead of silently disappearing.
398
- * - `'strip'` (legacy): silently drop the field and continue. Preserved for
399
- * apps that relied on the pre-2.9 behaviour — new code should not use it.
400
- */
401
- type FieldWriteDenialPolicy = "reject" | "strip";
402
- interface BodySanitizerConfig {
403
- /** Schema options for field sanitization */
404
- schemaOptions: RouteSchemaOptions;
405
- /**
406
- * What to do when a request contains fields the caller can't write.
407
- * Default: `'reject'` — surface the misconfiguration as a 403.
408
- */
409
- onFieldWriteDenied?: FieldWriteDenialPolicy;
410
- }
411
- declare class BodySanitizer {
412
- private schemaOptions;
413
- private onFieldWriteDenied;
414
- constructor(config: BodySanitizerConfig);
415
- /**
416
- * Strip readonly and system-managed fields from request body.
417
- * Prevents clients from overwriting _id, timestamps, __v, etc.
418
- *
419
- * Also applies field-level write permissions when the request has
420
- * field permission metadata.
421
- */
422
- sanitize(body: AnyRecord, _operation: "create" | "update", req?: IRequestContext, meta?: ArcInternalMetadata): AnyRecord;
423
- }
424
- //#endregion
425
- //#region src/core/controllerTypes.d.ts
426
- /**
427
- * Union of every return shape repo-core's `MinimalRepo.getAll()` is
428
- * contractually allowed to produce. See repo-core's `MinimalRepo.getAll`
429
- * docstring for the three-way split:
430
- *
431
- * - `OffsetPaginationResult<TDoc>` — `page` param drives pagination.
432
- * - `KeysetPaginationResult<TDoc>` — `sort` + optional `after` drives pagination.
433
- * - `TDoc[]` — raw array when neither drives pagination.
434
- *
435
- * Arc passes the kit's response verbatim; consumers narrow on shape.
436
- */
437
- type ListResult<TDoc> = OffsetPaginationResult<TDoc> | KeysetPaginationResult<TDoc> | TDoc[];
438
- /**
439
- * Discrete cache states reported via the `x-cache` response header.
440
- *
441
- * - `'HIT'` — fresh cache entry served, no upstream call made.
442
- * - `'STALE'` — stale entry served, upstream refresh scheduled in the background.
443
- * - `'MISS'` — no cache entry; upstream call ran and the result was cached.
444
- *
445
- * Exported as a literal union so test code and downstream clients can
446
- * import + narrow without restating the literal triple.
447
- */
448
- type CacheStatus = "HIT" | "STALE" | "MISS";
449
- /**
450
- * Controller-shape surface that the `Arc*Result` utilities read return
451
- * types from. Internal — exported so the utility types can reference
452
- * the minimal shape without a circular dependency on the full
453
- * `BaseCrudController` / `BaseController` declarations.
454
- */
455
- type ArcControllerLike = {
456
- list: (...args: never[]) => unknown;
457
- get: (...args: never[]) => unknown;
458
- create: (...args: never[]) => unknown;
459
- update: (...args: never[]) => unknown;
460
- delete: (...args: never[]) => unknown;
461
- };
462
- /**
463
- * Return type of the controller's `list` method.
464
- *
465
- * @example
466
- * ```ts
467
- * class ProductController extends BaseController<Product> {
468
- * async list(ctx: IRequestContext): ArcListResult<this> {
469
- * // return shape inferred from BaseController.list — no need to
470
- * // restate `Promise<IControllerResponse<ListResult<Product>>>`
471
- * return super.list(ctx);
472
- * }
473
- * }
474
- * ```
475
- */
476
- type ArcListResult<TCtrl extends ArcControllerLike> = ReturnType<TCtrl["list"]>;
477
- /** Return type of the controller's `get` method. See {@link ArcListResult}. */
478
- type ArcGetResult<TCtrl extends ArcControllerLike> = ReturnType<TCtrl["get"]>;
479
- /** Return type of the controller's `create` method. See {@link ArcListResult}. */
480
- type ArcCreateResult<TCtrl extends ArcControllerLike> = ReturnType<TCtrl["create"]>;
481
- /** Return type of the controller's `update` method. See {@link ArcListResult}. */
482
- type ArcUpdateResult<TCtrl extends ArcControllerLike> = ReturnType<TCtrl["update"]>;
483
- /** Return type of the controller's `delete` method. See {@link ArcListResult}. */
484
- type ArcDeleteResult<TCtrl extends ArcControllerLike> = ReturnType<TCtrl["delete"]>;
485
- //#endregion
486
569
  //#region src/core/QueryResolver.d.ts
487
570
  interface QueryResolverConfig {
488
571
  /** Query parser instance (default: Arc built-in parser) */
@@ -551,89 +634,6 @@ declare class QueryResolver {
551
634
  }
552
635
  //#endregion
553
636
  //#region src/core/BaseCrudController.d.ts
554
- /**
555
- * Construction-only options — fields that participate in the
556
- * controller's mixin composition / hook identity and **cannot** be
557
- * re-tuned post-construction via `configure()`. Pass these once at
558
- * construction; if they need to change, build a new controller.
559
- *
560
- * Layer split (2.15.0): keeping this distinct from the configurable
561
- * surface makes the layer explicit at compile time — `configure()`
562
- * can't accept these, so accidental "I'll re-name the resource at
563
- * runtime" calls fail to typecheck.
564
- */
565
- interface ControllerConstructionOptions {
566
- /** Resource name for hook execution (e.g., 'product' → 'product.created'). */
567
- resourceName?: string;
568
- }
569
- /**
570
- * Configurable options — fields arc can forward post-construction via
571
- * `BaseController.configure(opts)`. `defineResource()` calls
572
- * `configure()` automatically when a user-supplied controller exposes
573
- * the method, so resource-level options reach the controller without a
574
- * `super(repo, { ... })` dance. Everything except `resourceName` /
575
- * `repository` lives here.
576
- *
577
- * Each field maps 1:1 to a resource-level option on `defineResource()`:
578
- * the resource is the public-API source of truth, this interface is
579
- * the controller-internal surface arc forwards into.
580
- */
581
- interface ControllerConfigurableOptions {
582
- /** Schema options for field sanitization. */
583
- schemaOptions?: RouteSchemaOptions;
584
- /**
585
- * Query parser instance.
586
- * Default: Arc built-in query parser (adapter-agnostic).
587
- * Swap in MongoKit QueryParser, pgkit parser, etc.
588
- */
589
- queryParser?: QueryParserInterface;
590
- /** Maximum limit for pagination (default: 100). */
591
- maxLimit?: number;
592
- /** Default limit for pagination (default: 20). */
593
- defaultLimit?: number;
594
- /**
595
- * Default sort applied when the request doesn't specify one.
596
- * - `string` (default: `'-createdAt'`) — Mongo `-field` DESC convention.
597
- * - `false` — disable the default sort entirely (SQL/Drizzle resources
598
- * without a `createdAt` column).
599
- */
600
- defaultSort?: string | false;
601
- /**
602
- * Field name used for multi-tenant scoping (default: 'organizationId').
603
- * Override to match your schema: 'workspaceId', 'tenantId', 'teamId', etc.
604
- * Set to `false` to disable org filtering for platform-universal resources.
605
- */
606
- tenantField?: string | false;
607
- /**
608
- * Primary key field name (default: '_id'). Auto-derives from the repo's
609
- * own `idField` when unset.
610
- */
611
- idField?: string;
612
- /**
613
- * Custom filter matching for policy enforcement.
614
- * Provided by the DataAdapter for non-MongoDB databases (SQL, etc.).
615
- */
616
- matchesFilter?: (item: unknown, filters: Record<string, unknown>) => boolean;
617
- /** Cache configuration for the resource. */
618
- cache?: ResourceCacheConfig;
619
- /** Internal preset fields map (slug, tree, etc.). */
620
- presetFields?: {
621
- slugField?: string;
622
- parentField?: string;
623
- };
624
- /**
625
- * Policy for requests that include fields the caller can't write.
626
- * - `'reject'` (default): 403 with denied field names.
627
- * - `'strip'`: legacy silent-drop.
628
- */
629
- onFieldWriteDenied?: FieldWriteDenialPolicy;
630
- }
631
- /**
632
- * Full constructor options — union of construction-only + configurable.
633
- * The constructor accepts everything; `configure()` accepts only
634
- * `ControllerConfigurableOptions`.
635
- */
636
- interface BaseControllerOptions extends ControllerConstructionOptions, ControllerConfigurableOptions {}
637
637
  /**
638
638
  * Framework-agnostic CRUD controller implementing IController.
639
639
  *
@@ -683,6 +683,15 @@ declare class BaseCrudController<TDoc = AnyRecord, TRepository extends Repositor
683
683
  parentField?: string;
684
684
  };
685
685
  protected _cacheConfig?: ResourceCacheConfig;
686
+ /**
687
+ * Retained construction-time values so partial `configure()` rebuilds
688
+ * (e.g. `configure({ schemaOptions })`) reuse them instead of silently
689
+ * falling back to the sub-component defaults (`-createdAt` sort,
690
+ * `reject` write-denial) — `defaultSort: false` matters for kits
691
+ * without a `createdAt` column, `strip` for legacy write semantics.
692
+ */
693
+ protected _defaultSort?: string | false;
694
+ protected _onFieldWriteDenied?: FieldWriteDenialPolicy;
686
695
  constructor(repository: TRepository, options?: BaseControllerOptions);
687
696
  /**
688
697
  * Swap the controller's query parser. Mutates the existing `QueryResolver`
@@ -730,38 +739,16 @@ declare class BaseCrudController<TDoc = AnyRecord, TRepository extends Repositor
730
739
  */
731
740
  protected getTenantField(): string | undefined;
732
741
  /**
733
- * Build the canonical repo-options bag from the Fastify request.
734
- *
735
- * Forwards the cross-kit canonical set (see repo-core's
736
- * `STANDARD_REPO_OPTION_KEYS`) into every CRUD repo call so kit
737
- * plugins (multi-tenant, audit, audit-trail, observability) get
738
- * what they need without per-resource wiring:
739
- *
740
- * - **Tenant scope** — `[tenantField]: orgId` from `RequestScope`.
741
- * Plugin-scoped repos (mongokit's `multiTenantPlugin`) read tenant
742
- * scope from the TOP of the options bag, not `data.organizationId`.
743
- * Without this stamping, a tenant-scoped repo throws "Missing
744
- * 'organizationId' in context" even when arc has injected the
745
- * tenant into the request body.
746
- * Multi-field tenancy from `_tenantFields` (populated by
747
- * `multiTenantPreset`) is merged in.
748
- *
749
- * - **Audit attribution** — `userId` + `user` from the authenticated
750
- * actor. Mongokit's audit-log / audit-trail plugins read these
751
- * into the `who` column; sqlitekit's audit plugin reads the same
752
- * names. No host-side forwarding needed.
753
- *
754
- * - **Trace correlation** — `requestId` from Fastify's request id
755
- * for stitching logs / events / downstream calls.
756
- *
757
- * - **`session` is intentionally NOT auto-set.** Sessions are tied
758
- * to explicit transaction scopes the controller doesn't manage;
759
- * pass `session` inline at the call site when running inside a
760
- * `withTransaction` helper.
742
+ * Build the canonical repo-options bag (tenant scope, audit
743
+ * attribution, trace correlation) from the Fastify request. Full
744
+ * contract + rationale on `buildTenantRepoOptions` in
745
+ * `crud/requestPipeline.ts` — this delegate exists so host overrides
746
+ * and duck-typed consumers (aggregation router, MCP bridge) keep the
747
+ * same `protected` entry point.
761
748
  *
762
749
  * Method kept named `tenantRepoOptions` for back-compat with hosts
763
750
  * that spread `...this.tenantRepoOptions(req)` (10+ call sites in
764
- * arc, plus host overrides). The bag has always grown over time —
751
+ * arc, plus host overrides). The bag has always grown over time —
765
752
  * hosts that don't want audit forwarding never read those keys.
766
753
  */
767
754
  protected tenantRepoOptions(req: IRequestContext): AnyRecord;
@@ -770,15 +757,10 @@ declare class BaseCrudController<TDoc = AnyRecord, TRepository extends Repositor
770
757
  /** Get hook system from request context (instance-scoped) */
771
758
  protected getHooks(req: IRequestContext): HookSystem | null;
772
759
  /**
773
- * Resolve the repository primary key for mutation calls.
774
- *
775
- * When the resource declares a custom `idField` (slug, jobId, UUID), the
776
- * default behavior is to translate the route id → the fetched doc's `_id`
777
- * because most Mongo repositories key mutation methods off `_id`.
778
- *
779
- * Exception: if the repo exposes a matching `idField` property (e.g.
780
- * MongoKit's `new Repository(Model, [], {}, { idField: 'id' })`), the
781
- * repo handles lookup itself — pass the route id through unchanged.
760
+ * Resolve the repository primary key for mutation calls. Translates a
761
+ * custom route `idField` (slug, jobId, UUID) to the fetched doc's `_id`
762
+ * unless the repo declares a matching `idField` of its own — see
763
+ * `resolveMutationRepoId` in `crud/requestPipeline.ts`.
782
764
  */
783
765
  protected resolveRepoId(id: string, existing: AnyRecord | null): string;
784
766
  /**
@@ -828,23 +810,14 @@ declare class BaseCrudController<TDoc = AnyRecord, TRepository extends Repositor
828
810
  * or `null` — every truthy non-null shape collapses to `true`.
829
811
  */
830
812
  protected isExistsTruthy(result: unknown): boolean;
813
+ /** Assemble the per-request hook context from the protected accessors. */
814
+ private hookOpContext;
831
815
  /**
832
816
  * Run `executeBefore` then `executeAround` (or just the executor if no
833
817
  * hooks are wired). Returns the around-phase result directly. Throws an
834
818
  * `ArcError` (status 400, code `BEFORE_<OP>_HOOK_ERROR`) when the
835
- * before-hook fails — the global error handler emits the canonical
836
- * `ErrorContract` shape.
837
- *
838
- * The caller runs `executeAfter` separately via `runAfterHook` — typically
839
- * after success-checking the result (delete checks `isDeleteSuccess`,
840
- * update checks `if (!item)`).
841
- *
842
- * **Knobs:**
843
- * - `meta` — passed verbatim into `executeBefore` / `executeAround` opts.
844
- * - `pipeProcessedData` (default `true`) — whether `executeBefore`'s
845
- * return value flows into `executeAround` as the data parameter.
846
- * Set `false` for delete (current behaviour: discards before's
847
- * return, passes original input to around).
819
+ * before-hook fails. Full contract on `executeHookedOp` in
820
+ * `crud/requestPipeline.ts`.
848
821
  */
849
822
  protected runHookedOpUntilResult<TInput, TResult>(req: IRequestContext, args: {
850
823
  op: "create" | "update" | "delete";
@@ -868,26 +841,27 @@ declare class BaseCrudController<TDoc = AnyRecord, TRepository extends Repositor
868
841
  * Resource-dispatch verbs router. Returns `null` when the request is
869
842
  * a regular list query, otherwise returns the dispatch promise.
870
843
  *
871
- * Verbs (mutually exclusive — first match wins):
872
- * - `?_count=true` → `{ count: number }` via `repo.count()`
873
- * - `?_distinct=field` → `unknown[]` via `repo.distinct(field)`
874
- * - `?_exists=true` → `{ exists: boolean }` via `repo.exists()`
844
+ * Verbs (mutually exclusive — first match wins):
845
+ * - `?_count=true` → `{ count: number }` via `repo.count()`
846
+ * - `?_distinct=field` → `unknown[]` via `repo.distinct(field)`
847
+ * - `?_exists=true` → `{ exists: boolean }` via `repo.exists()`
875
848
  *
876
849
  * All verbs share the resolved filter (parsed query + policy filters
877
850
  * + tenant scope). Adapters that don't ship the underlying repo
878
851
  * method get a `501` so failures surface loudly instead of falling
879
- * back to a full table scan.
852
+ * back to a full table scan. Matching + repo invocation live in
853
+ * `crud/resourceVerbs.ts`.
880
854
  */
881
855
  protected dispatchResourceVerb(req: IRequestContext): Promise<IControllerResponse<unknown>> | null;
882
856
  /** Resolve filter + tenant/audit options for a dispatch verb. */
883
857
  private resolveDispatchScope;
884
- /** `?_count=true` → `repo.count(filter)` */
858
+ /** `?_count=true` → `repo.count(filter)` */
885
859
  protected dispatchCount(req: IRequestContext): Promise<IControllerResponse<{
886
860
  count: number;
887
861
  }>>;
888
- /** `?_distinct=field` → `repo.distinct(field, filter)` */
862
+ /** `?_distinct=field` → `repo.distinct(field, filter)` */
889
863
  protected dispatchDistinct(req: IRequestContext, field: string): Promise<IControllerResponse<unknown[]>>;
890
- /** `?_exists=true` → `repo.exists(filter)` */
864
+ /** `?_exists=true` → `repo.exists(filter)` */
891
865
  protected dispatchExists(req: IRequestContext): Promise<IControllerResponse<{
892
866
  exists: boolean;
893
867
  }>>;
@@ -4059,4 +4033,4 @@ interface ValidateOptions {
4059
4033
  strict?: boolean;
4060
4034
  }
4061
4035
  //#endregion
4062
- export { OnTenantDeleteConfig as $, BaseController as $t, RequestIdOptions as A, HookSystem as An, AggregationRateLimit as At, defineResource as B, AuthHelpers as Bt, RequestContext as C, AccessControlConfig as Cn, AggMeasureShorthand as Ct, HealthCheck as D, HookOperation as Dn, AggregationIndexHint as Dt, GracefulShutdownOptions as E, HookHandler as En, AggregationDateRangeRequirement as Et, FastifyWithDecorators as F, beforeCreate as Fn, OperationFilter as Ft, ActionsMap as G, TokenPair as Gt, ActionDefinition as H, Authenticator as Ht, MiddlewareHandler as I, beforeDelete as In, PipelineConfig as It, CrudRouteKey as J, ArcRequest as Jt, ArcFieldRule as K, AnyRecord as Kt, RequestWithExtras as L, beforeUpdate as Ln, PipelineContext as Lt, EventsDecorator as M, afterCreate as Mn, Guard as Mt, FastifyRequestExtras as N, afterDelete as Nn, Interceptor as Nt, HealthOptions as O, HookPhase as On, AggregationMaterializedContext as Ot, FastifyWithAuth as P, afterUpdate as Pn, NextFunction as Pt, MiddlewareConfig as Q, UserOrganization as Qt, RegisterOptions as R, createHookSystem as Rn, PipelineStep as Rt, QueryParserInterface as S, AccessControl as Sn, AggMeasureInput as St, CrudRouterOptions as T, HookContext as Tn, AggregationConfig as Tt, ActionEntry as U, AuthenticatorContext as Ut, ResourceDefinition as V, AuthPluginOptions as Vt, ActionHandlerFn as W, JwtContext as Wt, EventDefinition as X, ObjectId as Xt, CrudSchemas as Y, JWTPayload as Yt, FieldRule$1 as Z, UserLike as Zt, ControllerQueryOptions as _, ArcListResult as _n, FastifyHandler as _t, InferAdapterDoc as a, SlugMixin as an, ResolvedTenantPurge as at, ParsedQuery as b, BodySanitizer as bn, IRequestContext as bt, TypedController as c, BaseControllerOptions as cn, ResourceHookContext as ct, PaginationResult as d, ControllerConstructionOptions as dn, RouteDefinition as dt, SoftDeleteExt as en, OpenApiSchemas as et, IntrospectionData as f, QueryResolver as fn, RouteMcpConfig as ft, ArcInternalMetadata as g, ArcGetResult as gn, ControllerLike as gt, ResourceMetadata as h, ArcDeleteResult as hn, ControllerHandler as ht, ValidationResult as i, SlugExt as in, RateLimitConfig as it, ArcDecorator as j, HookSystemOptions as jn, AggregationsMap as jt, IntrospectionPluginOptions as k, HookRegistration as kn, AggregationMaterializedResult as kt, TypedRepository as l, BaseCrudController as ln, ResourceHooks as lt, RegistryStats as m, ArcCreateResult as mn, RouteSchemaOptions as mt, ConfigError as n, TreeExt as nn, PresetHook as nt, InferDocType as o, BulkExt as on, ResourceCacheConfig as ot, RegistryEntry as p, QueryResolverConfig as pn, RouteMethod as pt, CrudController as q, ApiResponse as qt, ValidateOptions as r, TreeMixin as rn, PresetResult as rt, InferResourceDoc as s, BulkMixin as sn, ResourceConfig as st, RouteHandlerMethod$1 as t, SoftDeleteMixin as tn, PresetFunction as tt, TypedResourceConfig as u, ControllerConfigurableOptions as un, ResourcePermissions as ut, LookupOption as v, ArcUpdateResult as vn, IController as vt, ServiceContext as w, DefineHookOptions as wn, AggregationCacheConfig as wt, PopulateOption as x, BodySanitizerConfig as xn, RouteHandler as xt, OwnershipCheck as y, ListResult as yn, IControllerResponse as yt, ResourceRegistry as z, defineHook as zn, Transform as zt };
4036
+ export { OnTenantDeleteConfig as $, BaseController as $t, RequestIdOptions as A, ArcDeleteResult as An, AggregationRateLimit as At, defineResource as B, AuthHelpers as Bt, RequestContext as C, afterUpdate as Cn, AggMeasureShorthand as Ct, HealthCheck as D, createHookSystem as Dn, AggregationIndexHint as Dt, GracefulShutdownOptions as E, beforeUpdate as En, AggregationDateRangeRequirement as Et, FastifyWithDecorators as F, ControllerConfigurableOptions as Fn, OperationFilter as Ft, ActionsMap as G, TokenPair as Gt, ActionDefinition as H, Authenticator as Ht, MiddlewareHandler as I, ControllerConstructionOptions as In, PipelineConfig as It, CrudRouteKey as J, ArcRequest as Jt, ArcFieldRule as K, AnyRecord as Kt, RequestWithExtras as L, ListResult as Ln, PipelineContext as Lt, EventsDecorator as M, ArcListResult as Mn, Guard as Mt, FastifyRequestExtras as N, ArcUpdateResult as Nn, Interceptor as Nt, HealthOptions as O, defineHook as On, AggregationMaterializedContext as Ot, FastifyWithAuth as P, BaseControllerOptions as Pn, NextFunction as Pt, MiddlewareConfig as Q, UserOrganization as Qt, RegisterOptions as R, BodySanitizer as Rn, PipelineStep as Rt, QueryParserInterface as S, afterDelete as Sn, AggMeasureInput as St, CrudRouterOptions as T, beforeDelete as Tn, AggregationConfig as Tt, ActionEntry as U, AuthenticatorContext as Ut, ResourceDefinition as V, AuthPluginOptions as Vt, ActionHandlerFn as W, JwtContext as Wt, EventDefinition as X, ObjectId as Xt, CrudSchemas as Y, JWTPayload as Yt, FieldRule$1 as Z, UserLike as Zt, ControllerQueryOptions as _, HookPhase as _n, FastifyHandler as _t, InferAdapterDoc as a, SlugMixin as an, ResolvedTenantPurge as at, ParsedQuery as b, HookSystemOptions as bn, IRequestContext as bt, TypedController as c, BaseCrudController as cn, ResourceHookContext as ct, PaginationResult as d, AccessControl as dn, RouteDefinition as dt, SoftDeleteExt as en, OpenApiSchemas as et, IntrospectionData as f, AccessControlConfig as fn, RouteMcpConfig as ft, ArcInternalMetadata as g, HookOperation as gn, ControllerLike as gt, ResourceMetadata as h, HookHandler as hn, ControllerHandler as ht, ValidationResult as i, SlugExt as in, RateLimitConfig as it, ArcDecorator as j, ArcGetResult as jn, AggregationsMap as jt, IntrospectionPluginOptions as k, ArcCreateResult as kn, AggregationMaterializedResult as kt, TypedRepository as l, QueryResolver as ln, ResourceHooks as lt, RegistryStats as m, HookContext as mn, RouteSchemaOptions as mt, ConfigError as n, TreeExt as nn, PresetHook as nt, InferDocType as o, BulkExt as on, ResourceCacheConfig as ot, RegistryEntry as p, DefineHookOptions as pn, RouteMethod as pt, CrudController as q, ApiResponse as qt, ValidateOptions as r, TreeMixin as rn, PresetResult as rt, InferResourceDoc as s, BulkMixin as sn, ResourceConfig as st, RouteHandlerMethod$1 as t, SoftDeleteMixin as tn, PresetFunction as tt, TypedResourceConfig as u, QueryResolverConfig as un, ResourcePermissions as ut, LookupOption as v, HookRegistration as vn, IController as vt, ServiceContext as w, beforeCreate as wn, AggregationCacheConfig as wt, PopulateOption as x, afterCreate as xn, RouteHandler as xt, OwnershipCheck as y, HookSystem as yn, IControllerResponse as yt, ResourceRegistry as z, BodySanitizerConfig as zn, Transform as zt };
@@ -1,6 +1,6 @@
1
- import { r as CacheStore, t as CacheLogger } from "./interface-BVkZsvEe.mjs";
2
- import { i as RequestScope, n as Mandate } from "./types-CfapW2t8.mjs";
3
- import { c as PermissionCheck, l as PermissionContext, u as PermissionResult } from "./fields-DqZLp5d6.mjs";
1
+ import { r as CacheStore, t as CacheLogger } from "./interface-DL7LlWS5.mjs";
2
+ import { i as RequestScope, n as Mandate } from "./types-BJwJN2Pg.mjs";
3
+ import { c as PermissionCheck, l as PermissionContext, u as PermissionResult } from "./fields-CKLrhyOb.mjs";
4
4
  import { FastifyReply, FastifyRequest } from "fastify";
5
5
 
6
6
  //#region src/permissions/agent.d.ts
package/dist/index.d.mts CHANGED
@@ -1,8 +1,8 @@
1
- import { $t as BaseController, A as RequestIdOptions, At as AggregationRateLimit, B as defineResource, C as RequestContext, Ct as AggMeasureShorthand, D as HealthCheck, Dt as AggregationIndexHint, E as GracefulShutdownOptions, Et as AggregationDateRangeRequirement, F as FastifyWithDecorators, J as CrudRouteKey, Jt as ArcRequest, Kt as AnyRecord, L as RequestWithExtras, N as FastifyRequestExtras, O as HealthOptions, Ot as AggregationMaterializedContext, P as FastifyWithAuth, Q as MiddlewareConfig, Qt as UserOrganization, S as QueryParserInterface, St as AggMeasureInput, T as CrudRouterOptions, Tt as AggregationConfig, V as ResourceDefinition, Vt as AuthPluginOptions, X as EventDefinition, Y as CrudSchemas, Yt as JWTPayload, Z as FieldRule, _n as ArcListResult, a as InferAdapterDoc, an as SlugMixin, bt as IRequestContext, c as TypedController, cn as BaseControllerOptions, d as PaginationResult, dn as ControllerConstructionOptions, en as SoftDeleteExt, f as IntrospectionData, g as ArcInternalMetadata, gn as ArcGetResult, gt as ControllerLike, h as ResourceMetadata, hn as ArcDeleteResult, i as ValidationResult, in as SlugExt, it as RateLimitConfig, jt as AggregationsMap, k as IntrospectionPluginOptions, kt as AggregationMaterializedResult, l as TypedRepository, ln as BaseCrudController, m as RegistryStats, mn as ArcCreateResult, mt as RouteSchemaOptions, n as ConfigError, nn as TreeExt, o as InferDocType, on as BulkExt, p as RegistryEntry, q as CrudController, qt as ApiResponse, r as ValidateOptions, rn as TreeMixin, rt as PresetResult, s as InferResourceDoc, sn as BulkMixin, st as ResourceConfig, t as RouteHandlerMethod, tn as SoftDeleteMixin, tt as PresetFunction, u as TypedResourceConfig, un as ControllerConfigurableOptions, vn as ArcUpdateResult, vt as IController, w as ServiceContext, wt as AggregationCacheConfig, xt as RouteHandler, y as OwnershipCheck, yn as ListResult, yt as IControllerResponse } from "./index-C000faom.mjs";
2
- import { a as applyFieldWritePermissions, c as PermissionCheck, d as UserBase, i as applyFieldReadPermissions, l as PermissionContext, n as FieldPermissionMap, o as fields, t as FieldPermission, u as PermissionResult } from "./fields-DqZLp5d6.mjs";
3
- 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, b as DEFAULT_ID_FIELD, f as defineResourceVariants, j as MAX_REGEX_LENGTH, k as HookPhase, m as defineAction, s as getControllerScope, v as CRUD_OPERATIONS, w as DEFAULT_TENANT_FIELD, x as DEFAULT_LIMIT, y as CrudOperation } from "./index-CNiryUMN.mjs";
4
- import { A as requireRoles, C as allOf, E as denyAll, M as when, O as requireAuth, S as createOrgPermissions, T as anyOf, a as presets_d_exports, c as readOnly, d as requireOrgRole, f as requireScopeContext, i as ownerWithAdminBypass, k as requireOwnership, l as requireOrgInScope, m as requireTeamMembership, n as authenticated, o as publicRead, p as requireServiceScope, r as fullPublic, s as publicReadAdminWrite, t as adminOnly, u as requireOrgMembership, v as DynamicPermissionMatrix, w as allowPublic, x as createDynamicPermissionMatrix, y as DynamicPermissionMatrixConfig } from "./index-3L-adFJO.mjs";
5
- import { a as NotFoundError, d as ValidationError, f as createDomainError, i as ForbiddenError, t as ArcError, u as UnauthorizedError } from "./errors-4ZloYFvm.mjs";
1
+ import { $t as BaseController, A as RequestIdOptions, An as ArcDeleteResult, At as AggregationRateLimit, B as defineResource, C as RequestContext, Ct as AggMeasureShorthand, D as HealthCheck, Dt as AggregationIndexHint, E as GracefulShutdownOptions, Et as AggregationDateRangeRequirement, F as FastifyWithDecorators, Fn as ControllerConfigurableOptions, In as ControllerConstructionOptions, J as CrudRouteKey, Jt as ArcRequest, Kt as AnyRecord, L as RequestWithExtras, Ln as ListResult, Mn as ArcListResult, N as FastifyRequestExtras, Nn as ArcUpdateResult, O as HealthOptions, Ot as AggregationMaterializedContext, P as FastifyWithAuth, Pn as BaseControllerOptions, Q as MiddlewareConfig, Qt as UserOrganization, S as QueryParserInterface, St as AggMeasureInput, T as CrudRouterOptions, Tt as AggregationConfig, V as ResourceDefinition, Vt as AuthPluginOptions, X as EventDefinition, Y as CrudSchemas, Yt as JWTPayload, Z as FieldRule, a as InferAdapterDoc, an as SlugMixin, bt as IRequestContext, c as TypedController, cn as BaseCrudController, d as PaginationResult, en as SoftDeleteExt, f as IntrospectionData, g as ArcInternalMetadata, gt as ControllerLike, h as ResourceMetadata, i as ValidationResult, in as SlugExt, it as RateLimitConfig, jn as ArcGetResult, jt as AggregationsMap, k as IntrospectionPluginOptions, kn as ArcCreateResult, kt as AggregationMaterializedResult, l as TypedRepository, m as RegistryStats, mt as RouteSchemaOptions, n as ConfigError, nn as TreeExt, o as InferDocType, on as BulkExt, p as RegistryEntry, q as CrudController, qt as ApiResponse, r as ValidateOptions, rn as TreeMixin, rt as PresetResult, s as InferResourceDoc, sn as BulkMixin, st as ResourceConfig, t as RouteHandlerMethod, tn as SoftDeleteMixin, tt as PresetFunction, u as TypedResourceConfig, vt as IController, w as ServiceContext, wt as AggregationCacheConfig, xt as RouteHandler, y as OwnershipCheck, yt as IControllerResponse } from "./index-QYma8mdC.mjs";
2
+ import { a as applyFieldWritePermissions, c as PermissionCheck, d as UserBase, i as applyFieldReadPermissions, l as PermissionContext, n as FieldPermissionMap, o as fields, t as FieldPermission, u as PermissionResult } from "./fields-CKLrhyOb.mjs";
3
+ 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, b as DEFAULT_ID_FIELD, f as defineResourceVariants, j as MAX_REGEX_LENGTH, k as HookPhase, m as defineAction, s as getControllerScope, v as CRUD_OPERATIONS, w as DEFAULT_TENANT_FIELD, x as DEFAULT_LIMIT, y as CrudOperation } from "./index-Cvo1u9n6.mjs";
4
+ import { A as requireRoles, C as allOf, E as denyAll, M as when, O as requireAuth, S as createOrgPermissions, T as anyOf, a as presets_d_exports, c as readOnly, d as requireOrgRole, f as requireScopeContext, i as ownerWithAdminBypass, k as requireOwnership, l as requireOrgInScope, m as requireTeamMembership, n as authenticated, o as publicRead, p as requireServiceScope, r as fullPublic, s as publicReadAdminWrite, t as adminOnly, u as requireOrgMembership, v as DynamicPermissionMatrix, w as allowPublic, x as createDynamicPermissionMatrix, y as DynamicPermissionMatrixConfig } from "./index-vcWUGkwf.mjs";
5
+ import { a as NotFoundError, d as ValidationError, f as createDomainError, i as ForbiddenError, t as ArcError, u as UnauthorizedError } from "./errors-DZOemeGa.mjs";
6
6
 
7
7
  //#region src/index.d.ts
8
8
  declare const version: string;
package/dist/index.mjs CHANGED
@@ -1,10 +1,10 @@
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
2
  import { d as createDomainError, i as NotFoundError, l as UnauthorizedError, r as ForbiddenError, t as ArcError, u as ValidationError } from "./errors-j4aJm1Wg.mjs";
3
- import { a as BulkMixin, i as SlugMixin, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, t as BaseController } from "./BaseController-DPwe89qs.mjs";
4
- import { C as requireAuth, D as when, M as applyFieldWritePermissions, N as fields, T as requireRoles, _ as requireTeamMembership, a as presets_exports, b as anyOf, c as readOnly, d as createOrgPermissions, f as requireOrgInScope, g as requireServiceScope, h as requireScopeContext, i as ownerWithAdminBypass, j as applyFieldReadPermissions, m as requireOrgRole, n as authenticated, o as publicRead, p as requireOrgMembership, r as fullPublic, s as publicReadAdminWrite, t as adminOnly, u as createDynamicPermissionMatrix, v as allOf, w as requireOwnership, x as denyAll, y as allowPublic } from "./permissions-B1Qy55fg.mjs";
5
- import { x as getControllerScope } from "./routerShared-Dl0A77Ba.mjs";
6
- import { a as defineResource, i as defineResourceVariants, o as ResourceDefinition, s as defineAction, u as defineAggregation } from "./core-B41eZxyM.mjs";
3
+ import { a as BulkMixin, i as SlugMixin, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, t as BaseController } from "./BaseController-B-uXzf6I.mjs";
4
+ import { C as requireAuth, D as when, F as applyFieldWritePermissions, I as fields, P as applyFieldReadPermissions, T as requireRoles, _ as requireTeamMembership, a as presets_exports, b as anyOf, c as readOnly, d as createOrgPermissions, f as requireOrgInScope, g as requireServiceScope, h as requireScopeContext, i as ownerWithAdminBypass, m as requireOrgRole, n as authenticated, o as publicRead, p as requireOrgMembership, r as fullPublic, s as publicReadAdminWrite, t as adminOnly, u as createDynamicPermissionMatrix, v as allOf, w as requireOwnership, x as denyAll, y as allowPublic } from "./permissions-3uzwkbQt.mjs";
5
+ import { a as defineResource, i as defineResourceVariants, o as ResourceDefinition, s as defineAction, u as defineAggregation } from "./core-C88uIwd3.mjs";
6
+ import { c as getControllerScope } from "./pipeline-D4sqiokR.mjs";
7
7
  //#region src/index.ts
8
- const version = "2.18.1";
8
+ const version = "2.18.3";
9
9
  //#endregion
10
10
  export { ArcError, BaseController, BaseCrudController, BulkMixin, CRUD_OPERATIONS, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, ForbiddenError, HOOK_OPERATIONS, HOOK_PHASES, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, NotFoundError, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, SlugMixin, SoftDeleteMixin, TreeMixin, UnauthorizedError, ValidationError, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, authenticated, createDomainError, createDynamicPermissionMatrix, createOrgPermissions, defineAction, defineAggregation, defineResource, defineResourceVariants, denyAll, fields, fullPublic, getControllerScope, ownerWithAdminBypass, presets_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAuth, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, version, when };
@@ -917,9 +917,9 @@ ${config.adapter === "mongokit" ? ` await mongoose.connection.collection('use
917
917
  //#region src/cli/commands/init/dependency-plan.ts
918
918
  const SCAFFOLD_DEP_VERSIONS = {
919
919
  core: {
920
- "@classytic/arc": "^2.17.2",
920
+ "@classytic/arc": "^2.18.3",
921
921
  "@classytic/primitives": "^0.6.0",
922
- "@classytic/repo-core": "^0.5.0",
922
+ "@classytic/repo-core": "^0.6.0",
923
923
  "@fastify/cors": "^11.2.0",
924
924
  "@fastify/helmet": "^13.0.2",
925
925
  "@fastify/rate-limit": "^10.3.0",
@@ -938,7 +938,7 @@ const SCAFFOLD_DEP_VERSIONS = {
938
938
  },
939
939
  authBetterAuthApiKey: { "@better-auth/api-key": "^1.6.11" },
940
940
  adapterMongokit: {
941
- "@classytic/mongokit": "^3.14.0",
941
+ "@classytic/mongokit": "^3.16.0",
942
942
  mongoose: "^9.6.2"
943
943
  },
944
944
  devCommon: {
@@ -1,5 +1,5 @@
1
- import { n as DomainEvent } from "../EventTransport-B1GFiYUy.mjs";
2
- import { c as WebSocketClient, l as WebSocketMessage } from "../websocket-BZMUP7Gr.mjs";
1
+ import { n as DomainEvent } from "../EventTransport-CaaXM5Y1.mjs";
2
+ import { c as WebSocketClient, l as WebSocketMessage } from "../websocket-BFBT5rH-.mjs";
3
3
  import { FastifyPluginAsync, FastifyRequest } from "fastify";
4
4
 
5
5
  //#region src/integrations/event-gateway.d.ts
@@ -4,7 +4,7 @@ const eventGatewayPluginImpl = async (fastify, opts = {}) => {
4
4
  const { auth = true, orgScoped = false, roomPolicy, maxMessageBytes, maxSubscriptionsPerClient, authenticate } = opts;
5
5
  if (auth && !authenticate && !fastify.hasDecorator("authenticate")) throw new Error("[arc-event-gateway] auth is true but fastify.authenticate is not registered. Register an auth plugin first, provide a custom authenticate function, or set auth: false.");
6
6
  if (opts.sse !== false) {
7
- const { default: ssePlugin } = await import("../sse-jh5OqFjR.mjs").then((n) => n.r);
7
+ const { default: ssePlugin } = await import("../sse-Xq8UtuQx.mjs").then((n) => n.r);
8
8
  await fastify.register(ssePlugin, {
9
9
  path: opts.sse?.path ?? "/events/stream",
10
10
  requireAuth: auth,