@classytic/arc 2.15.4 → 2.16.1

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 (160) hide show
  1. package/README.md +1 -0
  2. package/bin/arc.js +12 -0
  3. package/dist/{BaseController-dx3m2J8V.mjs → BaseController-Vk8I7C0x.mjs} +61 -19
  4. package/dist/{HookSystem-Iiebom92.mjs → HookSystem-Cmf7-Etp.mjs} +8 -4
  5. package/dist/{QueryCache-D41bfdBB.d.mts → QueryCache-8YmAQ-zW.d.mts} +1 -1
  6. package/dist/{ResourceRegistry-CTERg_2x.mjs → ResourceRegistry-CzSzVK1m.mjs} +55 -9
  7. package/dist/audit/index.d.mts +1 -1
  8. package/dist/audit/index.mjs +4 -2
  9. package/dist/auth/index.d.mts +4 -4
  10. package/dist/auth/index.mjs +4 -4
  11. package/dist/auth/redis-session.d.mts +1 -1
  12. package/dist/{betterAuthOpenApi--M_i87dQ.mjs → betterAuthOpenApi-ClWxaceA.mjs} +10 -6
  13. package/dist/buildHandler-C_SkBNF3.mjs +302 -0
  14. package/dist/cache/index.d.mts +3 -3
  15. package/dist/cache/index.mjs +3 -3
  16. package/dist/{caching-SM8gghN6.mjs → caching-8MfrrUYU.mjs} +1 -1
  17. package/dist/cli/commands/describe.d.mts +35 -1
  18. package/dist/cli/commands/describe.mjs +52 -12
  19. package/dist/cli/commands/docs.d.mts +1 -4
  20. package/dist/cli/commands/docs.mjs +4 -16
  21. package/dist/cli/commands/generate.d.mts +2 -20
  22. package/dist/cli/commands/generate.mjs +1 -546
  23. package/dist/cli/commands/init.d.mts +2 -40
  24. package/dist/cli/commands/init.mjs +1 -3045
  25. package/dist/cli/commands/introspect.mjs +53 -64
  26. package/dist/cli/index.d.mts +2 -2
  27. package/dist/cli/index.mjs +2 -2
  28. package/dist/{constants-Cxde4rpC.mjs → constants-TrJVIJl0.mjs} +7 -0
  29. package/dist/core/index.d.mts +3 -3
  30. package/dist/core/index.mjs +5 -5
  31. package/dist/{core-CvmOqEms.mjs → core-wKeGXn38.mjs} +222 -44
  32. package/dist/createActionRouter-eiOFtnC3.mjs +288 -0
  33. package/dist/{createAggregationRouter-B0bPDf5b.mjs → createAggregationRouter-C4unhBnV.mjs} +3 -2
  34. package/dist/{createApp-PFegs47-.mjs → createApp-DdPBtmzp.mjs} +16 -14
  35. package/dist/{defineEvent-D5h7EvAx.mjs → defineEvent-NPKUJRt8.mjs} +1 -1
  36. package/dist/docs/index.d.mts +2 -2
  37. package/dist/docs/index.mjs +1 -1
  38. package/dist/{errorHandler-Bk-AGhkU.mjs → errorHandler-DNPzqaTT.mjs} +17 -14
  39. package/dist/errors-4ZloYFvm.d.mts +91 -0
  40. package/dist/{eventPlugin-CaKTYkYM.mjs → eventPlugin-CnJCUyM0.mjs} +1 -1
  41. package/dist/{eventPlugin-qXpqTebY.d.mts → eventPlugin-DjEx_J3j.d.mts} +1 -1
  42. package/dist/events/index.d.mts +3 -3
  43. package/dist/events/index.mjs +5 -5
  44. package/dist/events/transports/redis-stream-entry.d.mts +1 -1
  45. package/dist/events/transports/redis.d.mts +1 -1
  46. package/dist/factory/index.d.mts +2 -2
  47. package/dist/factory/index.mjs +4 -3
  48. package/dist/fastify-augmentation-CJm0vh-l.d.mts +42 -0
  49. package/dist/{fields-COhcH3fk.d.mts → fields-DqZLp5d6.d.mts} +1 -1
  50. package/dist/generate-CcM24hoq.mjs +654 -0
  51. package/dist/generate-cRnsafMS.d.mts +38 -0
  52. package/dist/hooks/index.d.mts +1 -1
  53. package/dist/hooks/index.mjs +1 -1
  54. package/dist/idempotency/index.d.mts +2 -2
  55. package/dist/idempotency/index.mjs +1 -1
  56. package/dist/idempotency/redis.d.mts +1 -1
  57. package/dist/{index-BTqLEvhu.d.mts → index-3L-adFJO.d.mts} +12 -12
  58. package/dist/{index-BstGxcc3.d.mts → index-CC_pgZjY.d.mts} +88 -17
  59. package/dist/{index-BswOSJCE.d.mts → index-DBDgy6Hw.d.mts} +430 -19
  60. package/dist/index.d.mts +6 -6
  61. package/dist/index.mjs +7 -8
  62. package/dist/init-D-vrTZ1G.d.mts +71 -0
  63. package/dist/init-DYzfniuX.mjs +3098 -0
  64. package/dist/integrations/event-gateway.d.mts +2 -2
  65. package/dist/integrations/event-gateway.mjs +1 -1
  66. package/dist/integrations/index.d.mts +2 -2
  67. package/dist/integrations/jobs.mjs +3 -3
  68. package/dist/integrations/mcp/index.d.mts +239 -7
  69. package/dist/integrations/mcp/index.mjs +2 -528
  70. package/dist/integrations/mcp/testing.d.mts +2 -2
  71. package/dist/integrations/mcp/testing.mjs +6 -10
  72. package/dist/integrations/streamline.mjs +26 -1
  73. package/dist/integrations/websocket-redis.d.mts +1 -1
  74. package/dist/integrations/websocket.d.mts +1 -1
  75. package/dist/integrations/websocket.mjs +1 -0
  76. package/dist/loadResourcesFromEntry-DCjYMgfC.mjs +51 -0
  77. package/dist/{resourceToTools-tFYUNmM0.mjs → mcpPlugin-Dbgz9_Rj.mjs} +1021 -318
  78. package/dist/{memory-UBydS5ku.mjs → memory-QOLe11D5.mjs} +2 -0
  79. package/dist/middleware/index.d.mts +1 -1
  80. package/dist/middleware/index.mjs +1 -1
  81. package/dist/{openapi-BHXhoX8O.mjs → openapi-BRnd3pT7.mjs} +82 -44
  82. package/dist/permissions/index.d.mts +2 -2
  83. package/dist/permissions/index.mjs +1 -1
  84. package/dist/{permissions-ohQyv50e.mjs → permissions-CTxMrreC.mjs} +2 -2
  85. package/dist/{pipe-Zr0KXjQe.mjs → pipe-DiCyvyPN.mjs} +1 -0
  86. package/dist/pipeline/index.d.mts +1 -1
  87. package/dist/pipeline/index.mjs +1 -1
  88. package/dist/plugins/index.d.mts +5 -59
  89. package/dist/plugins/index.mjs +10 -10
  90. package/dist/plugins/response-cache.mjs +5 -5
  91. package/dist/plugins/tracing-entry.d.mts +1 -1
  92. package/dist/plugins/tracing-entry.mjs +1 -1
  93. package/dist/{pluralize-DQgqgifU.mjs → pluralize-B9M8xvy-.mjs} +2 -1
  94. package/dist/preloadResources-BOXzPhKU.mjs +45 -0
  95. package/dist/presets/filesUpload.d.mts +4 -4
  96. package/dist/presets/filesUpload.mjs +2 -2
  97. package/dist/presets/index.d.mts +1 -1
  98. package/dist/presets/index.mjs +1 -1
  99. package/dist/presets/multiTenant.d.mts +1 -1
  100. package/dist/presets/multiTenant.mjs +4 -3
  101. package/dist/presets/search.d.mts +2 -2
  102. package/dist/presets/search.mjs +1 -1
  103. package/dist/{presets-BbkjdPeH.mjs → presets-C9BE6WaZ.mjs} +2 -2
  104. package/dist/{queryCachePlugin-m1XsgAIJ.mjs → queryCachePlugin-B4XMSSe7.mjs} +2 -2
  105. package/dist/{queryCachePlugin-CqMdLI2-.d.mts → queryCachePlugin-Do4P_WBC.d.mts} +2 -2
  106. package/dist/{redis-DiMkdHEl.d.mts → redis-cpqVb85w.d.mts} +1 -1
  107. package/dist/{redis-stream-D6HzR1Z_.d.mts → redis-stream-BuiAS3aE.d.mts} +1 -1
  108. package/dist/registry/index.d.mts +341 -2
  109. package/dist/registry/index.mjs +3 -3
  110. package/dist/registry-BrlHkrRS.mjs +582 -0
  111. package/dist/{routerShared-DrOa-26E.mjs → routerShared-ClV4cCaa.mjs} +40 -16
  112. package/dist/scope/index.d.mts +3 -3
  113. package/dist/scope/index.mjs +3 -3
  114. package/dist/{sse-Bz-5ZeTt.mjs → sse-jh5OqFjR.mjs} +1 -1
  115. package/dist/testing/index.d.mts +2 -25
  116. package/dist/testing/index.mjs +17 -51
  117. package/dist/testing/storageContract.d.mts +1 -1
  118. package/dist/types/index.d.mts +5 -5
  119. package/dist/types/storage.d.mts +1 -1
  120. package/dist/{types-BQsjgQzS.d.mts → types-BD0BCdf6.d.mts} +106 -12
  121. package/dist/{types-C_s5moIu.mjs → types-Bi0r0vjG.mjs} +53 -1
  122. package/dist/{types-CTYvcwHe.d.mts → types-CfapW2t8.d.mts} +42 -1
  123. package/dist/{types-DrBaUwyV.d.mts → types-Dw--SyTq.d.mts} +57 -11
  124. package/dist/utils/index.d.mts +1287 -2
  125. package/dist/utils/index.mjs +1 -1
  126. package/dist/{utils-_h9B3c57.mjs → utils-DPXZnZUx.mjs} +158 -41
  127. package/dist/{buildHandler-CcFOpJLh.mjs → validate-DFIP2VrM.mjs} +73 -302
  128. package/dist/{versioning-hmkPcDlX.d.mts → versioning-5H4930tj.d.mts} +1 -1
  129. package/package.json +22 -29
  130. package/skills/arc/SKILL.md +300 -706
  131. package/skills/arc/references/auth.md +19 -7
  132. package/skills/arc-code-review/SKILL.md +1 -1
  133. package/skills/arc-code-review/references/arc-cheatsheet.md +100 -322
  134. package/dist/createActionRouter-S3MLVYot.mjs +0 -220
  135. package/dist/index-bRjYu21O.d.mts +0 -1320
  136. package/dist/org/index.d.mts +0 -66
  137. package/dist/org/index.mjs +0 -486
  138. package/dist/org/types.d.mts +0 -82
  139. package/dist/org/types.mjs +0 -1
  140. package/dist/registry-I-ogLgL9.mjs +0 -46
  141. /package/dist/{EventTransport-CT_52aWU.d.mts → EventTransport-B1GFiYUy.d.mts} +0 -0
  142. /package/dist/{EventTransport-DLWoUMHy.mjs → EventTransport-ClEDfiMS.mjs} +0 -0
  143. /package/dist/{actionPermissions-CyUkQu6O.mjs → actionPermissions-Bjmvn7Eb.mjs} +0 -0
  144. /package/dist/{elevation-DgoeTyfX.mjs → elevation-Dci0AYLT.mjs} +0 -0
  145. /package/dist/{elevation-BXOWoGCF.d.mts → elevation-DvwtjDwu.d.mts} +0 -0
  146. /package/dist/{errorHandler-DFr45ZG4.d.mts → errorHandler-DuqTqeqn.d.mts} +0 -0
  147. /package/dist/{externalPaths-BD5nw6St.d.mts → externalPaths-ClykOQqa.d.mts} +0 -0
  148. /package/dist/{interface-beEtJyWM.d.mts → interface-BVkZsvEe.d.mts} +0 -0
  149. /package/dist/{interface-DfLGcus7.d.mts → interface-DoE6UoC2.d.mts} +0 -0
  150. /package/dist/{keys-CGcCbNyu.mjs → keys-DopsCuyQ.mjs} +0 -0
  151. /package/dist/{loadResources-DBMQg_Aj.mjs → loadResources-fol6JuvW.mjs} +0 -0
  152. /package/dist/{metrics-Qnvwc-LQ.mjs → metrics-B-PU4-Yu.mjs} +0 -0
  153. /package/dist/{replyHelpers-CK-FNO8E.mjs → replyHelpers-boS5Rx26.mjs} +0 -0
  154. /package/dist/{schemaIR-lYhC2gE5.mjs → schemaIR-DAOvBWgT.mjs} +0 -0
  155. /package/dist/{sessionManager-C4Le_UB3.d.mts → sessionManager-DlmaHUAl.d.mts} +0 -0
  156. /package/dist/{storage-Dfzt4VTl.d.mts → storage-HcAgP5Ni.d.mts} +0 -0
  157. /package/dist/{store-helpers-BkIN9-vu.mjs → store-helpers-5JgaxieH.mjs} +0 -0
  158. /package/dist/{tracing-QJVprktp.d.mts → tracing-bRqqUxFO.d.mts} +0 -0
  159. /package/dist/{versioning-BUrT5aP4.mjs → versioning-CuIwUQZ2.mjs} +0 -0
  160. /package/dist/{websocket-ChC2rqe1.d.mts → websocket-BJ0w-3Dt.d.mts} +0 -0
