@classytic/arc 2.15.4 → 2.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/README.md +1 -0
  2. package/bin/arc.js +12 -0
  3. package/dist/{BaseController-dx3m2J8V.mjs → BaseController-DlCCTIxJ.mjs} +61 -19
  4. package/dist/{HookSystem-Iiebom92.mjs → HookSystem-Cmf7-Etp.mjs} +8 -4
  5. package/dist/{QueryCache-D41bfdBB.d.mts → QueryCache-SvmT_9ti.d.mts} +1 -1
  6. package/dist/{ResourceRegistry-CTERg_2x.mjs → ResourceRegistry-f48hFk3m.mjs} +52 -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-BZX6zzDM.mjs +300 -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-TeHE8G-v.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-DBJ_j6rX.mjs} +222 -44
  32. package/dist/createActionRouter-DUpN3Dd1.mjs +288 -0
  33. package/dist/{createAggregationRouter-B0bPDf5b.mjs → createAggregationRouter-Dq-TUCuY.mjs} +3 -2
  34. package/dist/{createApp-PFegs47-.mjs → createApp-DNccuhyI.mjs} +16 -14
  35. package/dist/{defineEvent-D5h7EvAx.mjs → defineEvent-DRwY0fYm.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-DpoXQHZ9.mjs} +17 -14
  39. package/dist/errors-C1lX_jlm.d.mts +91 -0
  40. package/dist/{eventPlugin-CaKTYkYM.mjs → eventPlugin-C2cGqtRO.mjs} +1 -1
  41. package/dist/{eventPlugin-qXpqTebY.d.mts → eventPlugin-CtHC_av1.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 +1 -1
  47. package/dist/factory/index.mjs +2 -2
  48. package/dist/{fields-COhcH3fk.d.mts → fields-Anj0xdih.d.mts} +1 -1
  49. package/dist/generate-BWFwgcCM.d.mts +38 -0
  50. package/dist/generate-CYac-OLv.mjs +654 -0
  51. package/dist/hooks/index.d.mts +1 -1
  52. package/dist/hooks/index.mjs +1 -1
  53. package/dist/idempotency/index.d.mts +2 -2
  54. package/dist/idempotency/index.mjs +1 -1
  55. package/dist/idempotency/redis.d.mts +1 -1
  56. package/dist/{index-BTqLEvhu.d.mts → index-3oIimXQn.d.mts} +12 -12
  57. package/dist/{index-BstGxcc3.d.mts → index-B-ulKx5P.d.mts} +55 -4
  58. package/dist/{index-BswOSJCE.d.mts → index-CkW0flkU.d.mts} +355 -16
  59. package/dist/index.d.mts +6 -6
  60. package/dist/index.mjs +7 -8
  61. package/dist/init-Dv71MsJr.d.mts +71 -0
  62. package/dist/init-HDvoO9L5.mjs +3098 -0
  63. package/dist/integrations/event-gateway.d.mts +2 -2
  64. package/dist/integrations/event-gateway.mjs +1 -1
  65. package/dist/integrations/index.d.mts +2 -2
  66. package/dist/integrations/jobs.mjs +3 -3
  67. package/dist/integrations/mcp/index.d.mts +239 -7
  68. package/dist/integrations/mcp/index.mjs +2 -528
  69. package/dist/integrations/mcp/testing.d.mts +2 -2
  70. package/dist/integrations/mcp/testing.mjs +6 -10
  71. package/dist/integrations/streamline.mjs +26 -1
  72. package/dist/integrations/websocket-redis.d.mts +1 -1
  73. package/dist/integrations/websocket.d.mts +1 -1
  74. package/dist/integrations/websocket.mjs +1 -0
  75. package/dist/loadResourcesFromEntry-BLMEI2Xa.mjs +51 -0
  76. package/dist/{resourceToTools-tFYUNmM0.mjs → mcpPlugin-7vGV51ED.mjs} +1021 -318
  77. package/dist/{memory-UBydS5ku.mjs → memory-QOLe11D5.mjs} +2 -0
  78. package/dist/middleware/index.d.mts +1 -1
  79. package/dist/middleware/index.mjs +1 -1
  80. package/dist/{openapi-BHXhoX8O.mjs → openapi-34T9yNwd.mjs} +47 -36
  81. package/dist/permissions/index.d.mts +2 -2
  82. package/dist/permissions/index.mjs +1 -1
  83. package/dist/{permissions-ohQyv50e.mjs → permissions-CTxMrreC.mjs} +2 -2
  84. package/dist/{pipe-Zr0KXjQe.mjs → pipe-DiCyvyPN.mjs} +1 -0
  85. package/dist/pipeline/index.d.mts +1 -1
  86. package/dist/pipeline/index.mjs +1 -1
  87. package/dist/plugins/index.d.mts +5 -5
  88. package/dist/plugins/index.mjs +10 -10
  89. package/dist/plugins/response-cache.mjs +5 -5
  90. package/dist/plugins/tracing-entry.d.mts +1 -1
  91. package/dist/plugins/tracing-entry.mjs +1 -1
  92. package/dist/{pluralize-DQgqgifU.mjs → pluralize-B9M8xvy-.mjs} +2 -1
  93. package/dist/presets/filesUpload.d.mts +4 -4
  94. package/dist/presets/filesUpload.mjs +2 -2
  95. package/dist/presets/index.d.mts +1 -1
  96. package/dist/presets/index.mjs +1 -1
  97. package/dist/presets/multiTenant.d.mts +1 -1
  98. package/dist/presets/multiTenant.mjs +4 -3
  99. package/dist/presets/search.d.mts +2 -2
  100. package/dist/presets/search.mjs +1 -1
  101. package/dist/{presets-BbkjdPeH.mjs → presets-C9BE6WaZ.mjs} +2 -2
  102. package/dist/{queryCachePlugin-m1XsgAIJ.mjs → queryCachePlugin-B4XMSSe7.mjs} +2 -2
  103. package/dist/{queryCachePlugin-CqMdLI2-.d.mts → queryCachePlugin-Biqzfbi5.d.mts} +2 -2
  104. package/dist/{redis-DiMkdHEl.d.mts → redis-Cyzrz6SX.d.mts} +1 -1
  105. package/dist/{redis-stream-D6HzR1Z_.d.mts → redis-stream-DT-YjzrB.d.mts} +1 -1
  106. package/dist/registry/index.d.mts +319 -2
  107. package/dist/registry/index.mjs +3 -3
  108. package/dist/registry-BBE23CDj.mjs +576 -0
  109. package/dist/{routerShared-DrOa-26E.mjs → routerShared-CZV5aabX.mjs} +3 -3
  110. package/dist/scope/index.d.mts +3 -3
  111. package/dist/scope/index.mjs +3 -3
  112. package/dist/{sse-Bz-5ZeTt.mjs → sse-BY6sTy4P.mjs} +1 -1
  113. package/dist/testing/index.d.mts +2 -2
  114. package/dist/testing/index.mjs +16 -7
  115. package/dist/testing/storageContract.d.mts +1 -1
  116. package/dist/types/index.d.mts +5 -5
  117. package/dist/types/storage.d.mts +1 -1
  118. package/dist/{types-C_s5moIu.mjs → types-Bi0r0vjG.mjs} +53 -1
  119. package/dist/{types-BQsjgQzS.d.mts → types-BsJMEQ4D.d.mts} +106 -12
  120. package/dist/{types-DrBaUwyV.d.mts → types-D-fYtKjb.d.mts} +33 -10
  121. package/dist/{types-CTYvcwHe.d.mts → types-DVfpSfx2.d.mts} +42 -1
  122. package/dist/utils/index.d.mts +1286 -2
  123. package/dist/utils/index.mjs +1 -1
  124. package/dist/{utils-_h9B3c57.mjs → utils-DC5ycPfr.mjs} +89 -40
  125. package/dist/{buildHandler-CcFOpJLh.mjs → validate-By96rH0r.mjs} +8 -299
  126. package/dist/{versioning-hmkPcDlX.d.mts → versioning-ZwX9tmbS.d.mts} +1 -1
  127. package/package.json +21 -28
  128. package/skills/arc/SKILL.md +300 -706
  129. package/skills/arc/references/auth.md +19 -7
  130. package/skills/arc-code-review/SKILL.md +1 -1
  131. package/skills/arc-code-review/references/arc-cheatsheet.md +100 -322
  132. package/dist/createActionRouter-S3MLVYot.mjs +0 -220
  133. package/dist/index-bRjYu21O.d.mts +0 -1320
  134. package/dist/org/index.d.mts +0 -66
  135. package/dist/org/index.mjs +0 -486
  136. package/dist/org/types.d.mts +0 -82
  137. package/dist/org/types.mjs +0 -1
  138. package/dist/registry-I-ogLgL9.mjs +0 -46
  139. /package/dist/{EventTransport-CT_52aWU.d.mts → EventTransport-C-2oAHtw.d.mts} +0 -0
  140. /package/dist/{EventTransport-DLWoUMHy.mjs → EventTransport-Hxvv5QQz.mjs} +0 -0
  141. /package/dist/{actionPermissions-CyUkQu6O.mjs → actionPermissions-Bjmvn7Eb.mjs} +0 -0
  142. /package/dist/{elevation-BXOWoGCF.d.mts → elevation-0YBpa663.d.mts} +0 -0
  143. /package/dist/{elevation-DgoeTyfX.mjs → elevation-Dci0AYLT.mjs} +0 -0
  144. /package/dist/{errorHandler-DFr45ZG4.d.mts → errorHandler-mHuyWzZE.d.mts} +0 -0
  145. /package/dist/{externalPaths-BD5nw6St.d.mts → externalPaths-DFg-2KTp.d.mts} +0 -0
  146. /package/dist/{interface-beEtJyWM.d.mts → interface-CH0OQudo.d.mts} +0 -0
  147. /package/dist/{interface-DfLGcus7.d.mts → interface-NwJ_qPlY.d.mts} +0 -0
  148. /package/dist/{keys-CGcCbNyu.mjs → keys-DopsCuyQ.mjs} +0 -0
  149. /package/dist/{loadResources-DBMQg_Aj.mjs → loadResources-ChQEj8ih.mjs} +0 -0
  150. /package/dist/{metrics-Qnvwc-LQ.mjs → metrics-TuOmguhi.mjs} +0 -0
  151. /package/dist/{replyHelpers-CK-FNO8E.mjs → replyHelpers-C-gD32oF.mjs} +0 -0
  152. /package/dist/{schemaIR-lYhC2gE5.mjs → schemaIR-Ctc89DSn.mjs} +0 -0
  153. /package/dist/{sessionManager-C4Le_UB3.d.mts → sessionManager-BqFegc0W.d.mts} +0 -0
  154. /package/dist/{storage-Dfzt4VTl.d.mts → storage-D2KZJAmn.d.mts} +0 -0
  155. /package/dist/{store-helpers-BkIN9-vu.mjs → store-helpers-B0sunfZZ.mjs} +0 -0
  156. /package/dist/{tracing-QJVprktp.d.mts → tracing-Dm8n7Cnn.d.mts} +0 -0
  157. /package/dist/{versioning-BUrT5aP4.mjs → versioning-B6mimogM.mjs} +0 -0
  158. /package/dist/{websocket-ChC2rqe1.d.mts → websocket-BkjeGZRn.d.mts} +0 -0
@@ -1,8 +1,325 @@
1
- import { R as RegisterOptions, k as IntrospectionPluginOptions, z as ResourceRegistry } from "../index-BswOSJCE.mjs";
1
+ import { J as CrudRouteKey, R as RegisterOptions, V as ResourceDefinition, at as ResolvedTenantPurge, k as IntrospectionPluginOptions, p as RegistryEntry, z as ResourceRegistry } from "../index-CkW0flkU.mjs";
2
2
  import { FastifyPluginAsync } from "fastify";
3
+ import { TenantPurgeProgress, TenantPurgeStrategy } from "@classytic/repo-core/repository";
3
4
 
5
+ //#region src/registry/assertNoTenantData.d.ts
6
+ interface AssertNoTenantDataOptions {
7
+ readonly organizationId: string;
8
+ /**
9
+ * Limit the check to a subset of resources. Default: every cascading
10
+ * resource (matches the cascade runner's filter).
11
+ */
12
+ readonly only?: readonly string[];
13
+ /**
14
+ * Skip resources whose strategy is `anonymize` (the rows legitimately
15
+ * remain). Default `true` — the smoke test focuses on "did data leave?"
16
+ * not "did anonymize keep rows?". Set `false` for a full pass.
17
+ */
18
+ readonly skipAnonymize?: boolean;
19
+ }
20
+ interface TenantDataLeak {
21
+ readonly resource: string;
22
+ readonly tenantField: string;
23
+ readonly strategy: TenantPurgeStrategy["type"];
24
+ readonly expected: number;
25
+ readonly actual: number;
26
+ readonly reason?: string;
27
+ }
28
+ interface AssertNoTenantDataReport {
29
+ readonly ok: boolean;
30
+ readonly organizationId: string;
31
+ readonly checked: number;
32
+ readonly skipped: readonly {
33
+ resource: string;
34
+ reason: string;
35
+ }[];
36
+ readonly leaks: readonly TenantDataLeak[];
37
+ }
38
+ /**
39
+ * Walk every cascading resource, run a tenant-scoped count, compare
40
+ * against the strategy's expected outcome.
41
+ *
42
+ * Designed for use inside compliance tests:
43
+ *
44
+ * ```ts
45
+ * import { assertNoTenantData } from '@classytic/arc/registry';
46
+ *
47
+ * it('after org delete, no tenant data leaks', async () => {
48
+ * await cascadeDeleteForOrganization(arc.registry, { organizationId: 'test-org' });
49
+ * const report = await assertNoTenantData(arc.registry, { organizationId: 'test-org' });
50
+ * expect(report.ok).toBe(true);
51
+ * expect(report.leaks).toHaveLength(0);
52
+ * });
53
+ * ```
54
+ */
55
+ declare function assertNoTenantData(registry: ResourceRegistry, options: AssertNoTenantDataOptions): Promise<AssertNoTenantDataReport>;
56
+ //#endregion
57
+ //#region src/registry/purgeResource.d.ts
58
+ /**
59
+ * Outcome for one resource. Wider than `TenantPurgeResult` because it
60
+ * carries the resource name + tenantField for the aggregate report,
61
+ * and a `path` discriminator so audit consumers can tell which code
62
+ * path ran.
63
+ */
64
+ interface PurgeResourceOutcome {
65
+ readonly resource: string;
66
+ readonly tenantField: string;
67
+ readonly strategy: TenantPurgeStrategy["type"];
68
+ readonly processed: number;
69
+ readonly ok: boolean;
70
+ readonly path: "purgeByField" | "legacy-deleteMany" | "skipped" | "unsupported";
71
+ readonly skipReason?: string;
72
+ readonly error?: {
73
+ code?: string;
74
+ message: string;
75
+ };
76
+ readonly durationMs?: number;
77
+ }
78
+ //#endregion
79
+ //#region src/registry/cascadeOrgDelete.d.ts
80
+ /**
81
+ * Per-resource result row. One entry for every resource Arc attempted to
82
+ * cascade-delete for the given org. `deletedCount: -1` means the adapter
83
+ * doesn't surface a row count (the delete still ran).
84
+ */
85
+ interface CascadeResourceReport {
86
+ readonly resource: string;
87
+ readonly tenantField: string;
88
+ /**
89
+ * Rows processed. For `hard` strategy this equals rows that no longer
90
+ * exist; for `soft`/`anonymize` it's rows touched (still present).
91
+ * `-1` only on legacy `deleteMany` adapters that don't surface a count.
92
+ */
93
+ readonly deletedCount: number;
94
+ /**
95
+ * Strategy that actually ran for this resource — `'hard'` / `'soft'` /
96
+ * `'anonymize'` / `'skip'`. Audit consumers branch on this to answer
97
+ * "did data physically leave the system?".
98
+ */
99
+ readonly strategy?: TenantPurgeStrategy["type"];
100
+ /**
101
+ * Where the strategy came from — `'declared'` (host wrote
102
+ * `onTenantDelete`) or `'disabled'` (filtered out before reaching
103
+ * this report). Future sources may be added; treat the field as a
104
+ * read-only audit signal.
105
+ */
106
+ readonly strategySource?: ResolvedTenantPurge["source"];
107
+ /**
108
+ * Code path that executed — `'purgeByField'` (preferred, chunked),
109
+ * `'legacy-deleteMany'` (single-shot fallback for old adapters),
110
+ * `'skipped'` (skip strategy), `'unsupported'` (adapter can't run
111
+ * the declared strategy — surfaces in `failures`).
112
+ */
113
+ readonly path?: PurgeResourceOutcome["path"];
114
+ /** Echoed for `skip` strategy — the declared reason. */
115
+ readonly skipReason?: string;
116
+ readonly error?: {
117
+ code?: string;
118
+ message: string;
119
+ };
120
+ }
121
+ /** Aggregate report — splits successful and failed resources for the caller. */
122
+ interface CascadeReport {
123
+ readonly organizationId: string;
124
+ readonly resources: readonly CascadeResourceReport[];
125
+ readonly successes: readonly CascadeResourceReport[];
126
+ readonly failures: readonly CascadeResourceReport[];
127
+ readonly totalDeleted: number;
128
+ readonly durationMs: number;
129
+ }
130
+ /** Lightweight logger shape — `fastify.log`, `pino`, or `console` all fit. */
131
+ interface CascadeLogger {
132
+ info?: (obj: unknown, msg?: string) => void;
133
+ warn?: (obj: unknown, msg?: string) => void;
134
+ error?: (obj: unknown, msg?: string) => void;
135
+ }
136
+ interface CascadeOptions {
137
+ /** Organization id whose tenant-scoped rows should be deleted. */
138
+ readonly organizationId: string;
139
+ /**
140
+ * Skip these resources even if they declare `onTenantDelete`.
141
+ * Useful for stage-gated rollouts ("cascade everything except `audit_log`
142
+ * — we want to keep the trail").
143
+ */
144
+ readonly skip?: readonly string[];
145
+ /**
146
+ * Resource names to LIMIT cascade to. When set, only these resources
147
+ * cascade — useful for partial-cleanup scripts and the test path that
148
+ * verifies one resource at a time.
149
+ */
150
+ readonly only?: readonly string[];
151
+ /** Optional logger — info on each resource, warn/error on failures. */
152
+ readonly logger?: CascadeLogger;
153
+ /**
154
+ * Forwarded to each resource's `purgeByField` — emits per-chunk
155
+ * progress. The event includes the resource name so a single
156
+ * progress handler can drive a multi-resource progress UI.
157
+ */
158
+ readonly onProgress?: (event: TenantPurgeProgress & {
159
+ resource: string;
160
+ }) => void | Promise<void>;
161
+ /**
162
+ * Forwarded to each resource's `purgeByField`. The runner checks
163
+ * between resources too — aborting mid-cascade stops the next
164
+ * resource from starting, in addition to stopping the currently-
165
+ * running purge between chunks.
166
+ */
167
+ readonly signal?: AbortSignal;
168
+ /**
169
+ * Global override for per-resource batchSize. Per-resource declarations
170
+ * (`onTenantDelete.batchSize`) win when set; this is the fallback.
171
+ */
172
+ readonly batchSize?: number;
173
+ /**
174
+ * Run up to `concurrency` resources in parallel. **Priority groups
175
+ * remain barriers** — all priority-10 resources finish before any
176
+ * priority-50 resource starts. Within a priority, resources run
177
+ * concurrently up to this cap. Default `1` (sequential, safest).
178
+ *
179
+ * Resources are independent (different collections / tables, no
180
+ * cross-resource constraints), so parallelism is safe — but oplog
181
+ * pressure / connection-pool exhaustion / replication lag scale with
182
+ * concurrency. Tune per environment; `4` is usually fine for cloud
183
+ * Mongo + small connection pools, `8`–`16` for high-throughput tiers.
184
+ */
185
+ readonly concurrency?: number;
186
+ /**
187
+ * Cascade-level checkpoint — survive a crash mid-cascade and resume
188
+ * from the last completed resource. `read()` returns the last cascade
189
+ * state (or `undefined` for a fresh run); `write()` persists state
190
+ * after each resource completes. Hosts plumb to Redis / a status
191
+ * table / a dedicated checkpoint store.
192
+ *
193
+ * Per-purge checkpointing is intentionally NOT offered — the chunked
194
+ * primitive is already idempotent (re-running a partially-completed
195
+ * cascade is safe because already-deleted rows don't match the next
196
+ * SELECT). The cascade-level checkpoint just skips entire resources
197
+ * known-completed in the prior pass — wasteful round-trips, not
198
+ * wasteful writes.
199
+ */
200
+ readonly checkpoint?: CascadeCheckpoint;
201
+ }
202
+ /** Cascade resume state. Persist between runs; rehydrate on retry. */
203
+ interface CascadeCheckpointState {
204
+ /** Names of resources fully completed in a prior pass. Skipped on resume. */
205
+ readonly completedResources: readonly string[];
206
+ }
207
+ interface CascadeCheckpoint {
208
+ /** Load the prior cascade state for this org. Return `undefined` for a fresh run. */
209
+ read(): Promise<CascadeCheckpointState | undefined>;
210
+ /** Persist updated state after a resource finishes. */
211
+ write(state: CascadeCheckpointState): Promise<void>;
212
+ }
213
+ /**
214
+ * Names of resources flagged for cascade — used by audit scripts.
215
+ * A resource is cascading when its resolved strategy isn't `disabled`
216
+ * (i.e. the host declared `onTenantDelete`).
217
+ */
218
+ declare function getCascadingResources(registry: ResourceRegistry): readonly string[];
219
+ /**
220
+ * Rich introspection — returns the resolved strategy + source per
221
+ * cascading resource. Use for audit dashboards that answer "what
222
+ * happens to this resource on org-delete?" without grepping the
223
+ * source.
224
+ */
225
+ declare function getCascadingResourcesWithMetadata(registry: ResourceRegistry): readonly {
226
+ name: string;
227
+ tenantField: string;
228
+ strategy: TenantPurgeStrategy["type"];
229
+ source: ResolvedTenantPurge["source"];
230
+ priority: number;
231
+ }[];
232
+ /**
233
+ * Cascade-cleanup every tenant-scoped resource for the given organization.
234
+ * Walks the registry in **ascending priority order** (`onTenantDelete.priority`
235
+ * — leaf data first, references last), runs each resource's resolved
236
+ * strategy via `purgeByField` when available (chunked, progress, abort),
237
+ * and returns a structured report.
238
+ *
239
+ * **Strategy resolution** lives in `resolveTenantPurge.ts` — this runner
240
+ * just reads `resource.resolvedTenantPurge` (computed once at boot).
241
+ *
242
+ * **Per-resource execution** lives in `purgeResource.ts` — preferred
243
+ * path is the kit's `purgeByField` (chunked + plugin-composed); falls
244
+ * back to legacy `deleteMany` only for `hard` strategy on adapters that
245
+ * haven't been upgraded.
246
+ *
247
+ * **Failure semantics**: continues on per-resource error, returns the
248
+ * full report. Hosts decide whether a partial cascade is a hard
249
+ * failure (re-throw) or degraded mode (log + alert).
250
+ *
251
+ * @param registry The arc resource registry (`fastify.arc.registry`).
252
+ * @param options Org id + filters + logger + progress + signal.
253
+ */
254
+ declare function cascadeDeleteForOrganization(registry: ResourceRegistry, options: CascadeOptions): Promise<CascadeReport>;
255
+ //#endregion
4
256
  //#region src/registry/introspectionPlugin.d.ts
5
257
  declare const introspectionPlugin: FastifyPluginAsync<IntrospectionPluginOptions>;
6
258
  declare const _default: FastifyPluginAsync<IntrospectionPluginOptions>;
7
259
  //#endregion
8
- export { type IntrospectionPluginOptions, type RegisterOptions, ResourceRegistry, _default as introspectionPlugin, introspectionPlugin as introspectionPluginFn };
260
+ //#region src/registry/manifest.d.ts
261
+ /** Mount-point string the FE uses to derive the URL for an action call. */
262
+ type ActionMount = "/:id/action" | "/action";
263
+ /**
264
+ * One action entry in a resource manifest. `requiresId` is the boolean
265
+ * the FE checks to decide whether its helper takes `(id, body)` or just
266
+ * `(body)`; `mount` is the URL suffix to append to the resource prefix.
267
+ */
268
+ interface ActionManifestEntry {
269
+ readonly name: string;
270
+ readonly mount: ActionMount;
271
+ readonly requiresId: boolean;
272
+ readonly description?: string;
273
+ }
274
+ /** Aggregation entry — one per `defineAggregation()` declaration. */
275
+ interface AggregationManifestEntry {
276
+ readonly name: string;
277
+ readonly path: string;
278
+ readonly summary?: string;
279
+ readonly description?: string;
280
+ }
281
+ /** Custom (non-CRUD, non-action) route entry. */
282
+ interface CustomRouteManifestEntry {
283
+ readonly method: string;
284
+ readonly path: string;
285
+ readonly operation?: string;
286
+ readonly summary?: string;
287
+ }
288
+ /**
289
+ * Single resource manifest. Everything an FE codegen needs to wire a
290
+ * typed client over the resource's HTTP surface.
291
+ */
292
+ interface ResourceManifest {
293
+ readonly name: string;
294
+ readonly displayName: string;
295
+ readonly prefix: string;
296
+ readonly idField: string;
297
+ /** Update method used for `/:id` PATCH / PUT routes. */
298
+ readonly updateMethod: "PUT" | "PATCH" | "both";
299
+ /** Enabled CRUD operations — filtered by `disabledRoutes` and `disableDefaultRoutes`. */
300
+ readonly crudOps: readonly CrudRouteKey[];
301
+ readonly actions: readonly ActionManifestEntry[];
302
+ readonly aggregations: readonly AggregationManifestEntry[];
303
+ readonly customRoutes: readonly CustomRouteManifestEntry[];
304
+ /** Tenant scoping field (when set) — surfaces for FE callers that need to send `x-organization-id`. */
305
+ readonly tenantField?: string | false;
306
+ }
307
+ /**
308
+ * Build a manifest from a `ResourceDefinition` (the value returned by
309
+ * `defineResource(...)`). Use at build time when you have direct access
310
+ * to the resource module — typically the simplest codegen path.
311
+ */
312
+ declare function buildResourceManifest(resource: ResourceDefinition): ResourceManifest;
313
+ /**
314
+ * Build a manifest from a `RegistryEntry` — use when the resource is
315
+ * already registered (introspection endpoint, runtime audit script).
316
+ *
317
+ * Equivalent to {@link buildResourceManifest} but reads from the projected
318
+ * registry shape, so a host that doesn't have the original `defineResource`
319
+ * value in scope (e.g. an FE-gen sidecar that scrapes a running server's
320
+ * `/_resources` endpoint) gets the same output without dragging the resource
321
+ * module into the codegen path.
322
+ */
323
+ declare function buildResourceManifestFromRegistry(entry: RegistryEntry): ResourceManifest;
324
+ //#endregion
325
+ export { type ActionManifestEntry, type ActionMount, type AggregationManifestEntry, type AssertNoTenantDataOptions, type AssertNoTenantDataReport, type CascadeCheckpoint, type CascadeCheckpointState, type CascadeOptions, type CascadeReport, type CascadeResourceReport, type CustomRouteManifestEntry, type IntrospectionPluginOptions, type RegisterOptions, type ResourceManifest, ResourceRegistry, type TenantDataLeak, assertNoTenantData, buildResourceManifest, buildResourceManifestFromRegistry, cascadeDeleteForOrganization, getCascadingResources, getCascadingResourcesWithMetadata, _default as introspectionPlugin, introspectionPlugin as introspectionPluginFn };
@@ -1,3 +1,3 @@
1
- import { n as introspectionPlugin_default, t as introspectionPlugin } from "../registry-I-ogLgL9.mjs";
2
- import { t as ResourceRegistry } from "../ResourceRegistry-CTERg_2x.mjs";
3
- export { ResourceRegistry, introspectionPlugin_default as introspectionPlugin, introspectionPlugin as introspectionPluginFn };
1
+ import { a as cascadeDeleteForOrganization, c as assertNoTenantData, i as introspectionPlugin_default, n as buildResourceManifestFromRegistry, o as getCascadingResources, r as introspectionPlugin, s as getCascadingResourcesWithMetadata, t as buildResourceManifest } from "../registry-BBE23CDj.mjs";
2
+ import { t as ResourceRegistry } from "../ResourceRegistry-f48hFk3m.mjs";
3
+ export { ResourceRegistry, assertNoTenantData, buildResourceManifest, buildResourceManifestFromRegistry, cascadeDeleteForOrganization, getCascadingResources, getCascadingResourcesWithMetadata, introspectionPlugin_default as introspectionPlugin, introspectionPlugin as introspectionPluginFn };