@classytic/arc 2.32.0 → 2.34.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.
- package/README.md +1 -1
- package/bin/arc.js +58 -17
- package/dist/{BaseController-Dk34dxhI.mjs → BaseController-CbkuhNI2.mjs} +329 -35
- package/dist/{EventTransport-2uVV34WU.d.mts → EventTransport-BEVP50ka.d.mts} +16 -0
- package/dist/{EventTransport-BV10D0oG.mjs → EventTransport-tq4CEB-q.mjs} +39 -2
- package/dist/{HookSystem-vimw5D7Z.mjs → HookSystem-DqXkMXkB.mjs} +2 -2
- package/dist/{ResourceRegistry-BVr7PgA0.mjs → ResourceRegistry-DoALUlOO.mjs} +3 -2
- package/dist/{actionPermissions-Dti7ebyv.mjs → actionPermissions-CUeCmpUd.mjs} +1 -1
- package/dist/audit/index.d.mts +2 -2
- package/dist/audit/index.mjs +2 -2
- package/dist/auth/audit.mjs +1 -1
- package/dist/auth/index.d.mts +2 -2
- package/dist/auth/index.mjs +39 -7
- package/dist/auth/redis-session.mjs +1 -1
- package/dist/{authorizationDecision-__T3EJDA.mjs → authorizationDecision-CMMLWmuZ.mjs} +6 -2
- package/dist/{types-B7XeLEgK.d.mts → base-Csjc2oF-.d.mts} +74 -74
- package/dist/{buildHandler-Dn7rzUJo.mjs → buildHandler-BrdYrG_1.mjs} +4 -4
- package/dist/cache/index.mjs +4 -4
- package/dist/{caching-DFJqHyFs.mjs → caching-BcGmvnHh.mjs} +2 -2
- package/dist/cleanup/index.d.mts +17 -5
- package/dist/cleanup/index.mjs +240 -7
- package/dist/cli/commands/describe.d.mts +1 -1
- package/dist/cli/commands/describe.mjs +3 -3
- package/dist/cli/commands/docs.mjs +3 -3
- package/dist/cli/commands/doctor.mjs +1 -1
- package/dist/cli/commands/generate.mjs +2 -2
- package/dist/cli/commands/init.mjs +2 -2
- package/dist/cli/commands/introspect.mjs +2 -2
- package/dist/cli/index.mjs +3 -3
- package/dist/{constants-J99LGTJI.mjs → constants-BxCoxmiN.mjs} +1 -1
- package/dist/context/index.mjs +3 -3
- package/dist/core/index.d.mts +3 -3
- package/dist/core/index.mjs +9 -8
- package/dist/{core-BwwmNSp7.mjs → core-BYKa8wHu.mjs} +3 -3
- package/dist/{createActionRouter-DkJZWo0m.mjs → createActionRouter-D6T0jWhS.mjs} +8 -8
- package/dist/{createAggregationRouter-B1exOVD8.mjs → createAggregationRouter-QLV2PrWP.mjs} +7 -7
- package/dist/{createApp-Bv0m-Q6_.mjs → createApp-zR-DEesr.mjs} +128 -24
- package/dist/{defineAggregation-gX4No1gt.mjs → defineAggregation-Nv-DwfOf.mjs} +1 -1
- package/dist/{defineResource-XFPPUu2c.mjs → defineResource-ZhuLonLm.mjs} +297 -23
- package/dist/discovery/index.mjs +1 -1
- package/dist/docs/index.d.mts +1 -1
- package/dist/docs/index.mjs +3 -3
- package/dist/{elevation-DNXXxgjl.mjs → elevation-B0tlY8y1.mjs} +4 -4
- package/dist/encryption/index.mjs +3 -3
- package/dist/{errorHandler-B2AZUJUj.mjs → errorHandler-C7xBqHsI.mjs} +42 -5
- package/dist/{errorHandler-CpYUJmPA.d.mts → errorHandler-DI5AN2b5.d.mts} +14 -3
- package/dist/{errors-Bh1KK5ps.mjs → errors-Cd_yy7aW.mjs} +1 -1
- package/dist/{eventPlugin-GF5nnBIq.d.mts → eventPlugin-DSNEZWfV.d.mts} +29 -1
- package/dist/{eventPlugin-Dk_TyXeE.mjs → eventPlugin-Dar8qRaj.mjs} +65 -9
- package/dist/events/index.d.mts +5 -351
- package/dist/events/index.mjs +5 -780
- package/dist/events/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis-stream-entry.mjs +1 -1
- package/dist/events/transports/redis.d.mts +1 -1
- package/dist/events/transports/redis.mjs +1 -1
- package/dist/factory/index.d.mts +20 -5
- package/dist/factory/index.mjs +7 -7
- package/dist/{fastify-augmentation-BppG5bMT.d.mts → fastify-augmentation-DVsTAy6X.d.mts} +3 -3
- package/dist/{fields-DEi65pGj.mjs → fields-CojeUkS4.mjs} +1 -1
- package/dist/{generate-CRSG0jTv.mjs → generate-DiB0nHPR.mjs} +2 -2
- package/dist/{headers-BXjQYbeC.mjs → headers-CveNO9gR.mjs} +2 -2
- package/dist/{health-5XnTa2uo.mjs → health-CasG2A28.mjs} +1 -1
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.mjs +2 -2
- package/dist/idempotency/index.d.mts +45 -1
- package/dist/idempotency/index.mjs +90 -9
- package/dist/idempotency/redis.mjs +1 -1
- package/dist/{index-zq6VrjaB.d.mts → index-B-DvUzsr.d.mts} +12 -2
- package/dist/{index-CpzxqePp.d.mts → index-BcR2bFZQ.d.mts} +707 -373
- package/dist/{index-ZWhLTp_s.d.mts → index-C5NnMEKF.d.mts} +1 -1
- package/dist/{index-DXlHwvuE.d.mts → index-CFAJEWCX.d.mts} +18 -5
- package/dist/{index-C-481Zf2.d.mts → index-ugr1tQlW.d.mts} +17 -1
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +13 -12
- package/dist/{init-BbfP8aky.mjs → init-mdJ-v4Xp.mjs} +18 -12
- package/dist/integrations/event-gateway.d.mts +1 -1
- package/dist/integrations/event-gateway.mjs +2 -2
- package/dist/integrations/index.d.mts +2 -2
- package/dist/integrations/index.mjs +1 -1
- package/dist/integrations/jobs/index.d.mts +1 -1
- package/dist/integrations/jobs/index.mjs +99 -97
- package/dist/integrations/mcp/index.d.mts +12 -3
- package/dist/integrations/mcp/index.mjs +2 -2
- package/dist/integrations/mcp/testing.d.mts +1 -1
- package/dist/integrations/mcp/testing.mjs +2 -2
- package/dist/integrations/streamline.mjs +3 -3
- package/dist/integrations/webhooks.d.mts +124 -1
- package/dist/integrations/webhooks.mjs +180 -2
- package/dist/integrations/websocket-pushref-redis.mjs +1 -1
- package/dist/integrations/websocket-redis.mjs +1 -1
- package/dist/integrations/websocket.mjs +1 -1
- package/dist/{interface-BP4IJCBO.mjs → interface-DznJrm9R.mjs} +1 -1
- package/dist/{jsonBody-DDSR2HFl.mjs → jsonBody-CfGH-GxO.mjs} +2 -2
- package/dist/{keys-B-HBTGXl.mjs → keys-WeKvY1dE.mjs} +1 -1
- package/dist/{loadResources-DisEAmkm.mjs → loadResources-Bj-aSsXi.mjs} +2 -2
- package/dist/{loadResourcesFromEntry-D1MJp13f.mjs → loadResourcesFromEntry-DwaxNcE2.mjs} +2 -2
- package/dist/logger/index.mjs +1 -1
- package/dist/{mcpPlugin-CpfVpKHE.mjs → mcpPlugin-DX3PHD7K.mjs} +60 -21
- package/dist/{memory-DsuWnj4T.mjs → memory-qYSB7rMQ.mjs} +2 -2
- package/dist/{metrics-DdQL8syd.mjs → metrics-D7uchLjN.mjs} +2 -2
- package/dist/middleware/index.d.mts +1 -1
- package/dist/middleware/index.mjs +3 -3
- package/dist/migrations/index.mjs +2 -2
- package/dist/{module-Br81am6m.mjs → module-CwKsgZXp.mjs} +1 -1
- package/dist/{multipartBody-BnkBLN7v.mjs → multipartBody-4w-S3-PU.mjs} +1 -1
- package/dist/{openapi-DIRzvxC0.mjs → openapi-CkV5mQ53.mjs} +6 -6
- package/dist/outbox-admin/index.d.mts +2 -2
- package/dist/outbox-admin/index.mjs +4 -4
- package/dist/outbox-module-C1Bs_FXF.d.mts +382 -0
- package/dist/outbox-module-D1QfHqO4.mjs +846 -0
- package/dist/permissions/index.d.mts +2 -2
- package/dist/permissions/index.mjs +5 -5
- package/dist/{permissions-Dl_m0NCe.mjs → permissions-CP47jdi7.mjs} +25 -6
- package/dist/{pipe-ELHCP3zj.mjs → pipe-BzzoEhHj.mjs} +2 -2
- package/dist/pipeline/index.d.mts +1 -1
- package/dist/pipeline/index.mjs +2 -2
- package/dist/{pipeline-CPA-jx0M.mjs → pipeline-q69DZzgG.mjs} +6 -6
- package/dist/plugins/index.d.mts +6 -6
- package/dist/plugins/index.mjs +16 -16
- package/dist/plugins/response-cache.mjs +2 -2
- package/dist/plugins/tracing-entry.mjs +2 -2
- package/dist/{pluralize-C2ZkKbsn.mjs → pluralize-B7xf8qZF.mjs} +1 -1
- package/dist/{preloadResources-CDs87fTw.mjs → preloadResources-BkyqeTDz.mjs} +1 -1
- package/dist/{preloadResources-T1hmlTEZ.d.mts → preloadResources-g07ldtzh.d.mts} +30 -7
- package/dist/presets/filesUpload.d.mts +2 -2
- package/dist/presets/filesUpload.mjs +5 -5
- package/dist/presets/index.d.mts +2 -2
- package/dist/presets/index.mjs +2 -2
- package/dist/presets/multiTenant.d.mts +1 -1
- package/dist/presets/multiTenant.mjs +3 -3
- package/dist/presets/search.d.mts +2 -2
- package/dist/presets/search.mjs +2 -2
- package/dist/{presets-Dntd_pUO.mjs → presets-BAPijK_A.mjs} +4 -4
- package/dist/projection-BKM0Ui-s.mjs +42 -0
- package/dist/{queryCachePlugin-Dhps-Ldt.mjs → queryCachePlugin-DhsZ0ZIc.mjs} +49 -7
- package/dist/{rateLimit-C7mmAGs3.mjs → rateLimit-D4-ASwsI.mjs} +2 -2
- package/dist/{rateLimitKey-CccEFBfk.mjs → rateLimitKey-XngqVNEV.mjs} +1 -1
- package/dist/{realtime-DVvVZZFz.mjs → realtime-G1TC6Yzc.mjs} +9 -9
- package/dist/{redis-stream-qN6A-RFv.d.mts → redis-stream-mwLWlfHG.d.mts} +1 -1
- package/dist/{registerRoute-B_QrjYZS.mjs → registerRoute-Ba8v0PCa.mjs} +4 -4
- package/dist/registry/index.d.mts +3 -3
- package/dist/registry/index.mjs +3 -3
- package/dist/{registry-DqUmzA9W.mjs → registry-CLxCR5LF.mjs} +2 -2
- package/dist/{renewingLease-BpP9wwj7.mjs → renewingLease-BnWtbA2U.mjs} +1 -1
- package/dist/{replyHelpers-DS-P0b32.mjs → replyHelpers-BSBVCwL3.mjs} +2 -2
- package/dist/repositoryFilter-BANpz6BX.mjs +78 -0
- package/dist/{requestContext-B6vQF-sy.mjs → requestContext-uYE35JxI.mjs} +1 -1
- package/dist/{rolldown-runtime-BhflRrBs.mjs → rolldown-runtime-DNg-KNCk.mjs} +1 -1
- package/dist/runtimeCapabilities-Dm88DaTW.mjs +49 -0
- package/dist/{schedules-C2Q3uv2d.mjs → schedules-CAcZgia0.mjs} +3 -3
- package/dist/{schemaConverter-Crjvczi_.mjs → schemaConverter-XH1RZRyu.mjs} +1 -1
- package/dist/{schemaIR-CnyKK_1j.mjs → schemaIR-CDvclAew.mjs} +2 -2
- package/dist/schemas/index.mjs +1 -1
- package/dist/scim/index.mjs +2 -2
- package/dist/scope/index.mjs +5 -5
- package/dist/{scope-afz_Ieek.mjs → scope-BaWcqBvr.mjs} +4 -4
- package/dist/{simpleEqualityMatcher-C4KiMWUa.mjs → simpleEqualityMatcher-Se8VrsaP.mjs} +1 -1
- package/dist/{sse-B9P4Y-UI.mjs → sse-Cf0jUHsh.mjs} +5 -5
- package/dist/{sseStream-B3zb_d1h.mjs → sseStream-Bvpi-UXQ.mjs} +2 -2
- package/dist/{store-helpers-DmEMHlPQ.mjs → store-helpers-B88p99Z2.mjs} +1 -1
- package/dist/{streaming-DPZdQmDz.mjs → streaming-DsT1B5zJ.mjs} +1 -1
- package/dist/{subscribe-helpers-sp5xTDVA.mjs → subscribe-helpers-CLIOHsOK.mjs} +2 -2
- package/dist/sync/changelog.mjs +1 -1
- package/dist/testing/cleanupStoreContract.d.mts +1 -1
- package/dist/testing/cleanupStoreContract.mjs +3 -1
- package/dist/testing/index.d.mts +24 -12
- package/dist/testing/index.mjs +24 -12
- package/dist/testing/outboxStoreContract.mjs +1 -1
- package/dist/testing/storageContract.mjs +1 -1
- package/dist/{transactionContext-BvLKvOIL.mjs → transactionContext-BYtWnwAS.mjs} +1 -1
- package/dist/{typeGuards-B_5-hKjJ.mjs → typeGuards-jjKJDN13.mjs} +1 -1
- package/dist/types/index.d.mts +3 -3
- package/dist/types/index.mjs +1 -1
- package/dist/types/storage.mjs +1 -1
- package/dist/{types-CT5vu6M0.d.mts → types-BcTumAz_.d.mts} +41 -7
- package/dist/{types-CwcUQ610.d.mts → types-BfC83KsP.d.mts} +15 -1
- package/dist/{types-DXYX7dIR.mjs → types-CoqIRrkY.mjs} +4 -4
- package/dist/{types-C4QE8qnm.d.mts → types-DVLddu2q.d.mts} +144 -1
- package/dist/usage/index.d.mts +1 -1
- package/dist/usage/index.mjs +0 -0
- package/dist/{userHelpers-BNsOXzOd.mjs → userHelpers-CWF5pbZD.mjs} +1 -1
- package/dist/utils/index.d.mts +57 -5
- package/dist/utils/index.mjs +12 -11
- package/dist/{utils-BtOha_Sp.mjs → utils-h1V_sT-t.mjs} +38 -7
- package/dist/{validate-PMCPR9El.mjs → validate-CdQlz52F.mjs} +2 -2
- package/dist/{versioning-D_rhHfZm.d.mts → versioning-DEs-_hFi.d.mts} +1 -1
- package/dist/{versioning-CKv2jz_U.mjs → versioning-rZbyLVD-.mjs} +3 -3
- package/package.json +17 -16
- package/skills/arc/SKILL.md +96 -4
- package/skills/arc/references/api-reference.md +19 -0
- package/skills/arc/references/production.md +2 -2
- package/dist/projection-CjHhM5W1.mjs +0 -18
- package/dist/repositoryFilter-DotlxG3L.mjs +0 -45
package/dist/cleanup/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { g as getUserId } from "../types-
|
|
3
|
-
import { t as defineResource } from "../defineResource-
|
|
4
|
-
import { t as defineModule } from "../module-
|
|
1
|
+
/*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
|
|
2
|
+
import { g as getUserId } from "../types-CoqIRrkY.mjs";
|
|
3
|
+
import { t as defineResource } from "../defineResource-ZhuLonLm.mjs";
|
|
4
|
+
import { t as defineModule } from "../module-CwKsgZXp.mjs";
|
|
5
5
|
import { createPurgeEvidence } from "@classytic/primitives/retention";
|
|
6
6
|
import { canonicalJson, sha256Hex } from "@classytic/primitives/canonical";
|
|
7
7
|
//#region src/cleanup/errors.ts
|
|
@@ -85,6 +85,18 @@ const CleanupErrors = {
|
|
|
85
85
|
status
|
|
86
86
|
});
|
|
87
87
|
},
|
|
88
|
+
/**
|
|
89
|
+
* The operator's exclusion list cannot be honoured as written.
|
|
90
|
+
*
|
|
91
|
+
* A 400 rather than a filter: dropping an unrecognised exclusion leaves
|
|
92
|
+
* someone believing they narrowed a destructive run when they did not, and
|
|
93
|
+
* dropping a PROTECTIVE one would let a guard be switched off from the same
|
|
94
|
+
* request that starts the run. `steps` carries the offending ids so a UI can
|
|
95
|
+
* point at them.
|
|
96
|
+
*/
|
|
97
|
+
invalidExclusion(reason, steps) {
|
|
98
|
+
return new CleanupError("CLEANUP_INVALID_EXCLUSION", 400, reason, { steps: [...steps] });
|
|
99
|
+
},
|
|
88
100
|
forbidden(operation) {
|
|
89
101
|
return new CleanupError("CLEANUP_FORBIDDEN", 403, `Not authorized to ${operation} cleanup.`, { operation });
|
|
90
102
|
}
|
|
@@ -102,6 +114,53 @@ function stepContextOf(ctx, parameters) {
|
|
|
102
114
|
logger: ctx.logger
|
|
103
115
|
};
|
|
104
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Resolve the operator's exclusion list against the recipe's real steps.
|
|
119
|
+
*
|
|
120
|
+
* REFUSES rather than filters. Two rejections, both of which a permissive
|
|
121
|
+
* version would turn into a silent lie:
|
|
122
|
+
*
|
|
123
|
+
* - **unknown id** — a typo, or a step that has since been removed. Dropping
|
|
124
|
+
* it leaves the operator believing they narrowed a destructive run when the
|
|
125
|
+
* excluded domain will in fact be purged. A free-text ignore-list that
|
|
126
|
+
* silently tolerates unknown entries carries exactly this hazard.
|
|
127
|
+
* - **a protective step** — the property an ignore-list alone cannot give. A
|
|
128
|
+
* guard deletes nothing; it stands between the run and records that must
|
|
129
|
+
* never be purged. If it can be switched off from the same screen that
|
|
130
|
+
* starts the run, it is advice, not a guard. `destructive: false` alone is
|
|
131
|
+
* not the test — a projection rebuild is also non-destructive and IS
|
|
132
|
+
* legitimately excludable — so the marker is the step's own
|
|
133
|
+
* `disposition: 'protect'`.
|
|
134
|
+
*
|
|
135
|
+
* Returns the validated set; throws `CleanupErrors.invalidInput` otherwise.
|
|
136
|
+
*/
|
|
137
|
+
function resolveExclusions(steps, requested) {
|
|
138
|
+
if (!requested || requested.length === 0) return /* @__PURE__ */ new Set();
|
|
139
|
+
const byId = new Map(steps.map((s) => [s.id, s]));
|
|
140
|
+
const unknown = [];
|
|
141
|
+
const protectedIds = [];
|
|
142
|
+
for (const id of requested) {
|
|
143
|
+
const step = byId.get(id);
|
|
144
|
+
if (!step) {
|
|
145
|
+
unknown.push(id);
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
if (isProtective(step)) protectedIds.push(id);
|
|
149
|
+
}
|
|
150
|
+
if (unknown.length > 0) throw CleanupErrors.invalidExclusion(`excludeSteps names step(s) this recipe does not have: ${unknown.join(", ")}. Refusing rather than ignoring — a dropped exclusion means the run touches data the operator believed they had left out.`, unknown);
|
|
151
|
+
if (protectedIds.length > 0) throw CleanupErrors.invalidExclusion(`excludeSteps names protective step(s): ${protectedIds.join(", ")}. A guard deletes nothing; it refuses the run when records that must never be purged are present. It cannot be switched off from the same request that starts the run.`, protectedIds);
|
|
152
|
+
return new Set(requested);
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Is this step a GUARD?
|
|
156
|
+
*
|
|
157
|
+
* Asked of the step's declared disposition rather than `destructive`, because
|
|
158
|
+
* `destructive: false` covers guards AND projection rebuilds — and a rebuild is
|
|
159
|
+
* perfectly reasonable to exclude.
|
|
160
|
+
*/
|
|
161
|
+
function isProtective(step) {
|
|
162
|
+
return step.disposition === "protect";
|
|
163
|
+
}
|
|
105
164
|
function errMessage(err) {
|
|
106
165
|
return err instanceof Error ? err.message : String(err);
|
|
107
166
|
}
|
|
@@ -131,16 +190,63 @@ function recipeFromSteps(input) {
|
|
|
131
190
|
},
|
|
132
191
|
async plan(cleanupInput, ctx) {
|
|
133
192
|
const stepCtx = stepContextOf(ctx, cleanupInput.parameters ?? {});
|
|
193
|
+
const excluded = resolveExclusions(steps, cleanupInput.excludeSteps);
|
|
134
194
|
const items = [];
|
|
135
195
|
const blockers = /* @__PURE__ */ new Set();
|
|
136
196
|
const retains = new Set(input.retains ?? []);
|
|
137
197
|
const rebuildActions = /* @__PURE__ */ new Set();
|
|
138
198
|
const warnings = new Set(input.warnings ?? []);
|
|
139
199
|
for (const step of steps) {
|
|
200
|
+
/**
|
|
201
|
+
* An excluded step is NOT estimated.
|
|
202
|
+
*
|
|
203
|
+
* Estimating it would run its counting queries for a line the operator
|
|
204
|
+
* has already taken out — cost with no consequence — and, worse, would
|
|
205
|
+
* surface its blockers, so leaving a domain out of a run could still be
|
|
206
|
+
* refused because of that domain. A line the run will not touch must not
|
|
207
|
+
* be able to stop the run.
|
|
208
|
+
*/
|
|
209
|
+
if (excluded.has(step.id)) {
|
|
210
|
+
items.push({
|
|
211
|
+
stepId: step.id,
|
|
212
|
+
resource: step.resource,
|
|
213
|
+
estimated: 0,
|
|
214
|
+
excluded: true,
|
|
215
|
+
retained: "excluded from this run by the operator"
|
|
216
|
+
});
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
140
219
|
const est = await step.estimate(stepCtx);
|
|
220
|
+
/**
|
|
221
|
+
* Disposition comes from the STEP, not from `step.destructive`.
|
|
222
|
+
*
|
|
223
|
+
* (See the exclusion handling above for why `'protect'` also decides
|
|
224
|
+
* whether a line may be left out of a run.)
|
|
225
|
+
*
|
|
226
|
+
* They are close but not the same, and conflating them is how the bug
|
|
227
|
+
* this fixes arose. `destructive: false` covers BOTH a protective guard
|
|
228
|
+
* (counts what it defends) and a projection rebuild (counts what it
|
|
229
|
+
* recomputes) — opposite meanings for the headline. A step that says
|
|
230
|
+
* nothing means `'remove'`, which is what every purge step is.
|
|
231
|
+
*/
|
|
232
|
+
/**
|
|
233
|
+
* A step may only PROTECT if it said so on the step itself.
|
|
234
|
+
*
|
|
235
|
+
* `resolveExclusions` runs before any estimate — it has to, since it
|
|
236
|
+
* decides which steps to estimate at all — so it can read only
|
|
237
|
+
* `step.disposition`. A guard that declared `'protect'` from its
|
|
238
|
+
* ESTIMATE instead was therefore excludable: the plan line came back
|
|
239
|
+
* marked protective, looked defended, and `excludeSteps: [thatId]`
|
|
240
|
+
* still switched it off. That is precisely the property this feature
|
|
241
|
+
* exists to make impossible, so the mismatch is an authoring error
|
|
242
|
+
* rather than a silent downgrade.
|
|
243
|
+
*/
|
|
244
|
+
if (est.disposition === "protect" && step.disposition !== "protect") throw CleanupErrors.invalidExclusion(`step '${step.id}' returned disposition 'protect' from its estimate but does not declare \`disposition: 'protect'\` on the step. Exclusions are resolved before estimates run, so a guard declared only at estimate time can be excluded — switching off the check it exists to enforce. Declare it on the step.`, [step.id]);
|
|
141
245
|
items.push({
|
|
246
|
+
stepId: step.id,
|
|
142
247
|
resource: est.resource,
|
|
143
248
|
estimated: est.estimated,
|
|
249
|
+
...(est.disposition ?? step.disposition) !== void 0 ? { disposition: est.disposition ?? step.disposition } : {},
|
|
144
250
|
...est.retained !== void 0 ? { retained: est.retained } : {},
|
|
145
251
|
...est.blockers && est.blockers.length > 0 ? { blockers: est.blockers } : {}
|
|
146
252
|
});
|
|
@@ -161,8 +267,44 @@ function recipeFromSteps(input) {
|
|
|
161
267
|
async execute(plan, ctx) {
|
|
162
268
|
const parameters = plan.parameters ?? {};
|
|
163
269
|
const results = [];
|
|
270
|
+
/**
|
|
271
|
+
* Re-resolved from the SEALED plan, never from a fresh caller input.
|
|
272
|
+
*
|
|
273
|
+
* The exclusion set is part of the digest the operator confirmed against,
|
|
274
|
+
* so taking it from the plan is what makes consent binding: an execute
|
|
275
|
+
* cannot widen the run beyond what was previewed. Re-validating here also
|
|
276
|
+
* means a step that has since become protective refuses rather than being
|
|
277
|
+
* quietly dropped.
|
|
278
|
+
*/
|
|
279
|
+
const excluded = resolveExclusions(steps, plan.excludeSteps);
|
|
280
|
+
/**
|
|
281
|
+
* Lifecycle reporting is OPTIONAL on the context — a host service that
|
|
282
|
+
* predates it simply gets no per-step view, rather than a crash. Resolved
|
|
283
|
+
* once so the loop below reads as bookkeeping, not feature detection.
|
|
284
|
+
*/
|
|
285
|
+
const reportState = ctx.onStepState?.bind(ctx) ?? (async () => {});
|
|
164
286
|
for (const step of steps) {
|
|
165
287
|
await ctx.throwIfCancelled();
|
|
288
|
+
if (excluded.has(step.id)) {
|
|
289
|
+
await reportState({
|
|
290
|
+
stepId: step.id,
|
|
291
|
+
resource: step.resource,
|
|
292
|
+
status: "skipped",
|
|
293
|
+
processed: 0,
|
|
294
|
+
startedAt: ctx.now,
|
|
295
|
+
completedAt: ctx.now,
|
|
296
|
+
detail: "excluded by the operator"
|
|
297
|
+
});
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
const startedAt = ctx.now;
|
|
301
|
+
await reportState({
|
|
302
|
+
stepId: step.id,
|
|
303
|
+
resource: step.resource,
|
|
304
|
+
status: "running",
|
|
305
|
+
processed: 0,
|
|
306
|
+
startedAt
|
|
307
|
+
});
|
|
166
308
|
let reported = 0;
|
|
167
309
|
const execCtx = {
|
|
168
310
|
...stepContextOf(ctx, parameters),
|
|
@@ -211,6 +353,25 @@ function recipeFromSteps(input) {
|
|
|
211
353
|
...outcome.error !== void 0 ? { error: outcome.error } : {},
|
|
212
354
|
...outcome.cursor !== void 0 ? { cursor: outcome.cursor } : {}
|
|
213
355
|
});
|
|
356
|
+
/**
|
|
357
|
+
* `skipped` is a REAL outcome, not "completed with zero".
|
|
358
|
+
*
|
|
359
|
+
* A step that had nothing in scope and a step that removed 4,000 rows
|
|
360
|
+
* both end `ok`, and reading a bare 0 as success is how an operator
|
|
361
|
+
* concludes a phase ran when its scope was simply empty. Three states
|
|
362
|
+
* alone only CATEGORISE the outcome; the `detail` is what makes it
|
|
363
|
+
* answerable.
|
|
364
|
+
*/
|
|
365
|
+
const isSkip = outcome.ok && outcome.processed === 0;
|
|
366
|
+
await reportState({
|
|
367
|
+
stepId: step.id,
|
|
368
|
+
resource: outcome.resource,
|
|
369
|
+
status: outcome.ok ? isSkip ? "skipped" : "completed" : "failed",
|
|
370
|
+
processed: outcome.processed,
|
|
371
|
+
startedAt,
|
|
372
|
+
completedAt: ctx.now,
|
|
373
|
+
...outcome.ok ? isSkip ? { detail: "nothing in scope" } : {} : { detail: outcome.error ?? "step failed" }
|
|
374
|
+
});
|
|
214
375
|
if (!outcome.ok) break;
|
|
215
376
|
}
|
|
216
377
|
const allOk = results.every((r) => r.ok);
|
|
@@ -465,12 +626,15 @@ function planMaterial(plan) {
|
|
|
465
626
|
items: plan.items.map((i) => ({
|
|
466
627
|
resource: i.resource,
|
|
467
628
|
estimated: i.estimated,
|
|
629
|
+
disposition: i.disposition ?? "remove",
|
|
630
|
+
excluded: i.excluded ?? false,
|
|
468
631
|
retained: i.retained ?? null,
|
|
469
632
|
blockers: [...i.blockers ?? []].sort()
|
|
470
633
|
})).sort((a, b) => a.resource < b.resource ? -1 : a.resource > b.resource ? 1 : a.estimated - b.estimated),
|
|
471
634
|
retains: [...plan.retains].sort(),
|
|
472
635
|
blockers: [...plan.blockers].sort(),
|
|
473
636
|
rebuildActions: [...plan.rebuildActions].sort(),
|
|
637
|
+
excludeSteps: [...plan.excludeSteps].sort(),
|
|
474
638
|
estimatedTotal: plan.estimatedTotal,
|
|
475
639
|
confirmationPhrase: plan.confirmationPhrase
|
|
476
640
|
};
|
|
@@ -586,10 +750,22 @@ function createCleanupService(deps) {
|
|
|
586
750
|
};
|
|
587
751
|
}
|
|
588
752
|
async function seal(recipe, input, ctx) {
|
|
589
|
-
const draft = await recipe.plan({
|
|
753
|
+
const draft = await recipe.plan({
|
|
754
|
+
parameters: input.parameters,
|
|
755
|
+
excludeSteps: input.excludeSteps
|
|
756
|
+
}, ctx);
|
|
590
757
|
const items = draft.items;
|
|
591
758
|
if (items.length > limits.maxPlanItems) throw CleanupErrors.planTooLarge(`${items.length} items > maxPlanItems ${limits.maxPlanItems}`);
|
|
592
|
-
|
|
759
|
+
/**
|
|
760
|
+
* Partition by DISPOSITION — a protective guard's count is not damage.
|
|
761
|
+
*
|
|
762
|
+
* This was one `reduce` over every item, so a guard reporting the 173 posted
|
|
763
|
+
* journal entries it defends pushed the "records to remove" headline to 540
|
|
764
|
+
* on a plan that removes 367. Absent disposition means `'remove'`, so every
|
|
765
|
+
* pre-existing recipe is unchanged.
|
|
766
|
+
*/
|
|
767
|
+
const estimatedTotal = items.reduce((sum, i) => sum + ((i.disposition ?? "remove") === "remove" ? i.estimated : 0), 0);
|
|
768
|
+
const protectedTotal = items.reduce((sum, i) => sum + (i.disposition === "protect" ? i.estimated : 0), 0);
|
|
593
769
|
const blockers = new Set(draft.blockers ?? []);
|
|
594
770
|
for (const item of items) for (const b of item.blockers ?? []) blockers.add(b);
|
|
595
771
|
const unsealed = {
|
|
@@ -601,6 +777,8 @@ function createCleanupService(deps) {
|
|
|
601
777
|
rebuildActions: [...draft.rebuildActions ?? []],
|
|
602
778
|
warnings: [...draft.warnings ?? []],
|
|
603
779
|
estimatedTotal,
|
|
780
|
+
protectedTotal,
|
|
781
|
+
excludeSteps: [...input.excludeSteps ?? []].sort(),
|
|
604
782
|
confirmationPhrase: draft.confirmationPhrase ?? recipe.id
|
|
605
783
|
};
|
|
606
784
|
return {
|
|
@@ -713,6 +891,14 @@ function createCleanupService(deps) {
|
|
|
713
891
|
let processed = 0;
|
|
714
892
|
let steps = 0;
|
|
715
893
|
let failed = 0;
|
|
894
|
+
/**
|
|
895
|
+
* Per-step lifecycle, keyed by `stepId` and ordered by first sight.
|
|
896
|
+
*
|
|
897
|
+
* Seeded from the run's existing progress so a RESUMED run (crash recovery,
|
|
898
|
+
* retry) keeps the states it already recorded instead of presenting an
|
|
899
|
+
* operator with a blank pipeline for work that demonstrably happened.
|
|
900
|
+
*/
|
|
901
|
+
const stepStates = new Map((run.progress?.stepProgress ?? []).map((s) => [s.stepId, s]));
|
|
716
902
|
let cancelled = false;
|
|
717
903
|
let lastSummary = run.progress ?? EMPTY_PROGRESS;
|
|
718
904
|
let lastPersistMs = 0;
|
|
@@ -745,6 +931,7 @@ function createCleanupService(deps) {
|
|
|
745
931
|
steps,
|
|
746
932
|
failed,
|
|
747
933
|
currentResource: step.resource,
|
|
934
|
+
...stepStates.size > 0 ? { stepProgress: [...stepStates.values()] } : {},
|
|
748
935
|
...step.cursor !== void 0 ? { lastCursor: step.cursor } : {},
|
|
749
936
|
heartbeatAt: now()
|
|
750
937
|
};
|
|
@@ -756,6 +943,31 @@ function createCleanupService(deps) {
|
|
|
756
943
|
await refreshCancel();
|
|
757
944
|
}
|
|
758
945
|
},
|
|
946
|
+
/**
|
|
947
|
+
* Upsert one step's lifecycle state, preserving FIRST-SEEN order.
|
|
948
|
+
*
|
|
949
|
+
* A `Map` keyed by `stepId` is what keeps this bounded and idempotent: a
|
|
950
|
+
* step transitioning running → completed updates its entry rather than
|
|
951
|
+
* appending, so the array length is the step count and never the
|
|
952
|
+
* transition count. Insertion order is the execution order, which is what
|
|
953
|
+
* an operator reads down the list.
|
|
954
|
+
*
|
|
955
|
+
* Persisted on the NEXT `onStep` (or the terminal write) rather than
|
|
956
|
+
* immediately — a lifecycle transition is not itself a committed chunk,
|
|
957
|
+
* and writing on every one would defeat the progress throttle that exists
|
|
958
|
+
* to keep a long run from hammering the store.
|
|
959
|
+
*/
|
|
960
|
+
async onStepState(state) {
|
|
961
|
+
stepStates.set(state.stepId, state);
|
|
962
|
+
lastSummary = {
|
|
963
|
+
...lastSummary ?? {
|
|
964
|
+
processed,
|
|
965
|
+
steps,
|
|
966
|
+
failed
|
|
967
|
+
},
|
|
968
|
+
stepProgress: [...stepStates.values()]
|
|
969
|
+
};
|
|
970
|
+
},
|
|
759
971
|
async throwIfCancelled() {
|
|
760
972
|
if (cancelled || controller.signal.aborted || await refreshCancel()) throw new CleanupCancelled(run.id);
|
|
761
973
|
}
|
|
@@ -1079,13 +1291,31 @@ const parametersSchema = {
|
|
|
1079
1291
|
type: "object",
|
|
1080
1292
|
additionalProperties: true
|
|
1081
1293
|
};
|
|
1294
|
+
/**
|
|
1295
|
+
* Step ids to leave out. Bounded and unique — an unbounded list on a
|
|
1296
|
+
* destructive endpoint is a denial-of-service surface, and a duplicate id says
|
|
1297
|
+
* nothing a single one does not. Unknown or PROTECTIVE ids are refused by the
|
|
1298
|
+
* recipe (CLEANUP_INVALID_EXCLUSION), not stripped here: the route must not
|
|
1299
|
+
* decide what an operator may narrow.
|
|
1300
|
+
*/
|
|
1301
|
+
const excludeStepsSchema = {
|
|
1302
|
+
type: "array",
|
|
1303
|
+
items: {
|
|
1304
|
+
type: "string",
|
|
1305
|
+
minLength: 1,
|
|
1306
|
+
maxLength: 200
|
|
1307
|
+
},
|
|
1308
|
+
maxItems: 200,
|
|
1309
|
+
uniqueItems: true
|
|
1310
|
+
};
|
|
1082
1311
|
const previewBodySchema = {
|
|
1083
1312
|
type: "object",
|
|
1084
1313
|
required: ["recipe"],
|
|
1085
1314
|
additionalProperties: false,
|
|
1086
1315
|
properties: {
|
|
1087
1316
|
recipe: recipeIdSchema,
|
|
1088
|
-
parameters: parametersSchema
|
|
1317
|
+
parameters: parametersSchema,
|
|
1318
|
+
excludeSteps: excludeStepsSchema
|
|
1089
1319
|
}
|
|
1090
1320
|
};
|
|
1091
1321
|
const runsBodySchema = {
|
|
@@ -1099,6 +1329,7 @@ const runsBodySchema = {
|
|
|
1099
1329
|
properties: {
|
|
1100
1330
|
recipe: recipeIdSchema,
|
|
1101
1331
|
parameters: parametersSchema,
|
|
1332
|
+
excludeSteps: excludeStepsSchema,
|
|
1102
1333
|
planDigest: {
|
|
1103
1334
|
type: "string",
|
|
1104
1335
|
minLength: 1,
|
|
@@ -1208,6 +1439,7 @@ function createDataCleanupModule(deps) {
|
|
|
1208
1439
|
const plan = await (await service()).preview({
|
|
1209
1440
|
recipeId: body.recipe,
|
|
1210
1441
|
parameters: body.parameters,
|
|
1442
|
+
excludeSteps: body.excludeSteps,
|
|
1211
1443
|
actor: resolveActor(r),
|
|
1212
1444
|
ambient: resolveAmbient?.(r)
|
|
1213
1445
|
});
|
|
@@ -1226,6 +1458,7 @@ function createDataCleanupModule(deps) {
|
|
|
1226
1458
|
const run = await (await service()).execute({
|
|
1227
1459
|
recipeId: body.recipe,
|
|
1228
1460
|
parameters: body.parameters,
|
|
1461
|
+
excludeSteps: body.excludeSteps,
|
|
1229
1462
|
planDigest: body.planDigest,
|
|
1230
1463
|
reason: body.reason,
|
|
1231
1464
|
confirmation: body.confirmation,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import { Nt as RateLimitConfig, V as ResourceDefinition, et as RouteSchemaOptions } from "../../index-
|
|
2
|
+
import { Nt as RateLimitConfig, V as ResourceDefinition, et as RouteSchemaOptions } from "../../index-BcR2bFZQ.mjs";
|
|
3
3
|
//#region src/cli/commands/describe.d.ts
|
|
4
4
|
interface DescribedResource {
|
|
5
5
|
name: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { t as CRUD_OPERATIONS } from "../../constants-
|
|
3
|
-
import { n as stringifyMeasureMap } from "../../ResourceRegistry-
|
|
1
|
+
/*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
|
|
2
|
+
import { t as CRUD_OPERATIONS } from "../../constants-BxCoxmiN.mjs";
|
|
3
|
+
import { n as stringifyMeasureMap } from "../../ResourceRegistry-DoALUlOO.mjs";
|
|
4
4
|
import { resolve } from "node:path";
|
|
5
5
|
import { pathToFileURL } from "node:url";
|
|
6
6
|
//#region src/cli/commands/describe.ts
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { t as buildOpenApiSpec } from "../../openapi-
|
|
3
|
-
import { t as loadResourcesFromEntry } from "../../loadResourcesFromEntry-
|
|
1
|
+
/*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
|
|
2
|
+
import { t as buildOpenApiSpec } from "../../openapi-CkV5mQ53.mjs";
|
|
3
|
+
import { t as loadResourcesFromEntry } from "../../loadResourcesFromEntry-DwaxNcE2.mjs";
|
|
4
4
|
import { dirname, resolve } from "node:path";
|
|
5
5
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
6
6
|
//#region src/cli/commands/docs.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
1
|
+
/*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
|
|
2
2
|
import { dirname, join, parse, resolve } from "node:path";
|
|
3
3
|
import { existsSync, readFileSync } from "node:fs";
|
|
4
4
|
//#region src/cli/commands/doctor.ts
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { t as generate } from "../../generate-
|
|
1
|
+
/*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
|
|
2
|
+
import { t as generate } from "../../generate-DiB0nHPR.mjs";
|
|
3
3
|
export { generate };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { t as init } from "../../init-
|
|
1
|
+
/*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
|
|
2
|
+
import { t as init } from "../../init-mdJ-v4Xp.mjs";
|
|
3
3
|
export { init };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { t as loadResourcesFromEntry } from "../../loadResourcesFromEntry-
|
|
1
|
+
/*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
|
|
2
|
+
import { t as loadResourcesFromEntry } from "../../loadResourcesFromEntry-DwaxNcE2.mjs";
|
|
3
3
|
//#region src/cli/commands/introspect.ts
|
|
4
4
|
function describePermission(value) {
|
|
5
5
|
if (!value) return "none";
|
package/dist/cli/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
1
|
+
/*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
|
|
2
2
|
import { describe } from "./commands/describe.mjs";
|
|
3
3
|
import { exportDocs } from "./commands/docs.mjs";
|
|
4
4
|
import { doctor } from "./commands/doctor.mjs";
|
|
5
|
-
import { t as generate } from "../generate-
|
|
6
|
-
import { t as init } from "../init-
|
|
5
|
+
import { t as generate } from "../generate-DiB0nHPR.mjs";
|
|
6
|
+
import { t as init } from "../init-mdJ-v4Xp.mjs";
|
|
7
7
|
import { introspect } from "./commands/introspect.mjs";
|
|
8
8
|
export { describe, doctor, exportDocs, generate, init, introspect };
|
package/dist/context/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { n as requestContext, t as getTraceHeaders } from "../requestContext-
|
|
3
|
-
import { t as transactionContext } from "../transactionContext-
|
|
1
|
+
/*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
|
|
2
|
+
import { n as requestContext, t as getTraceHeaders } from "../requestContext-uYE35JxI.mjs";
|
|
3
|
+
import { t as transactionContext } from "../transactionContext-BYtWnwAS.mjs";
|
|
4
4
|
export { getTraceHeaders, requestContext, transactionContext };
|
package/dist/core/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
|
|
2
|
-
import { $t as
|
|
3
|
-
import { A as
|
|
4
|
-
export { AccessControl, type AccessControlConfig, type AdapterLike, type AggMeasureInput, type AggMeasureShorthand, type AggregationCacheConfig, type AggregationConfig, type AggregationDateRangeRequirement, type AggregationIndexHint, type AggregationMaterializedContext, type AggregationMaterializedResult, type AggregationRateLimit, type AggregationsMap, BaseController, type BaseControllerOptions, BaseCrudController, BodySanitizer, type BodySanitizerConfig, type BulkExt, BulkMixin, CRUD_OPERATIONS, type ConfigError, type ControllerConfigurableOptions, type ControllerConstructionOptions, CrudOperation, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, type DefineActionConfig, HOOK_OPERATIONS, HOOK_PHASES, HookOperation, HookPhase, type ListResult, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, MutationOperation, QueryResolver, type QueryResolverConfig, RESERVED_QUERY_PARAMS, ResourceDefinition, type ResourceSeams, SYSTEM_FIELDS, type SeamedResourceConfig, type SlugExt, SlugMixin, type SoftDeleteExt, SoftDeleteMixin, type TreeExt, TreeMixin, type ValidateOptions, type ValidationResult, assertValidConfig, collectReadBlockedFields, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineAction, defineAggregation, defineResource, defineResourceVariants, formatValidationErrors, getControllerContext, getControllerScope, getEntityId, getEntityIdField, getEntityQuery, isFieldReadable, mergeResourceConfig, sendControllerResponse, validateResourceConfig };
|
|
2
|
+
import { $t as AccessControlConfig, B as defineResource, Bt as BaseController, Cn as ControllerConstructionOptions, En as BodySanitizerConfig, Gt as SlugExt, Ht as SoftDeleteMixin, Jt as BulkMixin, Kt as SlugMixin, Qt as AccessControl, Sn as ControllerConfigurableOptions, Tn as BodySanitizer, Ut as TreeExt, V as ResourceDefinition, Vt as SoftDeleteExt, Wt as TreeMixin, Xt as QueryResolver, Yt as BaseCrudController, Zt as QueryResolverConfig, ct as AggMeasureShorthand, dt as AggregationDateRangeRequirement, ft as AggregationIndexHint, gt as AggregationsMap, ht as AggregationRateLimit, lt as AggregationCacheConfig, mt as AggregationMaterializedResult, pt as AggregationMaterializedContext, qt as BulkExt, st as AggMeasureInput, ut as AggregationConfig, wn as ListResult, xn as BaseControllerOptions } from "../index-BcR2bFZQ.mjs";
|
|
3
|
+
import { A as CRUD_OPERATIONS, B as HookOperation, C as SeamedResourceConfig, D as createCrudRouter, E as defineAction, F as DEFAULT_SORT, G as MUTATION_OPERATIONS, H as MAX_FILTER_DEPTH, I as DEFAULT_TENANT_FIELD, J as SYSTEM_FIELDS, K as MutationOperation, L as DEFAULT_UPDATE_METHOD, M as DEFAULT_ID_FIELD, N as DEFAULT_LIMIT, O as createPermissionMiddleware, P as DEFAULT_MAX_LIMIT, R as HOOK_OPERATIONS, S as ResourceSeams, T as DefineActionConfig, U as MAX_REGEX_LENGTH, V as HookPhase, W as MAX_SEARCH_LENGTH, _ as getEntityId, a as formatValidationErrors, b as defineResourceVariants, c as nativePolicyFilter, d as createCrudHandlers, f as createFastifyHandler, g as sendControllerResponse, h as getControllerScope, i as assertValidConfig, j as CrudOperation, k as defineAggregation, l as collectReadBlockedFields, m as getControllerContext, n as ValidateOptions, o as validateResourceConfig, p as createRequestContext, q as RESERVED_QUERY_PARAMS, r as ValidationResult, s as NativePolicyFilter, t as ConfigError, u as isFieldReadable, v as getEntityIdField, w as mergeResourceConfig, x as AdapterLike, y as getEntityQuery, z as HOOK_PHASES } from "../index-CFAJEWCX.mjs";
|
|
4
|
+
export { AccessControl, type AccessControlConfig, type AdapterLike, type AggMeasureInput, type AggMeasureShorthand, type AggregationCacheConfig, type AggregationConfig, type AggregationDateRangeRequirement, type AggregationIndexHint, type AggregationMaterializedContext, type AggregationMaterializedResult, type AggregationRateLimit, type AggregationsMap, BaseController, type BaseControllerOptions, BaseCrudController, BodySanitizer, type BodySanitizerConfig, type BulkExt, BulkMixin, CRUD_OPERATIONS, type ConfigError, type ControllerConfigurableOptions, type ControllerConstructionOptions, CrudOperation, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, type DefineActionConfig, HOOK_OPERATIONS, HOOK_PHASES, HookOperation, HookPhase, type ListResult, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, MutationOperation, type NativePolicyFilter, QueryResolver, type QueryResolverConfig, RESERVED_QUERY_PARAMS, ResourceDefinition, type ResourceSeams, SYSTEM_FIELDS, type SeamedResourceConfig, type SlugExt, SlugMixin, type SoftDeleteExt, SoftDeleteMixin, type TreeExt, TreeMixin, type ValidateOptions, type ValidationResult, assertValidConfig, collectReadBlockedFields, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineAction, defineAggregation, defineResource, defineResourceVariants, formatValidationErrors, getControllerContext, getControllerScope, getEntityId, getEntityIdField, getEntityQuery, isFieldReadable, mergeResourceConfig, nativePolicyFilter, sendControllerResponse, validateResourceConfig };
|
package/dist/core/index.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
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-
|
|
3
|
-
import {
|
|
4
|
-
import { a as
|
|
5
|
-
import { a as
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
1
|
+
/*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
|
|
2
|
+
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-BxCoxmiN.mjs";
|
|
3
|
+
import { t as nativePolicyFilter } from "../repositoryFilter-BANpz6BX.mjs";
|
|
4
|
+
import { a as BulkMixin, c as collectReadBlockedFields, f as BodySanitizer, i as SlugMixin, l as isFieldReadable, m as AccessControl, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, s as QueryResolver, t as BaseController } from "../BaseController-CbkuhNI2.mjs";
|
|
5
|
+
import { a as ResourceDefinition, i as validateResourceConfig, n as assertValidConfig, o as createCrudRouter, r as formatValidationErrors, s as createPermissionMiddleware, t as defineResource } from "../defineResource-ZhuLonLm.mjs";
|
|
6
|
+
import { a as createFastifyHandler, c as getControllerScope, i as createCrudHandlers, l as sendControllerResponse, o as createRequestContext, s as getControllerContext } from "../pipeline-q69DZzgG.mjs";
|
|
7
|
+
import { t as defineAggregation } from "../defineAggregation-Nv-DwfOf.mjs";
|
|
8
|
+
import { a as mergeResourceConfig, i as defineResourceVariants, n as getEntityIdField, o as defineAction, r as getEntityQuery, t as getEntityId } from "../core-BYKa8wHu.mjs";
|
|
9
|
+
export { AccessControl, BaseController, BaseCrudController, BodySanitizer, BulkMixin, CRUD_OPERATIONS, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, HOOK_OPERATIONS, HOOK_PHASES, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, QueryResolver, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, SlugMixin, SoftDeleteMixin, TreeMixin, assertValidConfig, collectReadBlockedFields, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineAction, defineAggregation, defineResource, defineResourceVariants, formatValidationErrors, getControllerContext, getControllerScope, getEntityId, getEntityIdField, getEntityQuery, isFieldReadable, mergeResourceConfig, nativePolicyFilter, sendControllerResponse, validateResourceConfig };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import "./constants-
|
|
3
|
-
import { t as defineResource } from "./defineResource-
|
|
1
|
+
/*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
|
|
2
|
+
import "./constants-BxCoxmiN.mjs";
|
|
3
|
+
import { t as defineResource } from "./defineResource-ZhuLonLm.mjs";
|
|
4
4
|
//#region src/core/defineAction.ts
|
|
5
5
|
/**
|
|
6
6
|
* Build an `ActionDefinition` with a typed handler. The literal schema
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { t as __exportAll } from "./rolldown-runtime-
|
|
3
|
-
import "./constants-
|
|
4
|
-
import { f as createError } from "./errors-
|
|
5
|
-
import { a as buildRouteHooks, i as selectPluginMw, l as buildAuthMiddlewareForPermissions, n as buildRouteConfig, r as resolveRouterPluginMw, s as routeHookOptions, t as buildRateLimitConfig, u as buildArcDecorator } from "./rateLimit-
|
|
6
|
-
import { n as buildActionPermissionMw, t as tryRegisterRoute } from "./registerRoute-
|
|
7
|
-
import { l as sendControllerResponse, r as resolvePipelineSteps, t as buildActionPipelineHandler } from "./pipeline-
|
|
8
|
-
import { n as schemaIRToJsonSchemaBranch, t as normalizeSchemaIR } from "./schemaIR-
|
|
1
|
+
/*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
|
|
2
|
+
import { t as __exportAll } from "./rolldown-runtime-DNg-KNCk.mjs";
|
|
3
|
+
import "./constants-BxCoxmiN.mjs";
|
|
4
|
+
import { f as createError } from "./errors-Cd_yy7aW.mjs";
|
|
5
|
+
import { a as buildRouteHooks, i as selectPluginMw, l as buildAuthMiddlewareForPermissions, n as buildRouteConfig, r as resolveRouterPluginMw, s as routeHookOptions, t as buildRateLimitConfig, u as buildArcDecorator } from "./rateLimit-D4-ASwsI.mjs";
|
|
6
|
+
import { n as buildActionPermissionMw, t as tryRegisterRoute } from "./registerRoute-Ba8v0PCa.mjs";
|
|
7
|
+
import { l as sendControllerResponse, r as resolvePipelineSteps, t as buildActionPipelineHandler } from "./pipeline-q69DZzgG.mjs";
|
|
8
|
+
import { n as schemaIRToJsonSchemaBranch, t as normalizeSchemaIR } from "./schemaIR-CDvclAew.mjs";
|
|
9
9
|
//#region src/core/createActionRouter.ts
|
|
10
10
|
var createActionRouter_exports = /* @__PURE__ */ __exportAll({
|
|
11
11
|
buildActionBodySchema: () => buildActionBodySchema,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { n as evaluateAndApplyPermission } from "./authorizationDecision-
|
|
3
|
-
import { f as createError } from "./errors-
|
|
4
|
-
import { u as getRequestScope } from "./types-
|
|
5
|
-
import { a as buildRouteHooks, c as buildAuthMiddleware, i as selectPluginMw, r as resolveRouterPluginMw, s as routeHookOptions, t as buildRateLimitConfig, u as buildArcDecorator } from "./rateLimit-
|
|
6
|
-
import { n as validateAggregations } from "./validate-
|
|
7
|
-
import { t as buildAggregationHandler } from "./buildHandler-
|
|
1
|
+
/*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
|
|
2
|
+
import { n as evaluateAndApplyPermission } from "./authorizationDecision-CMMLWmuZ.mjs";
|
|
3
|
+
import { f as createError } from "./errors-Cd_yy7aW.mjs";
|
|
4
|
+
import { u as getRequestScope } from "./types-CoqIRrkY.mjs";
|
|
5
|
+
import { a as buildRouteHooks, c as buildAuthMiddleware, i as selectPluginMw, r as resolveRouterPluginMw, s as routeHookOptions, t as buildRateLimitConfig, u as buildArcDecorator } from "./rateLimit-D4-ASwsI.mjs";
|
|
6
|
+
import { n as validateAggregations } from "./validate-CdQlz52F.mjs";
|
|
7
|
+
import { t as buildAggregationHandler } from "./buildHandler-BrdYrG_1.mjs";
|
|
8
8
|
//#region src/core/aggregation/createAggregationRouter.ts
|
|
9
9
|
/**
|
|
10
10
|
* Register one Fastify route per aggregation. No-op when the map is
|