@@ -1,12 +1,12 @@
1
- import { a as QueryCacheConfig } from "./QueryCache-D41bfdBB.mjs";
2
- import { i as RequestScope } from "./types-CTYvcwHe.mjs";
3
- import { c as PermissionCheck, d as UserBase, n as FieldPermissionMap } from "./fields-COhcH3fk.mjs";
4
- import { n as DomainEvent } from "./EventTransport-CT_52aWU.mjs";
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";
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";
8
8
  import { DataAdapter, RepositoryLike } from "@classytic/repo-core/adapter";
9
- import { AggDateBucket, AggMeasure, AggTopN, QueryOptions, StandardRepo } from "@classytic/repo-core/repository";
9
+ import { AggDateBucket, AggMeasure, AggTopN, QueryOptions, StandardRepo, TenantPurgeStrategy } from "@classytic/repo-core/repository";
10
10
  import { LookupSpec } from "@classytic/repo-core/lookup";
11
11
  import { FieldRule, SchemaBuilderOptions } from "@classytic/repo-core/schema";
12
12
 
@@ -453,11 +453,11 @@ type CacheStatus = "HIT" | "STALE" | "MISS";
453
453
  * `BaseCrudController` / `BaseController` declarations.
454
454
  */
455
455
  type ArcControllerLike = {
456
- list: (...args: any[]) => unknown;
457
- get: (...args: any[]) => unknown;
458
- create: (...args: any[]) => unknown;
459
- update: (...args: any[]) => unknown;
460
- delete: (...args: any[]) => unknown;
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
461
  };
