@classytic/arc 2.19.0 → 2.20.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 +37 -0
- package/dist/{BaseController-Dy6EQHjM.mjs → BaseController-D-MHZ27_.mjs} +4 -4
- package/dist/{ResourceRegistry-5fKZwhK_.mjs → ResourceRegistry-7RnrEWNP.mjs} +1 -1
- package/dist/{actionPermissions-D7NGwcAR.mjs → actionPermissions-C9RMiIpc.mjs} +1 -1
- package/dist/audit/index.mjs +1 -1
- package/dist/auth/index.d.mts +1 -1
- package/dist/auth/index.mjs +7 -5
- package/dist/{buildHandler-B0qvAguf.mjs → buildHandler-D_2ULWxZ.mjs} +3 -3
- package/dist/cache/index.mjs +2 -2
- package/dist/cli/commands/describe.d.mts +1 -1
- package/dist/cli/commands/describe.mjs +2 -2
- package/dist/cli/commands/docs.mjs +2 -2
- package/dist/cli/commands/generate.mjs +1 -1
- package/dist/cli/commands/init.mjs +1 -1
- package/dist/cli/commands/introspect.mjs +4 -13
- package/dist/cli/index.mjs +2 -2
- package/dist/{constants-gaEeMlz-.mjs → constants-DNre0wRg.mjs} +1 -1
- package/dist/core/index.d.mts +2 -2
- package/dist/core/index.mjs +4 -4
- package/dist/{core-Ba-6Sue6.mjs → core-CWhyGkiM.mjs} +125 -53
- package/dist/{createActionRouter-B_WzBFyf.mjs → createActionRouter-HlQso0jO.mjs} +4 -4
- package/dist/{createAggregationRouter-B_G_nIjm.mjs → createAggregationRouter-5LzPzgw1.mjs} +5 -4
- package/dist/{createApp--703hQE1.mjs → createApp-D6uwzCKu.mjs} +210 -17
- package/dist/docs/index.d.mts +1 -1
- package/dist/docs/index.mjs +1 -1
- package/dist/events/index.mjs +9 -6
- package/dist/factory/index.d.mts +3 -2
- package/dist/factory/index.mjs +2 -2
- package/dist/{fastify-augmentation-D-5_yQJi.d.mts → fastify-augmentation-CCQJEDgh.d.mts} +12 -1
- package/dist/{generate-Brans3fW.mjs → generate-usRSdQmP.mjs} +4 -3
- package/dist/hooks/index.d.mts +1 -1
- package/dist/idempotency/index.mjs +1 -1
- package/dist/{index-CRKiiP5o.d.mts → index-CdFkIMEd.d.mts} +5 -0
- package/dist/{index-CP6A1Ffj.d.mts → index-DUa8WHz3.d.mts} +1 -1
- package/dist/{index-CUTG2Cuo.d.mts → index-_--GyzcO.d.mts} +28 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +6 -6
- package/dist/{init-Bqpt1Hxf.mjs → init-YH_nslQR.mjs} +87 -5
- package/dist/integrations/index.d.mts +1 -1
- package/dist/integrations/mcp/index.d.mts +2 -2
- package/dist/integrations/mcp/index.mjs +1 -1
- package/dist/integrations/mcp/testing.d.mts +1 -1
- package/dist/integrations/mcp/testing.mjs +1 -1
- package/dist/integrations/streamline.d.mts +17 -5
- package/dist/integrations/streamline.mjs +9 -5
- package/dist/{loadResourcesFromEntry-BTlFEx05.mjs → loadResourcesFromEntry-OMCvIEE7.mjs} +1 -1
- package/dist/{mcpPlugin-C088Nd-G.mjs → mcpPlugin-CuW6L_uD.mjs} +148 -49
- package/dist/middleware/index.d.mts +1 -1
- package/dist/middleware/index.mjs +1 -1
- package/dist/module-JYH9V0I8.d.mts +384 -0
- package/dist/{openapi-DZ-5a5Op.mjs → openapi-Dq6RbEGK.mjs} +3 -3
- package/dist/permissions/index.d.mts +1 -1
- package/dist/permissions/index.mjs +1 -1
- package/dist/{permissions-BPB1xqGf.mjs → permissions-CgbOLJZG.mjs} +10 -2
- package/dist/pipeline/index.d.mts +1 -1
- package/dist/plugins/index.d.mts +10 -5
- package/dist/plugins/index.mjs +3 -3
- package/dist/plugins/tracing-entry.mjs +1 -1
- package/dist/{pluralize-DccFV9R7.mjs → pluralize-BhrgwZb9.mjs} +3 -3
- package/dist/presets/filesUpload.d.mts +1 -1
- package/dist/presets/filesUpload.mjs +1 -1
- package/dist/presets/index.d.mts +16 -2
- package/dist/presets/index.mjs +1 -1
- package/dist/presets/multiTenant.d.mts +1 -1
- package/dist/presets/multiTenant.mjs +1 -1
- package/dist/presets/search.d.mts +1 -1
- package/dist/presets/search.mjs +3 -2
- package/dist/{presets-BtyFwTO4.mjs → presets-DWsYQdbV.mjs} +1 -1
- package/dist/{queryCachePlugin-emHb0CuX.mjs → queryCachePlugin-DzqLN904.mjs} +2 -2
- package/dist/{registerRoute-BdV8DDwU.mjs → registerRoute-DGSREwPw.mjs} +1 -1
- package/dist/registry/index.d.mts +1 -1
- package/dist/registry/index.mjs +2 -2
- package/dist/{registry-Bm9LjWKs.mjs → registry-vcOCtPij.mjs} +1 -1
- package/dist/{schemaIR-D1MJwqmp.mjs → schemaIR-ajetw3Fv.mjs} +1 -42
- package/dist/scim/index.mjs +2 -2
- package/dist/sync/changelog.d.mts +2 -0
- package/dist/sync/changelog.mjs +2 -0
- package/dist/testing/index.d.mts +2 -2
- package/dist/testing/index.mjs +2 -2
- package/dist/types/index.d.mts +1 -1
- package/dist/{types-9_wtNPsI.d.mts → types-BHMKlMBU.d.mts} +53 -195
- package/dist/{types-DpvSF5Hh.d.mts → types-C9b2HR5W.d.mts} +1 -1
- package/dist/utils/index.d.mts +1 -1
- package/dist/utils/index.mjs +1 -1
- package/dist/{utils-C6QQ9-hd.mjs → utils-ChjYQpjn.mjs} +1400 -1400
- package/dist/{validate-CRcaWzp2.mjs → validate-C2mGgSXg.mjs} +3 -3
- package/package.json +13 -8
- package/skills/arc/SKILL.md +10 -0
- package/skills/arc/references/mcp.md +2 -0
|
@@ -245,7 +245,7 @@ async function registerArcPlugins(fastify, config, trackPlugin, modules) {
|
|
|
245
245
|
trackPlugin("arc-caching", opts);
|
|
246
246
|
}
|
|
247
247
|
if (config.arcPlugins?.queryCache) {
|
|
248
|
-
const { queryCachePlugin } = await import("./queryCachePlugin-
|
|
248
|
+
const { queryCachePlugin } = await import("./queryCachePlugin-DzqLN904.mjs").then((n) => n.n);
|
|
249
249
|
const opts = config.arcPlugins.queryCache === true ? {} : config.arcPlugins.queryCache;
|
|
250
250
|
const store = config.stores?.queryCache ?? new (await (import("./memory-CLXA2VeJ.mjs").then((n) => n.n))).MemoryCacheStore();
|
|
251
251
|
await fastify.register(queryCachePlugin, {
|
|
@@ -384,6 +384,134 @@ function createOptionalAuthenticate(authenticate) {
|
|
|
384
384
|
};
|
|
385
385
|
}
|
|
386
386
|
//#endregion
|
|
387
|
+
//#region src/factory/module.ts
|
|
388
|
+
/**
|
|
389
|
+
* Resolve any module-input form to a concrete `ArcModule`. A thunk is invoked
|
|
390
|
+
* (this is where a dynamic `import()` fires); a promise (or plain module) is
|
|
391
|
+
* awaited. Called once per module at the start of the bootstrap phase.
|
|
392
|
+
*/
|
|
393
|
+
async function resolveModule(input) {
|
|
394
|
+
const resolved = typeof input === "function" ? await input() : await input;
|
|
395
|
+
if (!resolved || typeof resolved !== "object" || typeof resolved.name !== "string") throw new Error("[arc] a `modules` entry resolved to something that is not an ArcModule (expected an object with a string `name`). Check dynamic-import thunks return `createXModule(deps)` (or the module object), not the namespace.");
|
|
396
|
+
return resolved;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Order modules for composition by their `dependsOn` edges — a STABLE
|
|
400
|
+
* topological sort. Called once at the start of the bootstrap phase; every
|
|
401
|
+
* subsequent phase (bootstrap, resources, afterResources, and reverse-order
|
|
402
|
+
* onClose) iterates the returned list, so a module's declared dependencies are
|
|
403
|
+
* always composed before it.
|
|
404
|
+
*
|
|
405
|
+
* "Stable" = modules with no edge between them keep their original list order,
|
|
406
|
+
* so declaring `dependsOn` on one module never silently reorders an unrelated
|
|
407
|
+
* one. Backward compatible: a `modules` array with NO `dependsOn` anywhere is
|
|
408
|
+
* returned unchanged.
|
|
409
|
+
*
|
|
410
|
+
* Fail-fast — throws (never reorders past a broken contract) on:
|
|
411
|
+
* - duplicate module names (the name is the graph key)
|
|
412
|
+
* - a `dependsOn` name not present in the composed set
|
|
413
|
+
* - a self-reference (`dependsOn` includes the module's own name)
|
|
414
|
+
* - a dependency cycle (reports the concrete `a → b → … → a` path)
|
|
415
|
+
*/
|
|
416
|
+
function orderModules(modules) {
|
|
417
|
+
const byName = /* @__PURE__ */ new Map();
|
|
418
|
+
for (const m of modules) {
|
|
419
|
+
if (byName.has(m.name)) throw new Error(`[arc] Duplicate module name "${m.name}" — composed twice; check your modules array.`);
|
|
420
|
+
byName.set(m.name, m);
|
|
421
|
+
}
|
|
422
|
+
for (const m of modules) for (const dep of m.dependsOn ?? []) {
|
|
423
|
+
if (dep === m.name) throw new Error(`[arc] module "${m.name}" dependsOn itself — remove the self-reference.`);
|
|
424
|
+
if (!byName.has(dep)) throw new Error(`[arc] module "${m.name}" dependsOn "${dep}", which is not composed. Add the "${dep}" module to createApp({ modules }) (before this one is fine — arc orders them), or drop the dependency. Composed modules: ${[...byName.keys()].join(", ") || "(none)"}.`);
|
|
425
|
+
}
|
|
426
|
+
if (modules.every((m) => !m.dependsOn || m.dependsOn.length === 0)) return [...modules];
|
|
427
|
+
const originalIndex = /* @__PURE__ */ new Map();
|
|
428
|
+
let nextIndex = 0;
|
|
429
|
+
for (const m of modules) originalIndex.set(m.name, nextIndex++);
|
|
430
|
+
const pendingDeps = new Map(modules.map((m) => [m.name, (m.dependsOn ?? []).length]));
|
|
431
|
+
const dependents = /* @__PURE__ */ new Map();
|
|
432
|
+
for (const m of modules) for (const dep of m.dependsOn ?? []) {
|
|
433
|
+
const list = dependents.get(dep);
|
|
434
|
+
if (list) list.push(m.name);
|
|
435
|
+
else dependents.set(dep, [m.name]);
|
|
436
|
+
}
|
|
437
|
+
const ordered = [];
|
|
438
|
+
const remaining = new Set(modules.map((m) => m.name));
|
|
439
|
+
while (remaining.size > 0) {
|
|
440
|
+
let pick;
|
|
441
|
+
let pickIndex = Number.POSITIVE_INFINITY;
|
|
442
|
+
for (const name of remaining) {
|
|
443
|
+
if (pendingDeps.get(name) !== 0) continue;
|
|
444
|
+
const index = originalIndex.get(name) ?? Number.POSITIVE_INFINITY;
|
|
445
|
+
if (index < pickIndex) {
|
|
446
|
+
pick = name;
|
|
447
|
+
pickIndex = index;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
if (pick === void 0) throw new Error(describeModuleCycle(remaining, byName));
|
|
451
|
+
const picked = byName.get(pick);
|
|
452
|
+
if (!picked) throw new Error(`[arc] internal: ordered module "${pick}" is missing from the index`);
|
|
453
|
+
ordered.push(picked);
|
|
454
|
+
remaining.delete(pick);
|
|
455
|
+
for (const dependent of dependents.get(pick) ?? []) pendingDeps.set(dependent, (pendingDeps.get(dependent) ?? 1) - 1);
|
|
456
|
+
}
|
|
457
|
+
return ordered;
|
|
458
|
+
}
|
|
459
|
+
/** Walk the still-unordered subgraph for one concrete cycle path. */
|
|
460
|
+
function describeModuleCycle(remaining, byName) {
|
|
461
|
+
const stack = [];
|
|
462
|
+
const onStack = /* @__PURE__ */ new Set();
|
|
463
|
+
const done = /* @__PURE__ */ new Set();
|
|
464
|
+
let cycle = null;
|
|
465
|
+
const walk = (name) => {
|
|
466
|
+
if (cycle) return;
|
|
467
|
+
stack.push(name);
|
|
468
|
+
onStack.add(name);
|
|
469
|
+
for (const dep of byName.get(name)?.dependsOn ?? []) {
|
|
470
|
+
if (!remaining.has(dep)) continue;
|
|
471
|
+
if (onStack.has(dep)) {
|
|
472
|
+
cycle = [...stack.slice(stack.indexOf(dep)), dep];
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
if (!done.has(dep)) walk(dep);
|
|
476
|
+
if (cycle) return;
|
|
477
|
+
}
|
|
478
|
+
onStack.delete(name);
|
|
479
|
+
stack.pop();
|
|
480
|
+
done.add(name);
|
|
481
|
+
};
|
|
482
|
+
for (const name of remaining) {
|
|
483
|
+
if (!done.has(name)) walk(name);
|
|
484
|
+
if (cycle) break;
|
|
485
|
+
}
|
|
486
|
+
return `[arc] module dependency cycle: ${cycle ? cycle.join(" → ") : [...remaining].join(", ")}. Modules cannot dependsOn each other circularly — break it with a shared module both point at, or wire the softer direction through an event/port instead of a hard dependsOn.`;
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Identity helper for authoring a typed module — mirrors `defineResource`.
|
|
490
|
+
* Gives inference + a single obvious construction site; does no work.
|
|
491
|
+
*
|
|
492
|
+
* `TExports` is inferred from the `bootstrap` return value, so a module
|
|
493
|
+
* author gets a typed public export for free:
|
|
494
|
+
*
|
|
495
|
+
* ```ts
|
|
496
|
+
* export const accountingModule = (deps: Deps) =>
|
|
497
|
+
* defineModule({
|
|
498
|
+
* name: "accounting",
|
|
499
|
+
* bootstrap: async () => createAccountingEngine(deps), // TExports inferred
|
|
500
|
+
* });
|
|
501
|
+
* ```
|
|
502
|
+
*/
|
|
503
|
+
function defineModule(module) {
|
|
504
|
+
return module;
|
|
505
|
+
}
|
|
506
|
+
function getModuleExports(fastify, name) {
|
|
507
|
+
const modules = fastify.arc?.modules;
|
|
508
|
+
if (!modules || !Object.hasOwn(modules, name)) {
|
|
509
|
+
const available = modules ? Object.keys(modules) : [];
|
|
510
|
+
throw new Error(`[arc] no public export recorded for module "${name}".\nA module's export is its bootstrap() return value; it is readable only AFTER that module's bootstrap ran (dependsOn / list order = init order).\nModules with recorded exports: ${available.length ? available.join(", ") : "(none)"}.`);
|
|
511
|
+
}
|
|
512
|
+
return modules[name];
|
|
513
|
+
}
|
|
514
|
+
//#endregion
|
|
387
515
|
//#region src/factory/registerResources.ts
|
|
388
516
|
function isResourcesFactory(value) {
|
|
389
517
|
return typeof value === "function";
|
|
@@ -401,15 +529,29 @@ async function registerOne(parent, resource) {
|
|
|
401
529
|
}
|
|
402
530
|
}
|
|
403
531
|
/**
|
|
404
|
-
* Execute the full resource lifecycle
|
|
405
|
-
*
|
|
406
|
-
*
|
|
407
|
-
*
|
|
532
|
+
* Execute the full resource lifecycle. The module graph is resolved + ordered
|
|
533
|
+
* by `dependsOn` (stable topological sort) once, up FRONT — before any
|
|
534
|
+
* side-effecting plugin — so a bad graph fails fast with no half-initialised
|
|
535
|
+
* infra. Every phase below iterates that order; each module phase runs BEFORE
|
|
536
|
+
* its app-level counterpart:
|
|
537
|
+
*
|
|
538
|
+
* 1. resolve + orderModules — validate the graph (dup names, missing/self
|
|
539
|
+
* deps, cycles fail fast) BEFORE side effects
|
|
540
|
+
* 2. plugins() — app infra (DB, data, webhooks)
|
|
541
|
+
* 3. module.plugins — module infra, dependsOn order, before bootstraps
|
|
542
|
+
* 4a. module.bootstrap — engine init (return value → arc.modules[name])
|
|
543
|
+
* 4b. bootstrap[] — app-level domain init
|
|
544
|
+
* 5. resources factory (if any) — resolved AFTER bootstrap, so engine-backed
|
|
408
545
|
* adapters can `await ensureEngine()` and pass
|
|
409
546
|
* live models/repos into `defineResource(...)`
|
|
410
|
-
*
|
|
411
|
-
*
|
|
412
|
-
*
|
|
547
|
+
* 5b. module resources — RESOLVED after the app factory, but PREPENDED
|
|
548
|
+
* so they REGISTER before app resources (two
|
|
549
|
+
* orderings, both intentional — see §5b)
|
|
550
|
+
* 6. module.afterResources → afterResources() — post-registration wiring
|
|
551
|
+
* 7. onReady — lifecycle hook
|
|
552
|
+
* 7b. onClose — module.onClose (reverse composition order)
|
|
553
|
+
* THEN app onClose, in ONE hook so module
|
|
554
|
+
* teardown runs before shared infra closes.
|
|
413
555
|
*/
|
|
414
556
|
async function registerResources(fastify, config) {
|
|
415
557
|
if (config.preset === "production") {
|
|
@@ -422,10 +564,37 @@ async function registerResources(fastify, config) {
|
|
|
422
564
|
strictResourceDir: true
|
|
423
565
|
};
|
|
424
566
|
}
|
|
567
|
+
const modules = orderModules(await Promise.all((config.modules ?? []).map((m) => resolveModule(m))));
|
|
425
568
|
if (config.plugins) {
|
|
426
569
|
await config.plugins(fastify);
|
|
427
570
|
fastify.log.debug("Custom plugins registered");
|
|
428
571
|
}
|
|
572
|
+
for (const m of modules) {
|
|
573
|
+
if (!m.plugins) continue;
|
|
574
|
+
try {
|
|
575
|
+
await m.plugins(fastify);
|
|
576
|
+
} catch (err) {
|
|
577
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
578
|
+
throw new Error(`[arc] module "${m.name}" plugins() threw: ${msg}`, { cause: err });
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
for (const m of modules) {
|
|
582
|
+
if (!m.bootstrap) continue;
|
|
583
|
+
let exported;
|
|
584
|
+
try {
|
|
585
|
+
exported = await m.bootstrap(fastify);
|
|
586
|
+
} catch (err) {
|
|
587
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
588
|
+
throw new Error(`[arc] module "${m.name}" bootstrap threw: ${msg}`, { cause: err });
|
|
589
|
+
}
|
|
590
|
+
if (exported !== void 0) {
|
|
591
|
+
const arc = fastify.arc;
|
|
592
|
+
if (!arc) throw new Error(`[arc] module "${m.name}" returned a public export but fastify.arc is not decorated — arcCorePlugin must register first.`);
|
|
593
|
+
if (!arc.modules) arc.modules = Object.create(null);
|
|
594
|
+
arc.modules[m.name] = exported;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
if (modules.length) fastify.log.debug(`${modules.length} module(s) composed (in dependency order): ${modules.map((m) => m.name).join(" → ")}`);
|
|
429
598
|
if (config.bootstrap?.length) {
|
|
430
599
|
for (const init of config.bootstrap) await init(fastify);
|
|
431
600
|
fastify.log.debug(`${config.bootstrap.length} bootstrap function(s) executed`);
|
|
@@ -462,6 +631,20 @@ async function registerResources(fastify, config) {
|
|
|
462
631
|
}
|
|
463
632
|
resolvedResources = discovered;
|
|
464
633
|
}
|
|
634
|
+
if (modules.length) {
|
|
635
|
+
const moduleResources = [];
|
|
636
|
+
for (const m of modules) {
|
|
637
|
+
if (!m.resources) continue;
|
|
638
|
+
try {
|
|
639
|
+
const rs = typeof m.resources === "function" ? await m.resources(fastify) : m.resources;
|
|
640
|
+
moduleResources.push(...rs);
|
|
641
|
+
} catch (err) {
|
|
642
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
643
|
+
throw new Error(`[arc] module "${m.name}" resources factory threw: ${msg}. Check the module's bootstrap ran and its adapters received booted engines.`, { cause: err });
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
if (moduleResources.length) resolvedResources = [...moduleResources, ...resolvedResources ?? []];
|
|
647
|
+
}
|
|
465
648
|
if (resolvedResources && resolvedResources.length > 0) {
|
|
466
649
|
const seen = /* @__PURE__ */ new Set();
|
|
467
650
|
for (const resource of resolvedResources) if (resource.name) {
|
|
@@ -490,6 +673,15 @@ async function registerResources(fastify, config) {
|
|
|
490
673
|
const hints = discoveryYieldedZero ? ` but yielded 0 resources. Check the path, file naming (*.resource.{ts,js,mts,mjs}), and runtime layout (src/ vs dist/). Use \`strictResourceDir: true\` to fail boot.` : "";
|
|
491
674
|
fastify.log.warn(`0 resources registered${prefix}${scanned}${hints}`);
|
|
492
675
|
}
|
|
676
|
+
for (const m of modules) {
|
|
677
|
+
if (!m.afterResources) continue;
|
|
678
|
+
try {
|
|
679
|
+
await m.afterResources(fastify);
|
|
680
|
+
} catch (err) {
|
|
681
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
682
|
+
throw new Error(`[arc] module "${m.name}" afterResources() threw: ${msg}`, { cause: err });
|
|
683
|
+
}
|
|
684
|
+
}
|
|
493
685
|
if (config.afterResources) {
|
|
494
686
|
await config.afterResources(fastify);
|
|
495
687
|
fastify.log.debug("afterResources hook executed");
|
|
@@ -500,12 +692,12 @@ async function registerResources(fastify, config) {
|
|
|
500
692
|
await onReady(fastify);
|
|
501
693
|
});
|
|
502
694
|
}
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
}
|
|
695
|
+
const closers = modules.filter((m) => m.onClose).reverse();
|
|
696
|
+
const appOnClose = config.onClose;
|
|
697
|
+
if (closers.length || appOnClose) fastify.addHook("onClose", async () => {
|
|
698
|
+
for (const m of closers) await m.onClose?.(fastify);
|
|
699
|
+
if (appOnClose) await appOnClose(fastify);
|
|
700
|
+
});
|
|
509
701
|
}
|
|
510
702
|
//#endregion
|
|
511
703
|
//#region src/factory/registerSecurity.ts
|
|
@@ -522,7 +714,8 @@ function buildRateLimitOpts(input) {
|
|
|
522
714
|
};
|
|
523
715
|
const matchesPath = compilePathMatcher(skipPaths);
|
|
524
716
|
const combined = async (req, key) => {
|
|
525
|
-
|
|
717
|
+
const path = (req.url ?? "").split("?", 1)[0] ?? "";
|
|
718
|
+
if (matchesPath(path)) return true;
|
|
526
719
|
if (typeof allowList === "function") return await allowList(req, key);
|
|
527
720
|
if (Array.isArray(allowList)) return allowList.includes(key);
|
|
528
721
|
return false;
|
|
@@ -711,7 +904,7 @@ var createApp_exports = /* @__PURE__ */ __exportAll({
|
|
|
711
904
|
createApp: () => createApp,
|
|
712
905
|
resolveLoggerConfig: () => resolveLoggerConfig
|
|
713
906
|
});
|
|
714
|
-
const MEMORY_STORE_NAMES = new Set(["memory", "memory-cache"]);
|
|
907
|
+
const MEMORY_STORE_NAMES = /* @__PURE__ */ new Set(["memory", "memory-cache"]);
|
|
715
908
|
/**
|
|
716
909
|
* Default redact paths layered into Fastify's pino logger when the host
|
|
717
910
|
* doesn't supply a `logger.redact` of their own. Covers the common token /
|
|
@@ -947,4 +1140,4 @@ const ArcFactory = {
|
|
|
947
1140
|
}
|
|
948
1141
|
};
|
|
949
1142
|
//#endregion
|
|
950
|
-
export {
|
|
1143
|
+
export { getModuleExports as a, developmentPreset as c, productionPreset as d, testingPreset as f, defineModule as i, edgePreset as l, createApp as n, orderModules as o, createApp_exports as r, resolveModule as s, ArcFactory as t, getPreset as u };
|
package/dist/docs/index.d.mts
CHANGED
package/dist/docs/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as getUserRoles } from "../types-XTApa8b6.mjs";
|
|
2
|
-
import { n as openApiPlugin, r as openapi_default, t as buildOpenApiSpec } from "../openapi-
|
|
2
|
+
import { n as openApiPlugin, r as openapi_default, t as buildOpenApiSpec } from "../openapi-Dq6RbEGK.mjs";
|
|
3
3
|
import fp from "fastify-plugin";
|
|
4
4
|
//#region src/docs/scalar.ts
|
|
5
5
|
const scalarPlugin = async (fastify, opts = {}) => {
|
package/dist/events/index.mjs
CHANGED
|
@@ -417,12 +417,13 @@ function repositoryAsOutboxStore(repository) {
|
|
|
417
417
|
},
|
|
418
418
|
async getPending(limit) {
|
|
419
419
|
const now = /* @__PURE__ */ new Date();
|
|
420
|
-
|
|
420
|
+
const result = await r.getAll({
|
|
421
421
|
filters: claimableFilter(now),
|
|
422
422
|
sort: { createdAt: 1 },
|
|
423
423
|
page: 1,
|
|
424
424
|
limit
|
|
425
|
-
})
|
|
425
|
+
});
|
|
426
|
+
return unwrapDocs(result).map((d) => d.event).filter(isWellFormed);
|
|
426
427
|
},
|
|
427
428
|
async claimPending(options) {
|
|
428
429
|
const limit = options?.limit ?? DEFAULT_CLAIM_LIMIT;
|
|
@@ -493,12 +494,13 @@ function repositoryAsOutboxStore(repository) {
|
|
|
493
494
|
}
|
|
494
495
|
},
|
|
495
496
|
async getDeadLettered(limit) {
|
|
496
|
-
|
|
497
|
+
const result = await r.getAll({
|
|
497
498
|
filters: eq("status", "dead_letter"),
|
|
498
499
|
sort: { [idField]: 1 },
|
|
499
500
|
page: 1,
|
|
500
501
|
limit
|
|
501
|
-
})
|
|
502
|
+
});
|
|
503
|
+
return unwrapDocs(result).filter((d) => isWellFormed(d.event)).map((d) => ({
|
|
502
504
|
event: d.event,
|
|
503
505
|
error: {
|
|
504
506
|
message: d.lastError?.message ?? "unknown",
|
|
@@ -513,13 +515,14 @@ function repositoryAsOutboxStore(repository) {
|
|
|
513
515
|
const cutoff = new Date(Date.now() - olderThanMs);
|
|
514
516
|
let totalDeleted = 0;
|
|
515
517
|
for (;;) {
|
|
516
|
-
const
|
|
518
|
+
const result = await r.getAll({
|
|
517
519
|
filters: and(eq("status", "delivered"), lte("deliveredAt", cutoff)),
|
|
518
520
|
sort: { deliveredAt: 1 },
|
|
519
521
|
page: 1,
|
|
520
522
|
limit: DEFAULT_PURGE_BATCH,
|
|
521
523
|
select: idField
|
|
522
|
-
})
|
|
524
|
+
});
|
|
525
|
+
const batch = unwrapDocs(result);
|
|
523
526
|
if (batch.length === 0) break;
|
|
524
527
|
const ids = batch.map((d) => d[idField]);
|
|
525
528
|
const res = await r.deleteMany(anyOf(idField, ids));
|
package/dist/factory/index.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as getModuleExports, c as LoadResourcesOptions, d as loadResources, i as defineModule, l as ResourceLike, n as ArcModuleInput, o as orderModules, r as ArcModuleRegistry, s as resolveModule, t as ArcModule, u as ResourceModule } from "../module-JYH9V0I8.mjs";
|
|
2
|
+
import { a as CustomPluginAuthOption, c as RawBodyOptions, d as preloadResourcesAsync, i as CustomAuthenticatorOption, l as UnderPressureOptions, n as BetterAuthOption, o as JwtAuthOption, r as CreateAppOptions, s as MultipartOptions, t as AuthOption, u as preloadResources } from "../types-BHMKlMBU.mjs";
|
|
2
3
|
import { FastifyInstance, FastifyServerOptions } from "fastify";
|
|
3
4
|
|
|
4
5
|
//#region src/factory/createApp.d.ts
|
|
@@ -95,4 +96,4 @@ declare const edgePreset: Partial<CreateAppOptions>;
|
|
|
95
96
|
*/
|
|
96
97
|
declare function getPreset(name: "production" | "development" | "testing" | "edge"): Partial<CreateAppOptions>;
|
|
97
98
|
//#endregion
|
|
98
|
-
export { ArcFactory, type AuthOption, type BetterAuthOption, type CreateAppOptions, type CustomAuthenticatorOption, type CustomPluginAuthOption, type FetchHandlerOptions, type JwtAuthOption, type LoadResourcesOptions, type MultipartOptions, type RawBodyOptions, type ResourceLike, type ResourceModule, type UnderPressureOptions, createApp, developmentPreset, edgePreset, getPreset, loadResources, preloadResources, preloadResourcesAsync, productionPreset, testingPreset, toFetchHandler };
|
|
99
|
+
export { ArcFactory, type ArcModule, type ArcModuleInput, type ArcModuleRegistry, type AuthOption, type BetterAuthOption, type CreateAppOptions, type CustomAuthenticatorOption, type CustomPluginAuthOption, type FetchHandlerOptions, type JwtAuthOption, type LoadResourcesOptions, type MultipartOptions, type RawBodyOptions, type ResourceLike, type ResourceModule, type UnderPressureOptions, createApp, defineModule, developmentPreset, edgePreset, getModuleExports, getPreset, loadResources, orderModules, preloadResources, preloadResourcesAsync, productionPreset, resolveModule, testingPreset, toFetchHandler };
|
package/dist/factory/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as preloadResourcesAsync, t as preloadResources } from "../preloadResources-CHw3_oA_.mjs";
|
|
2
|
-
import { a as
|
|
2
|
+
import { a as getModuleExports, c as developmentPreset, d as productionPreset, f as testingPreset, i as defineModule, l as edgePreset, n as createApp, o as orderModules, s as resolveModule, t as ArcFactory, u as getPreset } from "../createApp-D6uwzCKu.mjs";
|
|
3
3
|
import { t as loadResources } from "../loadResources-B8UmpITt.mjs";
|
|
4
4
|
//#region src/factory/edge.ts
|
|
5
5
|
/**
|
|
@@ -47,4 +47,4 @@ function toFetchHandler(app, options = {}) {
|
|
|
47
47
|
};
|
|
48
48
|
}
|
|
49
49
|
//#endregion
|
|
50
|
-
export { ArcFactory, createApp, developmentPreset, edgePreset, getPreset, loadResources, preloadResources, preloadResourcesAsync, productionPreset, testingPreset, toFetchHandler };
|
|
50
|
+
export { ArcFactory, createApp, defineModule, developmentPreset, edgePreset, getModuleExports, getPreset, loadResources, orderModules, preloadResources, preloadResourcesAsync, productionPreset, resolveModule, testingPreset, toFetchHandler };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { bn as HookSystem, z as ResourceRegistry } from "./index-
|
|
1
|
+
import { bn as HookSystem, z as ResourceRegistry } from "./index-_--GyzcO.mjs";
|
|
2
2
|
import { t as ExternalOpenApiPaths } from "./externalPaths-BE6wFpYv.mjs";
|
|
3
|
+
import { r as ArcModuleRegistry } from "./module-JYH9V0I8.mjs";
|
|
3
4
|
import { FastifyPluginAsync } from "fastify";
|
|
4
5
|
|
|
5
6
|
//#region src/core/arcCorePlugin.d.ts
|
|
@@ -28,6 +29,16 @@ interface ArcCore {
|
|
|
28
29
|
externalOpenApiPaths: ExternalOpenApiPaths[];
|
|
29
30
|
/** Registered plugins for introspection */
|
|
30
31
|
plugins: Map<string, PluginMeta>;
|
|
32
|
+
/**
|
|
33
|
+
* Module public exports — `bootstrap()` return values keyed by module name
|
|
34
|
+
* (see `src/factory/module.ts`). Read via `getModuleExports(fastify, name)`:
|
|
35
|
+
* augment `ArcModuleRegistry` once and the name infers the export type;
|
|
36
|
+
* otherwise pass it inline. `Partial<ArcModuleRegistry>` gives augmented
|
|
37
|
+
* apps typed direct access (`fastify.arc.modules.order`), while the
|
|
38
|
+
* `Record<string, unknown>` intersection keeps un-augmented reads open.
|
|
39
|
+
* Populated lazily by `registerResources` — absent until a module exports.
|
|
40
|
+
*/
|
|
41
|
+
modules?: Partial<ArcModuleRegistry> & Record<string, unknown>;
|
|
31
42
|
}
|
|
32
43
|
declare const arcCorePlugin: FastifyPluginAsync<ArcCorePluginOptions>;
|
|
33
44
|
declare const _default: FastifyPluginAsync<ArcCorePluginOptions>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as pluralize } from "./pluralize-
|
|
1
|
+
import { t as pluralize } from "./pluralize-BhrgwZb9.mjs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
4
|
//#region src/cli/commands/generate/name-helpers.ts
|
|
@@ -601,9 +601,10 @@ async function generate(type, args) {
|
|
|
601
601
|
if (!type) throw new Error("Missing type argument\nUsage: arc generate <resource|controller|model|repository|schemas> <name>");
|
|
602
602
|
const [name, ...restArgs] = args;
|
|
603
603
|
if (!name) throw new Error("Missing name argument\nUsage: arc generate <type> <name>\nExample: arc generate resource product");
|
|
604
|
+
if (!/^[A-Za-z][A-Za-z0-9-]*$/.test(name)) throw new Error(`Invalid name "${name}". Use kebab-case: a letter followed by letters, digits, or hyphens (e.g. 'product', 'order-line'). No slashes, dots, spaces, or path segments.`);
|
|
604
605
|
const capitalizedName = toPascalCase(name);
|
|
605
606
|
const lowerName = name.toLowerCase();
|
|
606
|
-
if ((type === "resource" || type === "r" || type === "model" || type === "m") && new Set([
|
|
607
|
+
if ((type === "resource" || type === "r" || type === "model" || type === "m") && (/* @__PURE__ */ new Set([
|
|
607
608
|
"user",
|
|
608
609
|
"session",
|
|
609
610
|
"account",
|
|
@@ -614,7 +615,7 @@ async function generate(type, args) {
|
|
|
614
615
|
"team",
|
|
615
616
|
"team-member",
|
|
616
617
|
"apikey"
|
|
617
|
-
]).has(lowerName)) {
|
|
618
|
+
])).has(lowerName)) {
|
|
618
619
|
console.warn(`\n[arc generate] "${lowerName}" is a Better Auth-owned collection.\nBetter Auth's organization/admin/bearer plugins write this collection directly,\nso generating a parallel arc model would create a duplicate registration.\n\nRecommended pattern:\n import { createBetterAuthOverlay } from '@classytic/mongokit/better-auth';\n const adapter = await createBetterAuthOverlay({\n auth, mongoose, collection: '${lowerName}',\n });\n // ...then \`defineResource({ name: '${lowerName}', adapter, ... })\` reads\n // BA's collection through arc with full pagination/filters/permissions.\n\nAborting. Re-run with a different name if you need a separate domain model.\n`);
|
|
619
620
|
return;
|
|
620
621
|
}
|
package/dist/hooks/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Cn as afterDelete, Dn as beforeUpdate, En as beforeDelete, On as createHookSystem, Sn as afterCreate, Tn as beforeCreate, _n as HookOperation, bn as HookSystem, gn as HookHandler, hn as HookContext, kn as defineHook, mn as DefineHookOptions, vn as HookPhase, wn as afterUpdate, xn as HookSystemOptions, yn as HookRegistration } from "../index-
|
|
1
|
+
import { Cn as afterDelete, Dn as beforeUpdate, En as beforeDelete, On as createHookSystem, Sn as afterCreate, Tn as beforeCreate, _n as HookOperation, bn as HookSystem, gn as HookHandler, hn as HookContext, kn as defineHook, mn as DefineHookOptions, vn as HookPhase, wn as afterUpdate, xn as HookSystemOptions, yn as HookRegistration } from "../index-_--GyzcO.mjs";
|
|
2
2
|
export { type DefineHookOptions, type HookContext, type HookHandler, type HookOperation, type HookPhase, type HookRegistration, HookSystem, type HookSystemOptions, afterCreate, afterDelete, afterUpdate, beforeCreate, beforeDelete, beforeUpdate, createHookSystem, defineHook };
|
|
@@ -387,7 +387,7 @@ const idempotencyPlugin = async (fastify, opts = {}) => {
|
|
|
387
387
|
const statusCode = reply.statusCode;
|
|
388
388
|
if (statusCode < 200 || statusCode >= 300) return payload;
|
|
389
389
|
const headersToCache = {};
|
|
390
|
-
const excludeHeaders = new Set([
|
|
390
|
+
const excludeHeaders = /* @__PURE__ */ new Set([
|
|
391
391
|
"content-length",
|
|
392
392
|
"transfer-encoding",
|
|
393
393
|
"connection",
|
|
@@ -669,6 +669,11 @@ declare function fullPublic<TDoc = Record<string, unknown>>(overrides?: Permissi
|
|
|
669
669
|
/**
|
|
670
670
|
* Read-only: list + get authenticated, write operations denied.
|
|
671
671
|
* Useful for computed/derived resources.
|
|
672
|
+
*
|
|
673
|
+
* Writes carry an explicit `denyAll` check — an omitted CRUD permission
|
|
674
|
+
* mounts the route with NO gate (public-by-omission), so leaving
|
|
675
|
+
* create/update/delete undefined here would expose unauthenticated writes.
|
|
676
|
+
* Hosts that disable write routes entirely (`disabledRoutes`) are unaffected.
|
|
672
677
|
*/
|
|
673
678
|
declare function readOnly<TDoc = Record<string, unknown>>(overrides?: PermissionOverrides<TDoc>): ResourcePermissions<TDoc>;
|
|
674
679
|
//#endregion
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as RequestContext, Et as AggregationConfig, F as FastifyWithDecorators, H as ActionDefinition, K as ArcFieldRule, L as RequestWithExtras, T as CrudRouterOptions, V as ResourceDefinition, bt as IControllerResponse, ht as RouteSchemaOptions, pt as RouteMcpConfig, q as CrudController, qt as AnyRecord, st as ResourceConfig, xt as IRequestContext, yt as IController } from "./index-
|
|
1
|
+
import { C as RequestContext, Et as AggregationConfig, F as FastifyWithDecorators, H as ActionDefinition, K as ArcFieldRule, L as RequestWithExtras, T as CrudRouterOptions, V as ResourceDefinition, bt as IControllerResponse, ht as RouteSchemaOptions, pt as RouteMcpConfig, q as CrudController, qt as AnyRecord, st as ResourceConfig, xt as IRequestContext, yt as IController } from "./index-_--GyzcO.mjs";
|
|
2
2
|
import { i as RequestScope } from "./types-LNebCoJx.mjs";
|
|
3
3
|
import { c as PermissionCheck } from "./fields-C7ahdGYf.mjs";
|
|
4
4
|
import { FastifyReply, FastifyRequest, RouteHandlerMethod } from "fastify";
|
|
@@ -2467,6 +2467,25 @@ interface RouteDefinition {
|
|
|
2467
2467
|
* pipeline entirely.
|
|
2468
2468
|
*/
|
|
2469
2469
|
readonly fieldWrite?: boolean;
|
|
2470
|
+
/**
|
|
2471
|
+
* Per-route rate limit. A custom route is its own Fastify route, so this
|
|
2472
|
+
* overrides the resource-level `rateLimit` for THIS endpoint only:
|
|
2473
|
+
*
|
|
2474
|
+
* - omitted → inherit the resource-level limit (or app default)
|
|
2475
|
+
* - `false` → disable rate limiting on this route
|
|
2476
|
+
* - `{ max, timeWindow }` → apply this specific limit
|
|
2477
|
+
*
|
|
2478
|
+
* Requires `@fastify/rate-limit` registered (arc's factory wires it by
|
|
2479
|
+
* default). Use for an expensive `/export` or an auth-sensitive `/reset`
|
|
2480
|
+
* that needs a tighter cap than the resource's read-heavy CRUD, or `false`
|
|
2481
|
+
* on an internal health/webhook route that must not be throttled.
|
|
2482
|
+
*
|
|
2483
|
+
* Note: this is per-route because each custom route is a distinct endpoint.
|
|
2484
|
+
* `actions` share ONE `POST /:id/action` mount by design, so a per-ACTION
|
|
2485
|
+
* limit can't be expressed here — throttle a specific action by promoting
|
|
2486
|
+
* it to a dedicated `routes:` entry, or rely on the resource-level limit.
|
|
2487
|
+
*/
|
|
2488
|
+
readonly rateLimit?: RateLimitConfig | false;
|
|
2470
2489
|
/**
|
|
2471
2490
|
* Fastify route schema. Each slot (`body`, `querystring`, `params`,
|
|
2472
2491
|
* `headers`, `response[status]`) accepts a plain JSON Schema object
|
|
@@ -2504,7 +2523,15 @@ interface RouteDefinition {
|
|
|
2504
2523
|
* ID, action-specific data, and the request.
|
|
2505
2524
|
*/
|
|
2506
2525
|
type ActionHandlerFn = (id: string, data: Record<string, unknown>, req: RequestWithExtras) => Promise<unknown>;
|
|
2507
|
-
/**
|
|
2526
|
+
/**
|
|
2527
|
+
* Full action configuration with handler, permissions, and schema.
|
|
2528
|
+
*
|
|
2529
|
+
* Rate limiting is intentionally NOT per-action: every action shares one
|
|
2530
|
+
* `POST /:id/action` (or `POST /action`) mount, so Fastify's per-route limit
|
|
2531
|
+
* can't distinguish them. Actions inherit the resource-level `rateLimit`; to
|
|
2532
|
+
* throttle a specific operation, promote it to a `routes:` entry (which
|
|
2533
|
+
* supports `RouteDefinition.rateLimit`).
|
|
2534
|
+
*/
|
|
2508
2535
|
interface ActionDefinition {
|
|
2509
2536
|
readonly handler: ActionHandlerFn;
|
|
2510
2537
|
/** Per-action permission (overrides resource-level `actionPermissions`) */
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { $t as UserOrganization, A as RequestIdOptions, An as ArcCreateResult, At as AggregationMaterializedResult, B as defineResource, C as RequestContext, Ct as AggMeasureInput, D as HealthCheck, Dt as AggregationDateRangeRequirement, E as GracefulShutdownOptions, Et as AggregationConfig, F as FastifyWithDecorators, Fn as BaseControllerOptions, Ht as AuthPluginOptions, In as ControllerConfigurableOptions, J as CrudRouteKey, Jt as ApiResponse, L as RequestWithExtras, Ln as ControllerConstructionOptions, Mn as ArcGetResult, Mt as AggregationsMap, N as FastifyRequestExtras, Nn as ArcListResult, O as HealthOptions, Ot as AggregationIndexHint, P as FastifyWithAuth, Pn as ArcUpdateResult, Q as MiddlewareConfig, Rn as ListResult, S as QueryParserInterface, St as RouteHandler, T as CrudRouterOptions, Tt as AggregationCacheConfig, V as ResourceDefinition, X as EventDefinition, Xt as JWTPayload, Y as CrudSchemas, Yt as ArcRequest, Z as FieldRule, _t as ControllerLike, a as InferAdapterDoc, an as SlugExt, bt as IControllerResponse, c as TypedController, cn as BulkMixin, d as PaginationResult, en as BaseController, f as IntrospectionData, g as ArcInternalMetadata, h as ResourceMetadata, ht as RouteSchemaOptions, i as ValidationResult, in as TreeMixin, it as RateLimitConfig, jn as ArcDeleteResult, jt as AggregationRateLimit, k as IntrospectionPluginOptions, kt as AggregationMaterializedContext, l as TypedRepository, ln as BaseCrudController, m as RegistryStats, n as ConfigError, nn as SoftDeleteMixin, o as InferDocType, on as SlugMixin, p as RegistryEntry, q as CrudController, qt as AnyRecord, r as ValidateOptions, rn as TreeExt, rt as PresetResult, s as InferResourceDoc, sn as BulkExt, st as ResourceConfig, t as RouteHandlerMethod, tn as SoftDeleteExt, tt as PresetFunction, u as TypedResourceConfig, w as ServiceContext, wt as AggMeasureShorthand, xt as IRequestContext, y as OwnershipCheck, yt as IController } from "./index-
|
|
1
|
+
import { $t as UserOrganization, A as RequestIdOptions, An as ArcCreateResult, At as AggregationMaterializedResult, B as defineResource, C as RequestContext, Ct as AggMeasureInput, D as HealthCheck, Dt as AggregationDateRangeRequirement, E as GracefulShutdownOptions, Et as AggregationConfig, F as FastifyWithDecorators, Fn as BaseControllerOptions, Ht as AuthPluginOptions, In as ControllerConfigurableOptions, J as CrudRouteKey, Jt as ApiResponse, L as RequestWithExtras, Ln as ControllerConstructionOptions, Mn as ArcGetResult, Mt as AggregationsMap, N as FastifyRequestExtras, Nn as ArcListResult, O as HealthOptions, Ot as AggregationIndexHint, P as FastifyWithAuth, Pn as ArcUpdateResult, Q as MiddlewareConfig, Rn as ListResult, S as QueryParserInterface, St as RouteHandler, T as CrudRouterOptions, Tt as AggregationCacheConfig, V as ResourceDefinition, X as EventDefinition, Xt as JWTPayload, Y as CrudSchemas, Yt as ArcRequest, Z as FieldRule, _t as ControllerLike, a as InferAdapterDoc, an as SlugExt, bt as IControllerResponse, c as TypedController, cn as BulkMixin, d as PaginationResult, en as BaseController, f as IntrospectionData, g as ArcInternalMetadata, h as ResourceMetadata, ht as RouteSchemaOptions, i as ValidationResult, in as TreeMixin, it as RateLimitConfig, jn as ArcDeleteResult, jt as AggregationRateLimit, k as IntrospectionPluginOptions, kt as AggregationMaterializedContext, l as TypedRepository, ln as BaseCrudController, m as RegistryStats, n as ConfigError, nn as SoftDeleteMixin, o as InferDocType, on as SlugMixin, p as RegistryEntry, q as CrudController, qt as AnyRecord, r as ValidateOptions, rn as TreeExt, rt as PresetResult, s as InferResourceDoc, sn as BulkExt, st as ResourceConfig, t as RouteHandlerMethod, tn as SoftDeleteExt, tt as PresetFunction, u as TypedResourceConfig, w as ServiceContext, wt as AggMeasureShorthand, xt as IRequestContext, y as OwnershipCheck, yt as IController } from "./index-_--GyzcO.mjs";
|
|
2
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-C7ahdGYf.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-
|
|
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-
|
|
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-DUa8WHz3.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-CdFkIMEd.mjs";
|
|
5
5
|
import { a as NotFoundError, d as ValidationError, f as createDomainError, i as ForbiddenError, t as ArcError, u as UnauthorizedError } from "./errors-DOHkjQlD.mjs";
|
|
6
6
|
|
|
7
7
|
//#region src/index.d.ts
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { a as DEFAULT_SORT, c as HOOK_OPERATIONS, d as MAX_REGEX_LENGTH, f as MAX_SEARCH_LENGTH, h as SYSTEM_FIELDS, i as DEFAULT_MAX_LIMIT, l as HOOK_PHASES, m as RESERVED_QUERY_PARAMS, n as DEFAULT_ID_FIELD, o as DEFAULT_TENANT_FIELD, p as MUTATION_OPERATIONS, r as DEFAULT_LIMIT, s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS, u as MAX_FILTER_DEPTH } from "./constants-
|
|
1
|
+
import { a as DEFAULT_SORT, c as HOOK_OPERATIONS, d as MAX_REGEX_LENGTH, f as MAX_SEARCH_LENGTH, h as SYSTEM_FIELDS, i as DEFAULT_MAX_LIMIT, l as HOOK_PHASES, m as RESERVED_QUERY_PARAMS, n as DEFAULT_ID_FIELD, o as DEFAULT_TENANT_FIELD, p as MUTATION_OPERATIONS, r as DEFAULT_LIMIT, s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS, u as MAX_FILTER_DEPTH } from "./constants-DNre0wRg.mjs";
|
|
2
2
|
import { d as createDomainError, i as NotFoundError, l as UnauthorizedError, r as ForbiddenError, t as ArcError, u as ValidationError } from "./errors-DkO8Nk6-.mjs";
|
|
3
|
-
import { a as BulkMixin, i as SlugMixin, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, t as BaseController } from "./BaseController-
|
|
4
|
-
import { a as
|
|
5
|
-
import {
|
|
6
|
-
import { l as getControllerScope } from "./actionPermissions-
|
|
3
|
+
import { a as BulkMixin, i as SlugMixin, n as TreeMixin, o as BaseCrudController, r as SoftDeleteMixin, t as BaseController } from "./BaseController-D-MHZ27_.mjs";
|
|
4
|
+
import { C as requireAuth, D as when, F as applyFieldWritePermissions, I as fields, P as applyFieldReadPermissions, T as requireRoles, _ as requireTeamMembership, a as presets_exports, b as anyOf, c as readOnly, d as createOrgPermissions, f as requireOrgInScope, g as requireServiceScope, h as requireScopeContext, i as ownerWithAdminBypass, m as requireOrgRole, n as authenticated, o as publicRead, p as requireOrgMembership, r as fullPublic, s as publicReadAdminWrite, t as adminOnly, u as createDynamicPermissionMatrix, v as allOf, w as requireOwnership, x as denyAll, y as allowPublic } from "./permissions-CgbOLJZG.mjs";
|
|
5
|
+
import { a as defineResource, i as defineResourceVariants, o as ResourceDefinition, s as defineAction, u as defineAggregation } from "./core-CWhyGkiM.mjs";
|
|
6
|
+
import { l as getControllerScope } from "./actionPermissions-C9RMiIpc.mjs";
|
|
7
7
|
//#region src/index.ts
|
|
8
|
-
const version = "2.
|
|
8
|
+
const version = "2.20.0";
|
|
9
9
|
//#endregion
|
|
10
10
|
export { ArcError, BaseController, BaseCrudController, BulkMixin, CRUD_OPERATIONS, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, ForbiddenError, HOOK_OPERATIONS, HOOK_PHASES, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, NotFoundError, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, SlugMixin, SoftDeleteMixin, TreeMixin, UnauthorizedError, ValidationError, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, authenticated, createDomainError, createDynamicPermissionMatrix, createOrgPermissions, defineAction, defineAggregation, defineResource, defineResourceVariants, denyAll, fields, fullPublic, getControllerScope, ownerWithAdminBypass, presets_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAuth, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, version, when };
|