462
462
  /**
463
463
  * Return type of the controller's `list` method.
@@ -1569,8 +1569,39 @@ interface AggregationConfig {
1569
1569
  having?: AnyRecord;
1570
1570
  /** Order grouped rows by groupBy field, measure alias, or joined-alias path. */
1571
1571
  sort?: Record<string, 1 | -1>;
1572
- /** Hard cap on result rows. Applied at the IR level (LIMIT / `$limit`). */
1572
+ /**
1573
+ * Static hard cap on result rows. Always applied at the IR level
1574
+ * (LIMIT / `$limit`), regardless of URL params. Use when the
1575
+ * aggregation has a fixed-size shape ("top 10 categories"). Mutually
1576
+ * exclusive with `defaultLimit` / `maxLimit` — pick the static form
1577
+ * OR the URL-driven form, not both.
1578
+ */
1573
1579
  limit?: number;
1580
+ /**
1581
+ * URL-driven row limit — applied when the caller passes `?limit=N`.
1582
+ * When set, the auto-route reads `query.limit`, parses it as a
1583
+ * positive integer, caps it at `maxLimit` (or the framework default
1584
+ * if `maxLimit` is unset), and writes the result into `AggRequest.limit`.
1585
+ * When the caller omits `?limit`, this default applies.
1586
+ *
1587
+ * **DoS defense.** Auto-generated `/aggregations/:name` routes today
1588
+ * have no upper bound on response size. A `groupBy: 'userId'` on a
1589
+ * 10M-user table without `defaultLimit` returns a 10M-row JSON. Setting
1590
+ * `defaultLimit: 100, maxLimit: 1000` bounds the response shape while
1591
+ * letting power users request up to 1000 rows when they need them.
1592
+ *
1593
+ * Mutually exclusive with the static `limit` — boot error if both set.
1594
+ * Setting `defaultLimit` without `maxLimit` uses the framework
1595
+ * default cap (`AGG_FRAMEWORK_MAX_LIMIT = 1000`) — explicit is better.
1596
+ */
1597
+ defaultLimit?: number;
1598
+ /**
1599
+ * Hard ceiling for URL-driven `?limit=N`. Only meaningful when
1600
+ * `defaultLimit` is set; ignored otherwise. Defaults to
1601
+ * `AGG_FRAMEWORK_MAX_LIMIT` (1000) when omitted but `defaultLimit` is
1602
+ * present. Boot validation: must be ≥ `defaultLimit`.
1603
+ */
1604
+ maxLimit?: number;
1574
1605
  /**
1575
1606
  * Top-N-per-group filter. Keeps only the top `limit` rows per
1576
1607
  * partition, ranked by `sortBy`. The classic "top 3 products per
@@ -1964,6 +1995,62 @@ interface ControllerLike {
1964
1995
  //#region src/types/resource.d.ts
1965
1996
  /** Standard controller type alias for CRUD operations. */
1966
1997
  type CrudController<TDoc> = IController<TDoc>;
1998
+ /**
1999
+ * Tenant-cleanup declaration on a resource — compliance-grade strategy
2000
+ * for what happens to this resource's rows when the owning organization
2001
+ * is deleted. Surfaces in arc's org-delete cascade runner and in
2002
+ * registry introspection (audit scripts ask "what happens to this
2003
+ * resource on org delete?").
2004
+ *
2005
+ * Strategy variants:
2006
+ * - `hard` — permanent removal (GDPR right-to-be-forgotten).
2007
+ * - `soft` — recoverable; pair with TTL for eventual hard-purge.
2008
+ * - `anonymize` — keep the row (legal retention) but clear PII
2009
+ * (HIPAA / PCI / SOX-compatible).
2010
+ * - `skip` — explicit opt-out with mandatory `reason`.
2011
+ *
2012
+ * See {@link ResourceConfig.onTenantDelete} for the full decision tree.
2013
+ */
2014
+ interface OnTenantDeleteConfig {
2015
+ /**
2016
+ * What to do with rows whose `tenantField` matches the deleted org.
2017
+ * Discriminated union from `@classytic/repo-core/repository` — every
2018
+ * kit's `purgeByField` consumes the same shape.
2019
+ */
2020
+ strategy: TenantPurgeStrategy;
2021
+ /**
2022
+ * Resources are processed in ascending `priority` order. Use to land
2023
+ * leaf data (logs, events) before aggregate references. Default `100`.
2024
+ */
2025
+ priority?: number;
2026
+ /**
2027
+ * Rows per chunk for the underlying `purgeByField` call — bounds
2028
+ * lock contention + replication-log pressure on very large tenants.
2029
+ * Default kit-specific (~1000).
2030
+ */
2031
+ batchSize?: number;
2032
+ }
2033
+ /**
2034
+ * Resolved tenant-purge declaration — what arc actually runs when
2035
+ * `cascadeDeleteForOrganization` fires. Computed once at boot from the
2036
+ * resource's `onTenantDelete` declaration.
2037
+ *
2038
+ * Exposed via `ResourceDefinition.resolvedTenantPurge` and
2039
+ * `getCascadingResourcesWithMetadata(registry)` so audit tooling can
2040
+ * answer "is this resource really going to hard-delete?" without
2041
+ * reading the source.
2042
+ */
2043
+ interface ResolvedTenantPurge {
2044
+ readonly strategy: TenantPurgeStrategy;
2045
+ readonly priority: number;
2046
+ readonly batchSize?: number;
2047
+ /**
2048
+ * Where the strategy came from — `'declared'` (host wrote
2049
+ * `onTenantDelete` explicitly) or `'disabled'` (no declaration —
2050
+ * runner skips this resource).
2051
+ */
2052
+ readonly source: "declared" | "disabled";
2053
+ }
1967
2054
  /**
1968
2055
  * Per-resource cache configuration for QueryCache. Enables
1969
2056
  * stale-while-revalidate, auto-invalidation on mutations, and
@@ -2285,11 +2372,55 @@ interface RouteDefinition {
2285
2372
  readonly path: string;
2286
2373
  /**
2287
2374
  * Route handler.
2288
- * - String: controller method name (Arc pipeline)
2375
+ * - String: controller method name (Arc pipeline) — runtime lookup, no TS coverage on typos.
2289
2376
  * - Function without `raw: true`: receives IRequestContext, returns IControllerResponse (Arc pipeline)
2290
2377
  * - Function with `raw: true`: raw Fastify handler `(request, reply)`
2378
+ *
2379
+ * Prefer `controllerMethod` (2.16) over the string form when you want the
2380
+ * compiler to catch typos. `handler` stays optional when `controllerMethod`
2381
+ * is set — exactly one of the two must be declared.
2291
2382
  */
2292
- readonly handler: string | ControllerHandler | RouteHandlerMethod | ((request: FastifyRequest<Record<string, unknown>>, reply: FastifyReply) => unknown);
2383
+ readonly handler?: string | ControllerHandler | RouteHandlerMethod | ((request: FastifyRequest<Record<string, unknown>>, reply: FastifyReply) => unknown);
2384
+ /**
2385
+ * Typed function-reference handler (2.16). Receives the live controller
2386
+ * instance and returns the method to invoke — TypeScript catches typos
2387
+ * and surfaces autocomplete on the controller's method names. Prefer
2388
+ * this over the string `handler` form for any host that uses a typed
2389
+ * controller subclass.
2390
+ *
2391
+ * Resolved ONCE at route-registration time (the same path string
2392
+ * handlers go through), so there's no per-request lookup overhead.
2393
+ * The returned method is bound to the controller before dispatch.
2394
+ *
2395
+ * Mutually exclusive with `handler` — passing both throws at boot
2396
+ * with a clear "pick one" message. The runtime contract on what the
2397
+ * returned function accepts mirrors the `handler` rules: a plain
2398
+ * `ControllerHandler` for pipeline routes, a raw Fastify handler when
2399
+ * the route is `raw: true`.
2400
+ *
2401
+ * Typed loosely (`(controller: unknown) => …`) at the type-system
2402
+ * boundary because `RouteDefinition` is not generic over the
2403
+ * controller shape — host code annotates the parameter to opt in:
2404
+ *
2405
+ * @example
2406
+ * ```ts
2407
+ * class PostController extends BaseController<Post> {
2408
+ * async getStats(ctx: IRequestContext) { … }
2409
+ * }
2410
+ *
2411
+ * defineResource({
2412
+ * controller: new PostController(repo),
2413
+ * routes: [{
2414
+ * method: 'GET',
2415
+ * path: '/stats',
2416
+ * controllerMethod: (c: PostController) => c.getStats,
2417
+ * // ^^^^^^^^^^^^^^ TS catches typos here
2418
+ * permissions: requireAuth(),
2419
+ * }],
2420
+ * });
2421
+ * ```
2422
+ */
2423
+ readonly controllerMethod?: (controller: unknown) => ControllerHandler | RouteHandlerMethod;
2293
2424
  /** Permission check — REQUIRED */
2294
2425
  readonly permissions: PermissionCheck;
2295
2426
  /**
@@ -2309,6 +2440,24 @@ interface RouteDefinition {
2309
2440
  readonly preHandler?: RouteHandlerMethod[] | ((fastify: FastifyInstance) => RouteHandlerMethod[]);
2310
2441
  /** Pre-auth handlers (run before authentication) */
2311
2442
  readonly preAuth?: RouteHandlerMethod[];
2443
+ /**
2444
+ * Opt this custom route into the multiTenant preset's tenant scoping.
2445
+ *
2446
+ * When `true` AND the resource declares `multiTenantPreset` (or
2447
+ * `flexibleMultiTenantPreset`), arc prepends the preset's tenant
2448
+ * filter + injection middleware to this route's chain — the same
2449
+ * pair `update` gets. The handler can then read the resolved tenant
2450
+ * via `getOrgId(req.scope)` / `req._tenantFields` (or, for write
2451
+ * routes, off `req.body` after injection) without re-implementing
2452
+ * the scope read + header fallback + 400 boilerplate.
2453
+ *
2454
+ * Throws at boot if set when no multiTenant preset is wired — the
2455
+ * misconfiguration would otherwise be silently insecure (read routes
2456
+ * returning every tenant's rows).
2457
+ *
2458
+ * @default false
2459
+ */
2460
+ readonly tenantScope?: boolean;
2312
2461
  /** SSE streaming mode */
2313
2462
  readonly streamResponse?: boolean;
2314
2463
  /**
@@ -2364,6 +2513,25 @@ interface ActionDefinition {
2364
2513
  readonly schema?: unknown;
2365
2514
  /** Description for OpenAPI docs and MCP tool */
2366
2515
  readonly description?: string;
2516
+ /**
2517
+ * Whether this action needs an entity id from the URL.
2518
+ *
2519
+ * - `true` (default) — mounts under `POST /<prefix>/:id/action`. The `id`
2520
+ * path param is required; handler receives it as the first argument.
2521
+ * Use for actions that operate on an existing entity: `approve`,
2522
+ * `dispatch`, `cancel`, `archive`.
2523
+ * - `false` — mounts under `POST /<prefix>/action` (no `:id` segment).
2524
+ * Handler receives an empty-string first argument. Use for
2525
+ * collection-level actions that create / search / bulk-mutate:
2526
+ * `propose` (creates a new entity), `search` (returns rows), `bulk`.
2527
+ *
2528
+ * 2.15.5: previously every action had to live under `:id/action`, forcing
2529
+ * `propose`-style actions to swallow a meaningless URL parameter and
2530
+ * making the auto-generated MCP tool advertise an `id` field agents
2531
+ * had no value for. Setting `id: false` mounts the action at the
2532
+ * resource root and drops `id` from the MCP tool's input shape.
2533
+ */
2534
+ readonly id?: boolean;
2367
2535
  /**
2368
2536
  * MCP tool generation:
2369
2537
  * - omitted/true: auto-generate
@@ -2570,13 +2738,37 @@ interface ResourceConfig<TDoc = AnyRecord> {
2570
2738
  /**
2571
2739
  * Custom routes beyond CRUD. Presets also merge their routes here.
2572
2740
  *
2573
- * @example
2741
+ * **Route handlers return `IControllerResponse<T>` shape** —
2742
+ * `{ data, status?, meta?, headers? }`. Returning a bare value (array,
2743
+ * object, primitive) is supported via auto-envelope (2.17+) but the
2744
+ * explicit envelope is the canonical contract — declared `fields:`
2745
+ * permissions, custom `status`, `meta`, and `headers` only work when
2746
+ * you return the envelope. Set `raw: true` on a route to opt out of
2747
+ * arc's pipeline entirely (custom streaming, SSE, manual `reply.send()`).
2748
+ *
2749
+ * **Path collisions with auto-CRUD are detected at `defineResource()` time.**
2750
+ * If you declare a route that shares method+path with an auto-CRUD op
2751
+ * (e.g. `POST /` collides with `create`), validation throws with the
2752
+ * exact `disabledRoutes` line to add. Use one of:
2753
+ * - `disabledRoutes: ['create']` — suppress the auto-CRUD op
2754
+ * - `crud: { list: true, get: true }` — opt-in allow-list (preferred)
2755
+ * - `disableDefaultRoutes: true` — turn off all auto-CRUD on this resource
2756
+ *
2757
+ * @example Custom route alongside default CRUD:
2574
2758
  * ```typescript
2575
2759
  * routes: [
2576
2760
  * { method: 'GET', path: '/stats', handler: 'getStats', permissions: auth() },
2577
2761
  * { method: 'POST', path: '/webhook', handler: webhookFn, raw: true, permissions: auth() },
2578
2762
  * ]
2579
2763
  * ```
2764
+ *
2765
+ * @example Custom POST replacing the auto-CRUD `create`:
2766
+ * ```typescript
2767
+ * disabledRoutes: ['create'],
2768
+ * routes: [
2769
+ * { method: 'POST', path: '/', handler: customCreate, permissions: requireAuth() },
2770
+ * ]
2771
+ * ```
2580
2772
  */
2581
2773
  routes?: RouteDefinition[];
2582
2774
  /**
@@ -2630,13 +2822,84 @@ interface ResourceConfig<TDoc = AnyRecord> {
2630
2822
  aggregations?: AggregationsMap;
2631
2823
  disableCrud?: boolean;
2632
2824
  disableDefaultRoutes?: boolean;
2633
- /** Specific routes to disable */
2825
+ /** Specific routes to disable (negative-form opt-out). */
2634
2826
  disabledRoutes?: CrudRouteKey[];
2827
+ /**
2828
+ * Declarative CRUD allow-list — what's ENABLED is explicit (positive form).
2829
+ *
2830
+ * Mutually exclusive with `disabledRoutes` — passing both is a config
2831
+ * error and throws at boot. Use this when you want least-privilege
2832
+ * defaults: a new CRUD op added in a future arc release won't silently
2833
+ * leak through your `disabledRoutes` list because every op is opt-in.
2834
+ *
2835
+ * - `crud: { list: true, get: true }` — only `list` + `get` mount;
2836
+ * `create` / `update` / `delete` are NOT mounted.
2837
+ * - `crud: false` — equivalent to `disableDefaultRoutes: true` (no CRUD at all).
2838
+ * - `crud: undefined` (default) — every op mounts (legacy behaviour).
2839
+ *
2840
+ * 2.16: prefer this over `disabledRoutes` for new resources. The
2841
+ * negative form stays for back-compat but won't be the documented
2842
+ * default going forward.
2843
+ *
2844
+ * @example
2845
+ * ```ts
2846
+ * defineResource({
2847
+ * name: 'audit-log',
2848
+ * crud: { list: true, get: true }, // read-only — no create/update/delete
2849
+ * permissions: { list: requireRoles(['admin']), get: requireRoles(['admin']) },
2850
+ * });
2851
+ * ```
2852
+ */
2853
+ crud?: false | { [K in CrudRouteKey]?: boolean };
2635
2854
  /**
2636
2855
  * Field name used for multi-tenant scoping (default: 'organizationId').
2637
2856
  * Override to match your schema: 'workspaceId', 'tenantId', etc.
2638
2857
  */
2639
2858
  tenantField?: string | false;
2859
+ /**
2860
+ * Tenant-cleanup declaration — what `cascadeDeleteForOrganization`
2861
+ * does with this resource's rows when an organization is deleted.
2862
+ * Required for the resource to participate in the cascade; unflagged
2863
+ * resources are never touched.
2864
+ *
2865
+ * - `{ strategy: { type: 'hard' } }` — permanent delete (GDPR).
2866
+ * - `{ strategy: { type: 'soft' } }` — set `deleted: true` + `deletedAt`
2867
+ * (recoverable; pair with TTL for eventual hard-purge).
2868
+ * - `{ strategy: { type: 'anonymize', fields: { name: '[REDACTED]', email: null } } }`
2869
+ * — keep the row (legal retention) but clear PII linkage. HIPAA /
2870
+ * PCI / SOX-compatible. Field values can be static or `(doc) =>
2871
+ * value` for derived patches (hashes, etc.).
2872
+ * - `{ strategy: { type: 'skip', reason: 'audit-retained-per-SOX' } }`
2873
+ * — explicit opt-out with **mandatory** reason. Surfaces in audit reports.
2874
+ *
2875
+ * **Priority** — lower runs first. Default `100`. Use to land leaf data
2876
+ * before aggregate references:
2877
+ * - `10` : bulk leaf data (events, logs)
2878
+ * - `50` : business entities (orders, invoices)
2879
+ * - `100` : default
2880
+ *
2881
+ * Priority groups are barriers even under concurrency — all
2882
+ * priority-10 resources finish before any priority-50 starts.
2883
+ *
2884
+ * **Batch size** — rows per chunk for the underlying `purgeByField`
2885
+ * call. Default kit-specific (~1000). Tune for very large tenants.
2886
+ *
2887
+ * @example Compliance-retained financial ledger
2888
+ * ```ts
2889
+ * defineResource({
2890
+ * name: 'invoice',
2891
+ * tenantField: 'organizationId',
2892
+ * onTenantDelete: {
2893
+ * strategy: {
2894
+ * type: 'anonymize',
2895
+ * fields: { customerName: '[REDACTED]', customerEmail: null },
2896
+ * },
2897
+ * priority: 50,
2898
+ * },
2899
+ * });
2900
+ * ```
2901
+ */
2902
+ onTenantDelete?: OnTenantDeleteConfig;
2640
2903
  /**
2641
2904
  * Default sort applied to `list` responses when the request doesn't
2642
2905
  * specify one. Arc's built-in default is `-createdAt` (Mongo convention).
@@ -2678,6 +2941,28 @@ interface ResourceConfig<TDoc = AnyRecord> {
2678
2941
  skipValidation?: boolean;
2679
2942
  /** Don't register in introspection */
2680
2943
  skipRegistry?: boolean;
2944
+ /**
2945
+ * Per-resource MCP opt-out.
2946
+ *
2947
+ * - omitted / `true` (default) — resource may be surfaced by `mcpPlugin`,
2948
+ * subject to the plugin's `expose` / `include` / `exclude` selection.
2949
+ * - `false` — opt this resource OUT of MCP tool generation entirely.
2950
+ * Always wins over the plugin's `expose` / `include` allowlist;
2951
+ * keeps the opt-out colocated with the resource definition instead
2952
+ * of in a host-side blocklist that drifts as resources are added.
2953
+ *
2954
+ * Use the local opt-out for resources that should never expose tools
2955
+ * (internal back-office, audit-trail readers, system-managed entities).
2956
+ * Use the plugin-level `expose`/`include` allowlist when the cut is
2957
+ * cross-cutting (only a handful of resources should be agent-callable
2958
+ * across the whole app).
2959
+ *
2960
+ * @example
2961
+ * ```ts
2962
+ * defineResource({ name: 'internal-job-log', mcp: false, ... });
2963
+ * ```
2964
+ */
2965
+ mcp?: boolean;
2681
2966
  /** Internal: track applied presets */
2682
2967
  _appliedPresets?: string[];
2683
2968
  /** HTTP method for update routes. Default: 'PATCH' */
@@ -2718,6 +3003,39 @@ interface ResourceConfig<TDoc = AnyRecord> {
2718
3003
  };
2719
3004
  }
2720
3005
  //#endregion
3006
+ //#region src/core/defineResource/diagnostics.d.ts
3007
+ /**
3008
+ * Boot-time diagnostics produced by the `defineResource()` validation pipeline.
3009
+ *
3010
+ * `defineResource()` runs at module load — long before any Fastify instance
3011
+ * exists — so non-fatal warnings (redundant field-rule flags, ambiguous
3012
+ * preset combinations, etc.) cannot be emitted through a logger at the
3013
+ * point they are detected. Instead we COLLECT them into a structured
3014
+ * `ResourceDiagnostic[]`, attach the array to `ResourceDefinition._diagnostics`,
3015
+ * and flush each entry through `fastify.log.warn` on first mount inside
3016
+ * `buildResourcePlugin`. Hosts thus retain full control over framework
3017
+ * output (silencing, redirecting, structured logging) — the framework
3018
+ * never reaches for `console.*` directly outside of `src/cli/`.
3019
+ *
3020
+ * Hard errors continue to `throw` inside the validation pipeline — those
3021
+ * surface synchronously at define-time, which is the right UX for
3022
+ * "this resource will never work" failures.
3023
+ */
3024
+ /**
3025
+ * One non-fatal diagnostic produced during resource validation.
3026
+ *
3027
+ * - `severity`: log level the host logger uses (`warn` for misconfigurations
3028
+ * the host should clean up, `info` for deprecation hints).
3029
+ * - `code`: stable identifier for the diagnostic — hosts and tests can match
3030
+ * on this without parsing the human-readable message.
3031
+ * - `message`: pre-formatted line, resource name already interpolated.
3032
+ */
3033
+ interface ResourceDiagnostic {
3034
+ severity: "warn" | "info";
3035
+ code: string;
3036
+ message: string;
3037
+ }
3038
+ //#endregion
2721
3039
  //#region src/core/defineResource/ResourceDefinition.d.ts
2722
3040
  /**
2723
3041
  * Constructor input shape — `ResourceConfig` plus the metadata
@@ -2767,7 +3085,23 @@ declare class ResourceDefinition<TDoc = AnyRecord> {
2767
3085
  readonly pipe?: PipelineConfig;
2768
3086
  readonly fields?: FieldPermissionMap;
2769
3087
  readonly cache?: ResourceCacheConfig;
3088
+ /**
3089
+ * Per-resource MCP opt-out. `false` keeps the resource out of every
3090
+ * `mcpPlugin` registration regardless of the plugin's `expose` /
3091
+ * `include` allowlist — local opt-out is authoritative. See
3092
+ * `ResourceConfig.mcp` for the host-facing surface.
3093
+ */
3094
+ readonly mcp: boolean;
2770
3095
  readonly tenantField?: string | false;
3096
+ /** Tenant-cleanup strategy on org delete — see `OnTenantDeleteConfig`. */
3097
+ readonly onTenantDelete?: OnTenantDeleteConfig;
3098
+ /**
3099
+ * Resolved tenant-purge strategy — what `cascadeDeleteForOrganization`
3100
+ * actually runs. Computed once at boot from `onTenantDelete`. Audit /
3101
+ * introspection tooling reads this instead of re-running the rule at
3102
+ * the call site.
3103
+ */
3104
+ readonly resolvedTenantPurge: ResolvedTenantPurge;
2771
3105
  readonly idField?: string;
2772
3106
  readonly queryParser?: QueryParserInterface;
2773
3107
  readonly _appliedPresets: string[];
@@ -2778,6 +3112,17 @@ declare class ResourceDefinition<TDoc = AnyRecord> {
2778
3112
  priority: number;
2779
3113
  }>;
2780
3114
  _registryMeta?: RegisterOptions;
3115
+ /**
3116
+ * Boot-time validation diagnostics (non-fatal — hard errors throw
3117
+ * synchronously in `validateDefineResourceConfig`). Populated when
3118
+ * the host's config contains redundant / ambiguous flags that
3119
+ * shouldn't crash the boot but the host should clean up. Flushed
3120
+ * through `fastify.log.warn` on first mount inside
3121
+ * `buildResourcePlugin` so the host's configured logger owns the
3122
+ * output — the framework never speaks to `console.*` from `src/`
3123
+ * outside of the CLI.
3124
+ */
3125
+ _diagnostics?: ResourceDiagnostic[];
2781
3126
  /**
2782
3127
  * Per-host idempotency guard used by `buildResourcePlugin` to
2783
3128
  * skip duplicate shared-state writes when the same resource is
@@ -2852,8 +3197,25 @@ interface RouteRow {
2852
3197
  }
2853
3198
  declare class ResourceRegistry {
2854
3199
  private _resources;
3200
+ /**
3201
+ * Parallel map of full `DataAdapter` instances. The public `RegistryEntry.adapter`
3202
+ * field is intentionally narrowed to `{ type, name }` so introspection can be
3203
+ * JSON-serialized — but cascade / cleanup / migration helpers need the live
3204
+ * adapter (and its `.repository`) to do real work. Stored here, behind
3205
+ * `getAdapter(name)`, so the public metadata stays serializable and the
3206
+ * runtime-only handle is still reachable.
3207
+ */
3208
+ private _adapters;
2855
3209
  private _frozen;
2856
3210
  constructor();
3211
+ /**
3212
+ * Get the live `DataAdapter` for a registered resource — the handle whose
3213
+ * `.repository` cascade / cleanup helpers actually call. Returns `undefined`
3214
+ * when the resource is unknown OR was registered without an adapter
3215
+ * (service-only resources). Typed loosely (`unknown`-shaped fields) so
3216
+ * consumers cast to their kit's adapter type at the use site.
3217
+ */
3218
+ getAdapter<T = unknown>(name: string): T | undefined;
2857
3219
  /**
2858
3220
  * Register a resource
2859
3221
  */
@@ -2923,7 +3285,16 @@ declare class ResourceRegistry {
2923
3285
  */
2924
3286
  unfreeze(): void;
2925
3287
  /**
2926
- * Reset registry — clear all resources and unfreeze
3288
+ * Reset registry — clear all resources, drop their parallel live-adapter
3289
+ * handles, and unfreeze.
3290
+ *
3291
+ * The `_adapters` map (added in 2.15.5 so cascade / cleanup helpers can
3292
+ * reach `adapter.repository` after registration) must clear alongside
3293
+ * `_resources`. Pre-2.16 this method dropped the public entries but
3294
+ * left the live adapters dangling, so a test that called `reset()`
3295
+ * between cases would see ghost adapters and either (a) leak a live
3296
+ * Mongo connection across describe blocks or (b) `cascadeDeleteForOrganization`
3297
+ * iterate over a defunct registry entry. Clear both halves together.
2927
3298
  */
2928
3299
  reset(): void;
2929
3300
  /** @internal Alias for unfreeze() */
@@ -3306,6 +3677,21 @@ interface RegistryEntry extends ResourceMetadata {
3306
3677
  } | null;
3307
3678
  events?: string[];
3308
3679
  disableDefaultRoutes?: boolean;
3680
+ /**
3681
+ * 2.15.5 — multi-tenant scoping field declared on the resource
3682
+ * (defaults to `'organizationId'`; `false` for company-wide tables).
3683
+ * Surfaced so introspection / cascade helpers can scope deletes
3684
+ * without re-reading the resource definition.
3685
+ */
3686
+ tenantField?: string | false;
3687
+ /**
3688
+ * Resolved tenant-purge strategy — what arc actually runs when
3689
+ * `cascadeDeleteForOrganization` fires for this resource. Computed
3690
+ * at boot from the resource's `onTenantDelete` declaration. Surfaced
3691
+ * here so introspection / audit scripts can answer "what happens on
3692
+ * org-delete?" without re-reading the resource definition.
3693
+ */
3694
+ resolvedTenantPurge?: ResolvedTenantPurge;
3309
3695
  openApiSchemas?: OpenApiSchemas;
3310
3696
  registeredAt?: string;
3311
3697
  /** Field-level permissions metadata (for OpenAPI data) */
@@ -3340,7 +3726,15 @@ interface RegistryEntry extends ResourceMetadata {
3340
3726
  readonly name: string;
3341
3727
  readonly description?: string; /** Raw per-action schema (JSON Schema, Zod v4, or legacy field map) */
3342
3728
  readonly schema?: unknown; /** Per-action permission check (if different from resource-level `actionPermissions`) */
3343
- readonly permissions?: PermissionCheck; /** MCP tool generation flag — `false` to skip, object for overrides */
3729
+ readonly permissions?: PermissionCheck;
3730
+ /**
3731
+ * 2.15.5: mount point — `true` (default) for `POST /:id/action`,
3732
+ * `false` for `POST /action` (resource-root, no `:id` path param).
3733
+ * Consumed by registry enumeration, OpenAPI generation, and FE
3734
+ * resource manifests so callers can pick the right URL without
3735
+ * reading the action definition itself.
3736
+ */
3737
+ readonly id?: boolean; /** MCP tool generation flag — `false` to skip, object for overrides */
3344
3738
  readonly mcp?: boolean | {
3345
3739
  readonly description?: string;
3346
3740
  readonly annotations?: Record<string, unknown>;
@@ -3374,7 +3768,24 @@ interface RegistryEntry extends ResourceMetadata {
3374
3768
  field: string;
3375
3769
  maxRangeDays?: number;
3376
3770
  }; /** Whether the aggregation requires named filters — surfaced in docs. */
3377
- readonly requireFilters?: readonly string[]; /** MCP tool generation flag — `false` to skip, object for overrides. */
3771
+ readonly requireFilters?: readonly string[];
3772
+ /**
3773
+ * Static result-row cap (no URL override). Mutually exclusive with
3774
+ * `defaultLimit` / `maxLimit`. Surfaced so OpenAPI docs can mention
3775
+ * the fixed cap in the description.
3776
+ */
3777
+ readonly limit?: number;
3778
+ /**
3779
+ * URL-driven default limit (caller may pass `?limit=N`). When set,
3780
+ * OpenAPI docs render `?limit` as a query parameter with this
3781
+ * default and `maxLimit` as the maximum.
3782
+ */
3783
+ readonly defaultLimit?: number;
3784
+ /**
3785
+ * URL-driven limit ceiling (only meaningful with `defaultLimit`).
3786
+ * OpenAPI docs render this as the `maximum` constraint on `?limit`.
3787
+ */
3788
+ readonly maxLimit?: number; /** MCP tool generation flag — `false` to skip, object for overrides. */
3378
3789
  readonly mcp?: boolean | {
3379
3790
  readonly description?: string;
3380
3791
  readonly annotations?: Record<string, unknown>;
@@ -3463,4 +3874,4 @@ interface ValidateOptions {
3463
3874
  strict?: boolean;
3464
3875
  }
3465
3876
  //#endregion
3466
- export { OpenApiSchemas as $, SoftDeleteMixin as $t, RequestIdOptions as A, afterCreate as An, Guard as At, defineResource as B, Authenticator as Bt, RequestContext as C, HookContext as Cn, AggregationConfig as Ct, HealthCheck as D, HookRegistration as Dn, AggregationMaterializedResult as Dt, GracefulShutdownOptions as E, HookPhase as En, AggregationMaterializedContext as Et, FastifyWithDecorators as F, beforeUpdate as Fn, PipelineContext as Ft, ActionsMap as G, ApiResponse as Gt, ActionDefinition as H, JwtContext as Ht, MiddlewareHandler as I, createHookSystem as In, PipelineStep as It, CrudRouteKey as J, ObjectId as Jt, ArcFieldRule as K, ArcRequest as Kt, RequestWithExtras as L, defineHook as Ln, Transform as Lt, EventsDecorator as M, afterUpdate as Mn, NextFunction as Mt, FastifyRequestExtras as N, beforeCreate as Nn, OperationFilter as Nt, HealthOptions as O, HookSystem as On, AggregationRateLimit as Ot, FastifyWithAuth as P, beforeDelete as Pn, PipelineConfig as Pt, MiddlewareConfig as Q, SoftDeleteExt as Qt, RegisterOptions as R, AuthHelpers as Rt, QueryParserInterface as S, DefineHookOptions as Sn, AggregationCacheConfig as St, CrudRouterOptions as T, HookOperation as Tn, AggregationIndexHint as Tt, ActionEntry as U, TokenPair as Ut, ResourceDefinition as V, AuthenticatorContext as Vt, ActionHandlerFn as W, AnyRecord as Wt, EventDefinition as X, UserOrganization as Xt, CrudSchemas as Y, UserLike as Yt, FieldRule$1 as Z, BaseController as Zt, ControllerQueryOptions as _, ListResult as _n, IControllerResponse as _t, InferAdapterDoc as a, BulkMixin as an, ResourceConfig as at, ParsedQuery as b, AccessControl as bn, AggMeasureInput as bt, TypedController as c, ControllerConfigurableOptions as cn, ResourcePermissions as ct, PaginationResult as d, QueryResolverConfig as dn, RouteMethod as dt, TreeExt as en, PresetFunction as et, IntrospectionData as f, ArcCreateResult as fn, RouteSchemaOptions as ft, ArcInternalMetadata as g, ArcUpdateResult as gn, IController as gt, ResourceMetadata as h, ArcListResult as hn, FastifyHandler as ht, ValidationResult as i, BulkExt as in, ResourceCacheConfig as it, ArcDecorator as j, afterDelete as jn, Interceptor as jt, IntrospectionPluginOptions as k, HookSystemOptions as kn, AggregationsMap as kt, TypedRepository as l, ControllerConstructionOptions as ln, RouteDefinition as lt, RegistryStats as m, ArcGetResult as mn, ControllerLike as mt, ConfigError as n, SlugExt as nn, PresetResult as nt, InferDocType as o, BaseControllerOptions as on, ResourceHookContext as ot, RegistryEntry as p, ArcDeleteResult as pn, ControllerHandler as pt, CrudController as q, JWTPayload as qt, ValidateOptions as r, SlugMixin as rn, RateLimitConfig as rt, InferResourceDoc as s, BaseCrudController as sn, ResourceHooks as st, RouteHandlerMethod$1 as t, TreeMixin as tn, PresetHook as tt, TypedResourceConfig as u, QueryResolver as un, RouteMcpConfig as ut, LookupOption as v, BodySanitizer as vn, IRequestContext as vt, ServiceContext as w, HookHandler as wn, AggregationDateRangeRequirement as wt, PopulateOption as x, AccessControlConfig as xn, AggMeasureShorthand as xt, OwnershipCheck as y, BodySanitizerConfig as yn, RouteHandler as yt, ResourceRegistry as z, AuthPluginOptions as zt };
3877
+ 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 };
package/dist/index.d.mts CHANGED
@@ -1,10 +1,10 @@
1
- import { $t as SoftDeleteMixin, A as RequestIdOptions, B as defineResource, C as RequestContext, Ct as AggregationConfig, D as HealthCheck, Dt as AggregationMaterializedResult, E as GracefulShutdownOptions, Et as AggregationMaterializedContext, F as FastifyWithDecorators, Gt as ApiResponse, J as CrudRouteKey, Kt as ArcRequest, L as RequestWithExtras, N as FastifyRequestExtras, O as HealthOptions, Ot as AggregationRateLimit, P as FastifyWithAuth, Q as MiddlewareConfig, Qt as SoftDeleteExt, S as QueryParserInterface, St as AggregationCacheConfig, T as CrudRouterOptions, Tt as AggregationIndexHint, V as ResourceDefinition, Wt as AnyRecord, X as EventDefinition, Xt as UserOrganization, Y as CrudSchemas, Z as FieldRule, Zt as BaseController, _n as ListResult, _t as IControllerResponse, a as InferAdapterDoc, an as BulkMixin, at as ResourceConfig, bt as AggMeasureInput, c as TypedController, cn as ControllerConfigurableOptions, d as PaginationResult, en as TreeExt, et as PresetFunction, f as IntrospectionData, fn as ArcCreateResult, ft as RouteSchemaOptions, g as ArcInternalMetadata, gn as ArcUpdateResult, gt as IController, h as ResourceMetadata, hn as ArcListResult, i as ValidationResult, in as BulkExt, k as IntrospectionPluginOptions, kt as AggregationsMap, l as TypedRepository, ln as ControllerConstructionOptions, m as RegistryStats, mn as ArcGetResult, mt as ControllerLike, n as ConfigError, nn as SlugExt, nt as PresetResult, o as InferDocType, on as BaseControllerOptions, p as RegistryEntry, pn as ArcDeleteResult, q as CrudController, qt as JWTPayload, r as ValidateOptions, rn as SlugMixin, rt as RateLimitConfig, s as InferResourceDoc, sn as BaseCrudController, t as RouteHandlerMethod, tn as TreeMixin, u as TypedResourceConfig, vt as IRequestContext, w as ServiceContext, wt as AggregationDateRangeRequirement, xt as AggMeasureShorthand, y as OwnershipCheck, yt as RouteHandler, zt as AuthPluginOptions } from "./index-BswOSJCE.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-COhcH3fk.mjs";
3
- import { A as MAX_SEARCH_LENGTH, C as DEFAULT_UPDATE_METHOD, D as HookPhase, E as HookOperation, M as MutationOperation, N as RESERVED_QUERY_PARAMS, O as MAX_FILTER_DEPTH, P as SYSTEM_FIELDS, S as DEFAULT_TENANT_FIELD, T as HOOK_PHASES, _ as CrudOperation, b as DEFAULT_MAX_LIMIT, f as defineResourceVariants, g as CRUD_OPERATIONS, h as defineAggregation, j as MUTATION_OPERATIONS, k as MAX_REGEX_LENGTH, s as getControllerScope, v as DEFAULT_ID_FIELD, w as HOOK_OPERATIONS, x as DEFAULT_SORT, y as DEFAULT_LIMIT } from "./index-BstGxcc3.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-BTqLEvhu.mjs";
5
- import { ct as NotFoundError, ht as createDomainError, it as ArcError, mt as ValidationError, pt as UnauthorizedError, st as ForbiddenError, t as getUserId } from "./index-bRjYu21O.mjs";
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-DBDgy6Hw.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-CC_pgZjY.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";
6
6
 
7
7
  //#region src/index.d.ts
8
8
  declare const version: string;
9
9
  //#endregion
10
- export { type AggMeasureInput, type AggMeasureShorthand, type AggregationCacheConfig, type AggregationConfig, type AggregationDateRangeRequirement, type AggregationIndexHint, type AggregationMaterializedContext, type AggregationMaterializedResult, type AggregationRateLimit, type AggregationsMap, type AnyRecord, type ApiResponse, type ArcCreateResult, type ArcDeleteResult, ArcError, type ArcGetResult, type ArcInternalMetadata, type ArcListResult, type ArcRequest, type ArcUpdateResult, type AuthPluginOptions, BaseController, type BaseControllerOptions, BaseCrudController, type BulkExt, BulkMixin, CRUD_OPERATIONS, type ConfigError, type ControllerConfigurableOptions, type ControllerConstructionOptions, type ControllerLike, type CrudController, type CrudOperation, type CrudRouteKey, type CrudRouterOptions, type CrudSchemas, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, type DynamicPermissionMatrix, type DynamicPermissionMatrixConfig, type EventDefinition, type FastifyRequestExtras, type FastifyWithAuth, type FastifyWithDecorators, type FieldPermission, type FieldPermissionMap, type FieldRule, ForbiddenError, type GracefulShutdownOptions, HOOK_OPERATIONS, HOOK_PHASES, type HealthCheck, type HealthOptions, type HookOperation, type HookPhase, type IController, type IControllerResponse, type IRequestContext, type InferAdapterDoc, type InferDocType, type InferResourceDoc, type IntrospectionData, type IntrospectionPluginOptions, type JWTPayload, type ListResult, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, type MiddlewareConfig, type MutationOperation, NotFoundError, type OwnershipCheck, type PaginationResult, type PermissionCheck, type PermissionContext, type PermissionResult, type PresetFunction, type PresetResult, type QueryParserInterface, RESERVED_QUERY_PARAMS, type RateLimitConfig, type RegistryEntry, type RegistryStats, type RequestContext, type RequestIdOptions, type RequestWithExtras, type ResourceConfig, ResourceDefinition, type ResourceMetadata, type RouteHandler, type RouteHandlerMethod, type RouteSchemaOptions, SYSTEM_FIELDS, type ServiceContext, type SlugExt, SlugMixin, type SoftDeleteExt, SoftDeleteMixin, type TreeExt, TreeMixin, type TypedController, type TypedRepository, type TypedResourceConfig, UnauthorizedError, type UserBase, type UserOrganization, type ValidateOptions, ValidationError, type ValidationResult, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, authenticated, createDomainError, createDynamicPermissionMatrix, createOrgPermissions, defineAggregation, defineResource, defineResourceVariants, denyAll, fields, fullPublic, getControllerScope, getUserId, ownerWithAdminBypass, presets_d_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAuth, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, version, when };
10
+ export { type AggMeasureInput, type AggMeasureShorthand, type AggregationCacheConfig, type AggregationConfig, type AggregationDateRangeRequirement, type AggregationIndexHint, type AggregationMaterializedContext, type AggregationMaterializedResult, type AggregationRateLimit, type AggregationsMap, type AnyRecord, type ApiResponse, type ArcCreateResult, type ArcDeleteResult, ArcError, type ArcGetResult, type ArcInternalMetadata, type ArcListResult, type ArcRequest, type ArcUpdateResult, type AuthPluginOptions, BaseController, type BaseControllerOptions, BaseCrudController, type BulkExt, BulkMixin, CRUD_OPERATIONS, type ConfigError, type ControllerConfigurableOptions, type ControllerConstructionOptions, type ControllerLike, type CrudController, type CrudOperation, type CrudRouteKey, type CrudRouterOptions, type CrudSchemas, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, type DynamicPermissionMatrix, type DynamicPermissionMatrixConfig, type EventDefinition, type FastifyRequestExtras, type FastifyWithAuth, type FastifyWithDecorators, type FieldPermission, type FieldPermissionMap, type FieldRule, ForbiddenError, type GracefulShutdownOptions, HOOK_OPERATIONS, HOOK_PHASES, type HealthCheck, type HealthOptions, type HookOperation, type HookPhase, type IController, type IControllerResponse, type IRequestContext, type InferAdapterDoc, type InferDocType, type InferResourceDoc, type IntrospectionData, type IntrospectionPluginOptions, type JWTPayload, type ListResult, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, type MiddlewareConfig, type MutationOperation, NotFoundError, type OwnershipCheck, type PaginationResult, type PermissionCheck, type PermissionContext, type PermissionResult, type PresetFunction, type PresetResult, type QueryParserInterface, RESERVED_QUERY_PARAMS, type RateLimitConfig, type RegistryEntry, type RegistryStats, type RequestContext, type RequestIdOptions, type RequestWithExtras, type ResourceConfig, ResourceDefinition, type ResourceMetadata, type RouteHandler, type RouteHandlerMethod, type RouteSchemaOptions, SYSTEM_FIELDS, type ServiceContext, type SlugExt, SlugMixin, type SoftDeleteExt, SoftDeleteMixin, type TreeExt, TreeMixin, type TypedController, type TypedRepository, type TypedResourceConfig, UnauthorizedError, type UserBase, type UserOrganization, type ValidateOptions, ValidationError, type ValidationResult, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, authenticated, createDomainError, createDynamicPermissionMatrix, createOrgPermissions, defineAction, defineAggregation, defineResource, defineResourceVariants, denyAll, fields, fullPublic, getControllerScope, ownerWithAdminBypass, presets_d_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAuth, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, version, when };