@classytic/arc 2.9.1 → 2.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -90
- package/dist/{BaseController-Vu2yc56T.mjs → BaseController-CbKKIflT.mjs} +8 -44
- package/dist/{ResourceRegistry-Dq3_zBQP.mjs → ResourceRegistry-BPd6NQDm.mjs} +1 -1
- package/dist/adapters/index.d.mts +3 -3
- package/dist/adapters/index.mjs +2 -2
- package/dist/{adapters-BBqAVvPK.mjs → adapters-BXY4i-hw.mjs} +210 -41
- package/dist/audit/index.d.mts +38 -3
- package/dist/audit/index.mjs +41 -7
- package/dist/auth/index.d.mts +4 -4
- package/dist/auth/index.mjs +5 -5
- package/dist/auth/redis-session.d.mts +1 -1
- package/dist/cache/index.d.mts +17 -15
- package/dist/cache/index.mjs +15 -14
- package/dist/{caching-CjybdRwx.mjs → caching-CBpK_SCM.mjs} +8 -3
- package/dist/cli/commands/describe.mjs +1 -1
- 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 +1 -1
- package/dist/core/index.d.mts +2 -2
- package/dist/core/index.mjs +3 -4
- package/dist/{defineResource-C__jkwvs.mjs → core-CcR01lup.mjs} +44 -12
- package/dist/{createActionRouter-DH1YFL9m.mjs → createActionRouter-Bp_5c_2b.mjs} +1 -1
- package/dist/{createApp-CBJUJKGP.mjs → createApp-BuvPma24.mjs} +14 -14
- package/dist/docs/index.d.mts +2 -2
- package/dist/docs/index.mjs +2 -2
- package/dist/{elevation-DxQ6ACbt.mjs → elevation-C7hgL_aI.mjs} +2 -2
- package/dist/{errorHandler-CZDW4EXS.mjs → errorHandler-Bb49BvPD.mjs} +1 -1
- package/dist/{errorHandler-DixGcttC.d.mts → errorHandler-DRQ3EqfL.d.mts} +1 -1
- package/dist/{eventPlugin-BxvaCIZF.d.mts → eventPlugin-CxWgpd6K.d.mts} +1 -1
- package/dist/{eventPlugin-Dl7MoVWH.mjs → eventPlugin-DCUjuiQT.mjs} +1 -1
- package/dist/events/index.d.mts +8 -5
- package/dist/events/index.mjs +34 -17
- package/dist/events/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis.d.mts +1 -1
- package/dist/factory/index.d.mts +1 -1
- package/dist/factory/index.mjs +2 -2
- package/dist/{types-DZi1aYhm.d.mts → fields-Lo1VUDpt.d.mts} +121 -1
- package/dist/{filesUpload-q8oHt--L.mjs → filesUpload-t21LS-py.mjs} +2 -2
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.mjs +1 -1
- package/dist/idempotency/index.d.mts +7 -4
- package/dist/idempotency/index.mjs +9 -11
- package/dist/idempotency/redis.d.mts +1 -1
- package/dist/{index-Cibkchnx.d.mts → index-8qw4y6ff.d.mts} +2 -2
- package/dist/{index-C-xjcA6F.d.mts → index-ChIw3776.d.mts} +283 -408
- package/dist/{interface-YrWsmKqE.d.mts → index-Cl0uoKd5.d.mts} +1885 -2741
- package/dist/{index-CtGKT0lf.d.mts → index-DStwgFUK.d.mts} +81 -7
- package/dist/index.d.mts +7 -8
- package/dist/index.mjs +11 -12
- package/dist/integrations/event-gateway.d.mts +1 -1
- package/dist/integrations/event-gateway.mjs +1 -1
- 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/interface-D218ikEo.d.mts +77 -0
- package/dist/{memory-BFAYkf8H.mjs → memory-B5Amv9A1.mjs} +23 -8
- package/dist/{openapi-CXuTG1M9.mjs → openapi-B5F8AddX.mjs} +2 -2
- package/dist/org/index.d.mts +2 -2
- package/dist/permissions/index.d.mts +3 -4
- package/dist/permissions/index.mjs +5 -5
- package/dist/{permissions-oNZawnkR.mjs → permissions-Dk6mshja.mjs} +315 -397
- package/dist/plugins/index.d.mts +4 -4
- package/dist/plugins/index.mjs +12 -14
- package/dist/plugins/response-cache.mjs +1 -1
- package/dist/plugins/tracing-entry.d.mts +1 -1
- package/dist/plugins/tracing-entry.mjs +1 -1
- package/dist/presets/filesUpload.d.mts +3 -3
- package/dist/presets/filesUpload.mjs +1 -1
- package/dist/presets/index.d.mts +1 -1
- package/dist/presets/index.mjs +2 -2
- package/dist/presets/multiTenant.d.mts +1 -1
- package/dist/presets/multiTenant.mjs +1 -1
- package/dist/presets/search.d.mts +91 -4
- package/dist/presets/search.mjs +1 -1
- package/dist/{presets-hM4WhNWY.mjs → presets-fLJVXdVn.mjs} +1 -1
- package/dist/{queryCachePlugin-CnTZZTC5.d.mts → queryCachePlugin-BKbWjgDG.d.mts} +1 -1
- package/dist/{queryCachePlugin-DbUVroUG.mjs → queryCachePlugin-DQCEfJis.mjs} +8 -8
- package/dist/{queryParser-Cs-6SHQK.mjs → queryParser-DBqBB6AC.mjs} +1 -1
- package/dist/{redis-MXLp1oOf.d.mts → redis-DqyeggCa.d.mts} +1 -1
- package/dist/{redis-stream-Bz-4q96t.d.mts → redis-stream-CakIQmwR.d.mts} +1 -1
- package/dist/registry/index.d.mts +1 -1
- package/dist/registry/index.mjs +2 -2
- package/dist/{resourceToTools-C3cWymnW.mjs → resourceToTools-BElv3xPT.mjs} +3 -3
- package/dist/scope/index.d.mts +1 -1
- package/dist/scope/index.mjs +2 -2
- package/dist/{sse-CJpt7LGI.mjs → sse-yBCgOLGu.mjs} +1 -1
- package/dist/testing/index.d.mts +6 -5
- package/dist/testing/index.mjs +8 -10
- package/dist/testing/storageContract.d.mts +1 -1
- package/dist/types/index.d.mts +4 -4
- package/dist/types/index.mjs +1 -31
- package/dist/types/storage.d.mts +1 -1
- package/dist/{types-CoSzA-s-.d.mts → types-Btdda02s.d.mts} +1 -1
- package/dist/{types-CunEX4UX.d.mts → types-Co8k3NyS.d.mts} +9 -9
- package/dist/types-Csi3FLfq.mjs +27 -0
- package/dist/utils/index.d.mts +207 -3
- package/dist/utils/index.mjs +3 -4
- package/dist/{utils-B7FuRr9w.mjs → utils-B2fNOD_i.mjs} +285 -2
- package/dist/{versioning-Cm8qoFDg.mjs → versioning-C2U_bLY0.mjs} +3 -5
- package/package.json +15 -18
- package/skills/arc/SKILL.md +7 -11
- package/skills/arc/references/production.md +0 -41
- package/dist/circuitBreaker-CvXkjfrW.d.mts +0 -206
- package/dist/circuitBreaker-l18oRgL5.mjs +0 -284
- package/dist/core-DNncu0xF.mjs +0 -34
- package/dist/dynamic/index.d.mts +0 -93
- package/dist/dynamic/index.mjs +0 -122
- package/dist/fields-BC7zcmI9.d.mts +0 -121
- package/dist/interface-DplgQO2e.d.mts +0 -54
- package/dist/policies/index.d.mts +0 -425
- package/dist/policies/index.mjs +0 -318
- package/dist/rpc/index.d.mts +0 -90
- package/dist/rpc/index.mjs +0 -248
- /package/dist/{EventTransport-CqZ8FyM_.d.mts → EventTransport-CUw5NNWe.d.mts} +0 -0
- /package/dist/{HookSystem-BjFu7zf1.mjs → HookSystem-BNYKnrXF.mjs} +0 -0
- /package/dist/{applyPermissionResult-bqGpo9ML.mjs → applyPermissionResult-QhV1Pa-g.mjs} +0 -0
- /package/dist/{betterAuthOpenApi--rdY15Ld.mjs → betterAuthOpenApi-BBRVhjQN.mjs} +0 -0
- /package/dist/{constants-Cxde4rpC.mjs → constants-BhY1OHoH.mjs} +0 -0
- /package/dist/{elevation-B6S5csVA.d.mts → elevation-C5SwtkAn.d.mts} +0 -0
- /package/dist/{errors-BI8kEKsO.d.mts → errors-CCSsMpXE.d.mts} +0 -0
- /package/dist/{errors-CqWnSqM-.mjs → errors-D5c-5BJL.mjs} +0 -0
- /package/dist/{externalPaths-Bapitwvd.d.mts → externalPaths-BQ8QijNH.d.mts} +0 -0
- /package/dist/{fields-CU6FlaDV.mjs → fields-bxkeltzz.mjs} +0 -0
- /package/dist/{interface-B-pe8fhj.d.mts → interface-CSbZdv_3.d.mts} +0 -0
- /package/dist/{loadResources-Bksk8ydA.mjs → loadResources-BAzJItAJ.mjs} +0 -0
- /package/dist/{logger-CDjpjySd.mjs → logger-DLg8-Ueg.mjs} +0 -0
- /package/dist/{metrics-TuOmguhi.mjs → metrics-DuhiSEZI.mjs} +0 -0
- /package/dist/{pluralize-CWP6MB39.mjs → pluralize-A0tWEl1K.mjs} +0 -0
- /package/dist/{registry-B0Wl7uVV.mjs → registry-B3lRFBWo.mjs} +0 -0
- /package/dist/{replyHelpers-BLojtuvR.mjs → replyHelpers-CXtJDAZ0.mjs} +0 -0
- /package/dist/{requestContext-DYtmNpm5.mjs → requestContext-xHIKedG6.mjs} +0 -0
- /package/dist/{sessionManager-D-oNWHz3.d.mts → sessionManager-BkzVU8h2.d.mts} +0 -0
- /package/dist/{storage-BwGQXUpd.d.mts → storage-CVk_SEn2.d.mts} +0 -0
- /package/dist/{store-helpers-DFiZl5TL.mjs → store-helpers-ZCSMJJAX.mjs} +0 -0
- /package/dist/{tracing-xqXzWeaf.d.mts → tracing-65B51Dw3.d.mts} +0 -0
- /package/dist/{types-ZUu_h0jp.mjs → types-DV9WDfeg.mjs} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as EventLogger, n as DomainEvent, o as EventTransport, r as EventHandler } from "./EventTransport-
|
|
1
|
+
import { i as EventLogger, n as DomainEvent, o as EventTransport, r as EventHandler } from "./EventTransport-CUw5NNWe.mjs";
|
|
2
2
|
import { FastifyPluginAsync } from "fastify";
|
|
3
3
|
|
|
4
4
|
//#region src/events/defineEvent.d.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
|
|
2
|
-
import { t as requestContext } from "./requestContext-
|
|
2
|
+
import { t as requestContext } from "./requestContext-xHIKedG6.mjs";
|
|
3
3
|
import fp from "fastify-plugin";
|
|
4
4
|
//#region src/events/EventTransport.ts
|
|
5
5
|
/**
|
package/dist/events/index.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as EventMeta, c as MemoryEventTransportOptions, d as createEvent, i as EventLogger, l as PublishManyResult, n as DomainEvent, o as EventTransport, r as EventHandler, s as MemoryEventTransport, t as DeadLetteredEvent, u as createChildEvent } from "../EventTransport-
|
|
3
|
-
import { a as withRetry, c as EventDefinitionOutput, d as EventSchema, f as ValidationResult, i as createDeadLetterPublisher, l as EventRegistry, m as defineEvent, n as eventPlugin, o as CustomValidator, p as createEventRegistry, r as RetryOptions, s as EventDefinitionInput, t as EventPluginOptions, u as EventRegistryOptions } from "../eventPlugin-
|
|
1
|
+
import { kt as RepositoryLike } from "../index-Cl0uoKd5.mjs";
|
|
2
|
+
import { a as EventMeta, c as MemoryEventTransportOptions, d as createEvent, i as EventLogger, l as PublishManyResult, n as DomainEvent, o as EventTransport, r as EventHandler, s as MemoryEventTransport, t as DeadLetteredEvent, u as createChildEvent } from "../EventTransport-CUw5NNWe.mjs";
|
|
3
|
+
import { a as withRetry, c as EventDefinitionOutput, d as EventSchema, f as ValidationResult, i as createDeadLetterPublisher, l as EventRegistry, m as defineEvent, n as eventPlugin, o as CustomValidator, p as createEventRegistry, r as RetryOptions, s as EventDefinitionInput, t as EventPluginOptions, u as EventRegistryOptions } from "../eventPlugin-CxWgpd6K.mjs";
|
|
4
4
|
import { RedisEventTransportOptions, RedisLike } from "./transports/redis.mjs";
|
|
5
|
-
import { r as RedisStreamTransportOptions, t as RedisStreamLike } from "../redis-stream-
|
|
5
|
+
import { r as RedisStreamTransportOptions, t as RedisStreamLike } from "../redis-stream-CakIQmwR.mjs";
|
|
6
6
|
|
|
7
7
|
//#region src/events/eventTypes.d.ts
|
|
8
8
|
/**
|
|
@@ -597,4 +597,7 @@ interface ExponentialBackoffOptions {
|
|
|
597
597
|
*/
|
|
598
598
|
declare function exponentialBackoff(options: ExponentialBackoffOptions): Date;
|
|
599
599
|
//#endregion
|
|
600
|
-
|
|
600
|
+
//#region src/events/repository-outbox-adapter.d.ts
|
|
601
|
+
declare function repositoryAsOutboxStore(repository: RepositoryLike): OutboxStore;
|
|
602
|
+
//#endregion
|
|
603
|
+
export { ARC_LIFECYCLE_EVENTS, type ArcLifecycleEvent, CACHE_EVENTS, CRUD_EVENT_SUFFIXES, type CacheEvent, type CrudEventSuffix, type CustomValidator, type DeadLetteredEvent, type DomainEvent, type EventDefinitionInput, type EventDefinitionOutput, type EventHandler, type EventLogger, type EventMeta, EventOutbox, type EventOutboxOptions, type EventPluginOptions, type EventRegistry, type EventRegistryOptions, type EventSchema, type EventTransport, type ExponentialBackoffOptions, InvalidOutboxEventError, MemoryEventTransport, type MemoryEventTransportOptions, MemoryOutboxStore, type OutboxAcknowledgeOptions, type OutboxClaimOptions, type OutboxErrorInfo, type OutboxFailOptions, type OutboxFailureContext, type OutboxFailureDecision, type OutboxFailurePolicy, OutboxOwnershipError, type OutboxRelayErrorHandler, type OutboxRelayErrorKind, type OutboxStore, type OutboxWriteOptions, type PublishManyResult, type RedisEventTransportOptions, type RedisLike, type RedisStreamLike, type RedisStreamTransportOptions, type RelayResult, type RetryOptions, type ValidationResult, createChildEvent, createDeadLetterPublisher, createEvent, createEventRegistry, crudEventType, defineEvent, eventPlugin, exponentialBackoff, repositoryAsOutboxStore, withRetry };
|
package/dist/events/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as MemoryEventTransport, i as withRetry, o as createChildEvent, r as createDeadLetterPublisher, s as createEvent, t as eventPlugin } from "../eventPlugin-
|
|
2
|
-
import { n as createSafeGetOne, t as createIsDuplicateKeyError } from "../store-helpers-
|
|
1
|
+
import { a as MemoryEventTransport, i as withRetry, o as createChildEvent, r as createDeadLetterPublisher, s as createEvent, t as eventPlugin } from "../eventPlugin-DCUjuiQT.mjs";
|
|
2
|
+
import { n as createSafeGetOne, t as createIsDuplicateKeyError } from "../store-helpers-ZCSMJJAX.mjs";
|
|
3
3
|
//#region src/events/defineEvent.ts
|
|
4
4
|
/**
|
|
5
5
|
* defineEvent — Typed Event Definitions with Optional Schema Validation
|
|
@@ -346,11 +346,19 @@ function repositoryAsOutboxStore(repository) {
|
|
|
346
346
|
const missing = [];
|
|
347
347
|
if (typeof repository.create !== "function") missing.push("create");
|
|
348
348
|
if (typeof repository.getOne !== "function") missing.push("getOne");
|
|
349
|
-
if (typeof repository.
|
|
349
|
+
if (typeof repository.getAll !== "function") missing.push("getAll");
|
|
350
350
|
if (typeof repository.deleteMany !== "function") missing.push("deleteMany");
|
|
351
351
|
if (typeof repository.findOneAndUpdate !== "function") missing.push("findOneAndUpdate");
|
|
352
|
-
if (missing.length > 0) throw new Error(`EventOutbox: repository is missing required methods: ${missing.join(", ")}. mongokit ≥3.
|
|
352
|
+
if (missing.length > 0) throw new Error(`EventOutbox: repository is missing required methods: ${missing.join(", ")}. mongokit ≥3.10.2 satisfies all five; other kits must implement them to back the outbox.`);
|
|
353
353
|
const r = repository;
|
|
354
|
+
/**
|
|
355
|
+
* Unwrap mongokit's pagination envelope ({ docs, total, ... }) — some
|
|
356
|
+
* kits may return a bare array when pagination is disabled. Handle both.
|
|
357
|
+
*/
|
|
358
|
+
const unwrapDocs = (result) => {
|
|
359
|
+
if (Array.isArray(result)) return result;
|
|
360
|
+
return result?.docs ?? [];
|
|
361
|
+
};
|
|
354
362
|
const isDuplicateKeyError = createIsDuplicateKeyError(repository);
|
|
355
363
|
const safeGetOne = createSafeGetOne(repository);
|
|
356
364
|
const isWellFormed = (event) => !!event && typeof event.type === "string" && !!event.meta?.id;
|
|
@@ -386,12 +394,14 @@ function repositoryAsOutboxStore(repository) {
|
|
|
386
394
|
},
|
|
387
395
|
async getPending(limit) {
|
|
388
396
|
const now = /* @__PURE__ */ new Date();
|
|
389
|
-
return (await r.
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
397
|
+
return unwrapDocs(await r.getAll({
|
|
398
|
+
filters: {
|
|
399
|
+
status: "pending",
|
|
400
|
+
visibleAt: { $lte: now },
|
|
401
|
+
$or: [{ leaseOwner: null }, { leaseExpiresAt: { $lte: now } }]
|
|
402
|
+
},
|
|
394
403
|
sort: { createdAt: 1 },
|
|
404
|
+
page: 1,
|
|
395
405
|
limit
|
|
396
406
|
})).map((d) => d.event).filter(isWellFormed);
|
|
397
407
|
},
|
|
@@ -460,14 +470,19 @@ function repositoryAsOutboxStore(repository) {
|
|
|
460
470
|
},
|
|
461
471
|
firstFailedAt: { $ifNull: ["$firstFailedAt", now] }
|
|
462
472
|
} }];
|
|
463
|
-
if (await r.findOneAndUpdate(filter, pipeline, {
|
|
473
|
+
if (await r.findOneAndUpdate(filter, pipeline, {
|
|
474
|
+
returnDocument: "after",
|
|
475
|
+
updatePipeline: true
|
|
476
|
+
})) return;
|
|
464
477
|
const current = await safeGetOne({ _id: eventId });
|
|
465
478
|
if (!current) return;
|
|
466
479
|
if (options?.consumerId && current.leaseOwner !== options.consumerId) throw new OutboxOwnershipError(eventId, options.consumerId, current.leaseOwner);
|
|
467
480
|
},
|
|
468
481
|
async getDeadLettered(limit) {
|
|
469
|
-
return (await r.
|
|
482
|
+
return unwrapDocs(await r.getAll({
|
|
483
|
+
filters: { status: "dead_letter" },
|
|
470
484
|
sort: { _id: 1 },
|
|
485
|
+
page: 1,
|
|
471
486
|
limit
|
|
472
487
|
})).filter((d) => isWellFormed(d.event)).map((d) => ({
|
|
473
488
|
event: d.event,
|
|
@@ -484,14 +499,16 @@ function repositoryAsOutboxStore(repository) {
|
|
|
484
499
|
const cutoff = new Date(Date.now() - olderThanMs);
|
|
485
500
|
let totalDeleted = 0;
|
|
486
501
|
for (;;) {
|
|
487
|
-
const batch = await r.
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
502
|
+
const batch = unwrapDocs(await r.getAll({
|
|
503
|
+
filters: {
|
|
504
|
+
status: "delivered",
|
|
505
|
+
deliveredAt: { $lte: cutoff }
|
|
506
|
+
},
|
|
491
507
|
sort: { deliveredAt: 1 },
|
|
508
|
+
page: 1,
|
|
492
509
|
limit: DEFAULT_PURGE_BATCH,
|
|
493
510
|
select: "_id"
|
|
494
|
-
});
|
|
511
|
+
}));
|
|
495
512
|
if (batch.length === 0) break;
|
|
496
513
|
const ids = batch.map((d) => d._id);
|
|
497
514
|
const res = await r.deleteMany({ _id: { $in: ids } });
|
|
@@ -843,4 +860,4 @@ function exponentialBackoff(options) {
|
|
|
843
860
|
return new Date(now + jittered);
|
|
844
861
|
}
|
|
845
862
|
//#endregion
|
|
846
|
-
export { ARC_LIFECYCLE_EVENTS, CACHE_EVENTS, CRUD_EVENT_SUFFIXES, EventOutbox, InvalidOutboxEventError, MemoryEventTransport, MemoryOutboxStore, OutboxOwnershipError, createChildEvent, createDeadLetterPublisher, createEvent, createEventRegistry, crudEventType, defineEvent, eventPlugin, exponentialBackoff, withRetry };
|
|
863
|
+
export { ARC_LIFECYCLE_EVENTS, CACHE_EVENTS, CRUD_EVENT_SUFFIXES, EventOutbox, InvalidOutboxEventError, MemoryEventTransport, MemoryOutboxStore, OutboxOwnershipError, createChildEvent, createDeadLetterPublisher, createEvent, createEventRegistry, crudEventType, defineEvent, eventPlugin, exponentialBackoff, repositoryAsOutboxStore, withRetry };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as RedisStreamTransport, r as RedisStreamTransportOptions, t as RedisStreamLike } from "../../redis-stream-
|
|
1
|
+
import { n as RedisStreamTransport, r as RedisStreamTransportOptions, t as RedisStreamLike } from "../../redis-stream-CakIQmwR.mjs";
|
|
2
2
|
export { type RedisStreamLike, RedisStreamTransport, type RedisStreamTransportOptions };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as EventLogger, n as DomainEvent, o as EventTransport, r as EventHandler } from "../../EventTransport-
|
|
1
|
+
import { i as EventLogger, n as DomainEvent, o as EventTransport, r as EventHandler } from "../../EventTransport-CUw5NNWe.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/events/transports/redis.d.ts
|
|
4
4
|
interface RedisLike {
|
package/dist/factory/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as CustomPluginAuthOption, c as RawBodyOptions, d as ResourceLike, f as loadResources, i as CustomAuthenticatorOption, l as UnderPressureOptions, n as BetterAuthOption, o as JwtAuthOption, r as CreateAppOptions, s as MultipartOptions, t as AuthOption, u as LoadResourcesOptions } from "../types-
|
|
1
|
+
import { a as CustomPluginAuthOption, c as RawBodyOptions, d as ResourceLike, f as loadResources, i as CustomAuthenticatorOption, l as UnderPressureOptions, n as BetterAuthOption, o as JwtAuthOption, r as CreateAppOptions, s as MultipartOptions, t as AuthOption, u as LoadResourcesOptions } from "../types-Co8k3NyS.mjs";
|
|
2
2
|
import { FastifyInstance } from "fastify";
|
|
3
3
|
|
|
4
4
|
//#region src/factory/createApp.d.ts
|
package/dist/factory/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as edgePreset, c as testingPreset, i as developmentPreset, n as createApp, o as getPreset, s as productionPreset, t as ArcFactory } from "../createApp-
|
|
2
|
-
import { t as loadResources } from "../loadResources-
|
|
1
|
+
import { a as edgePreset, c as testingPreset, i as developmentPreset, n as createApp, o as getPreset, s as productionPreset, t as ArcFactory } from "../createApp-BuvPma24.mjs";
|
|
2
|
+
import { t as loadResources } from "../loadResources-BAzJItAJ.mjs";
|
|
3
3
|
//#region src/factory/edge.ts
|
|
4
4
|
/**
|
|
5
5
|
* Convert a Fastify app into a Web Standards fetch handler.
|
|
@@ -175,4 +175,124 @@ interface PermissionCheckMeta {
|
|
|
175
175
|
_orgInScopeTarget?: string | ((ctx: PermissionContext) => string | undefined);
|
|
176
176
|
}
|
|
177
177
|
//#endregion
|
|
178
|
-
|
|
178
|
+
//#region src/permissions/fields.d.ts
|
|
179
|
+
/**
|
|
180
|
+
* Field-Level Permissions
|
|
181
|
+
*
|
|
182
|
+
* Control field visibility and writability per role.
|
|
183
|
+
* Integrated into the response path (read) and sanitization path (write).
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```typescript
|
|
187
|
+
* import { fields, defineResource } from '@classytic/arc';
|
|
188
|
+
*
|
|
189
|
+
* const userResource = defineResource({
|
|
190
|
+
* name: 'user',
|
|
191
|
+
* adapter: userAdapter,
|
|
192
|
+
* fields: {
|
|
193
|
+
* salary: fields.visibleTo(['admin', 'hr']),
|
|
194
|
+
* internalNotes: fields.writableBy(['admin']),
|
|
195
|
+
* email: fields.redactFor(['viewer']),
|
|
196
|
+
* password: fields.hidden(),
|
|
197
|
+
* },
|
|
198
|
+
* });
|
|
199
|
+
* ```
|
|
200
|
+
*/
|
|
201
|
+
type FieldPermissionType = "hidden" | "visibleTo" | "writableBy" | "redactFor";
|
|
202
|
+
interface FieldPermission {
|
|
203
|
+
readonly _type: FieldPermissionType;
|
|
204
|
+
readonly roles?: readonly string[];
|
|
205
|
+
readonly redactValue?: unknown;
|
|
206
|
+
}
|
|
207
|
+
type FieldPermissionMap = Record<string, FieldPermission>;
|
|
208
|
+
declare const fields: {
|
|
209
|
+
/**
|
|
210
|
+
* Field is never included in responses. Not writable via API.
|
|
211
|
+
*
|
|
212
|
+
* @example
|
|
213
|
+
* ```typescript
|
|
214
|
+
* fields: { password: fields.hidden() }
|
|
215
|
+
* ```
|
|
216
|
+
*/
|
|
217
|
+
hidden(): FieldPermission;
|
|
218
|
+
/**
|
|
219
|
+
* Field is only visible to users with specified roles.
|
|
220
|
+
* Other users don't see the field at all.
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* ```typescript
|
|
224
|
+
* fields: { salary: fields.visibleTo(['admin', 'hr']) }
|
|
225
|
+
* ```
|
|
226
|
+
*/
|
|
227
|
+
visibleTo(roles: readonly string[]): FieldPermission;
|
|
228
|
+
/**
|
|
229
|
+
* Field is only writable by users with specified roles.
|
|
230
|
+
* All users can still read the field. Users without the role
|
|
231
|
+
* have the field silently stripped from write operations.
|
|
232
|
+
*
|
|
233
|
+
* @example
|
|
234
|
+
* ```typescript
|
|
235
|
+
* fields: { role: fields.writableBy(['admin']) }
|
|
236
|
+
* ```
|
|
237
|
+
*/
|
|
238
|
+
writableBy(roles: readonly string[]): FieldPermission;
|
|
239
|
+
/**
|
|
240
|
+
* Field is redacted (replaced with a placeholder) for specified roles.
|
|
241
|
+
* Other users see the real value.
|
|
242
|
+
*
|
|
243
|
+
* @param roles - Roles that see the redacted value
|
|
244
|
+
* @param redactValue - Replacement value (default: '***')
|
|
245
|
+
*
|
|
246
|
+
* @example
|
|
247
|
+
* ```typescript
|
|
248
|
+
* fields: {
|
|
249
|
+
* email: fields.redactFor(['viewer']),
|
|
250
|
+
* ssn: fields.redactFor(['basic'], '***-**-****'),
|
|
251
|
+
* }
|
|
252
|
+
* ```
|
|
253
|
+
*/
|
|
254
|
+
redactFor(roles: readonly string[], redactValue?: unknown): FieldPermission;
|
|
255
|
+
};
|
|
256
|
+
/**
|
|
257
|
+
* Apply field-level READ permissions to a response object.
|
|
258
|
+
* Strips hidden fields, enforces visibility, and applies redaction.
|
|
259
|
+
*
|
|
260
|
+
* @param data - The response object (mutated in place for performance)
|
|
261
|
+
* @param fieldPermissions - Field permission map from resource config
|
|
262
|
+
* @param userRoles - Current user's roles (empty array for unauthenticated)
|
|
263
|
+
* @returns The filtered object
|
|
264
|
+
*/
|
|
265
|
+
declare function applyFieldReadPermissions<T extends Record<string, unknown>>(data: T, fieldPermissions: FieldPermissionMap, userRoles: readonly string[]): T;
|
|
266
|
+
/**
|
|
267
|
+
* Result of applying write permissions — includes both the filtered body
|
|
268
|
+
* and the list of fields that were stripped so callers can decide whether
|
|
269
|
+
* to reject the request (secure default) or silently strip (legacy).
|
|
270
|
+
*/
|
|
271
|
+
interface FieldWritePermissionResult<T extends Record<string, unknown>> {
|
|
272
|
+
readonly body: T;
|
|
273
|
+
readonly deniedFields: readonly string[];
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Apply field-level WRITE permissions to request body.
|
|
277
|
+
*
|
|
278
|
+
* Returns both the filtered body and the list of denied fields. Callers are
|
|
279
|
+
* expected to reject the request when `deniedFields.length > 0` — silently
|
|
280
|
+
* stripping fields hides misconfigurations and real attacks. See
|
|
281
|
+
* `BodySanitizer` for the default policy.
|
|
282
|
+
*
|
|
283
|
+
* @param body - The request body (returns a new filtered copy)
|
|
284
|
+
* @param fieldPermissions - Field permission map from resource config
|
|
285
|
+
* @param userRoles - Current user's roles
|
|
286
|
+
*/
|
|
287
|
+
declare function applyFieldWritePermissions<T extends Record<string, unknown>>(body: T, fieldPermissions: FieldPermissionMap, userRoles: readonly string[]): FieldWritePermissionResult<T>;
|
|
288
|
+
/**
|
|
289
|
+
* Resolve effective roles by merging global user roles with org-level roles.
|
|
290
|
+
*
|
|
291
|
+
* Global roles come from `req.user.role` (normalized via getUserRoles()).
|
|
292
|
+
* Org roles come from `req.context.orgRoles` (set by BA adapter's org bridge).
|
|
293
|
+
*
|
|
294
|
+
* When no org context exists, returns global roles only — backward compatible.
|
|
295
|
+
*/
|
|
296
|
+
declare function resolveEffectiveRoles(userRoles: readonly string[], orgRoles: readonly string[]): string[];
|
|
297
|
+
//#endregion
|
|
298
|
+
export { applyFieldWritePermissions as a, PermissionCheck as c, UserBase as d, getUserRoles as f, applyFieldReadPermissions as i, PermissionContext as l, FieldPermissionMap as n, fields as o, normalizeRoles as p, FieldPermissionType as r, resolveEffectiveRoles as s, FieldPermission as t, PermissionResult as u };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { o as getOrgId, p as getUserId } from "./types-AOD8fxIw.mjs";
|
|
2
|
-
import { i as NotFoundError, u as ValidationError } from "./errors-
|
|
3
|
-
import {
|
|
2
|
+
import { i as NotFoundError, u as ValidationError } from "./errors-D5c-5BJL.mjs";
|
|
3
|
+
import { C as requireAuth, y as allowPublic } from "./permissions-Dk6mshja.mjs";
|
|
4
4
|
//#region src/middleware/multipartBody.ts
|
|
5
5
|
const DEFAULT_MAX_FILE_SIZE$1 = 10 * 1024 * 1024;
|
|
6
6
|
const DEFAULT_MAX_FILES = 5;
|
package/dist/hooks/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $t as HookPhase, Qt as HookOperation, Xt as HookContext, Yt as DefineHookOptions, Zt as HookHandler, an as afterUpdate, cn as beforeUpdate, en as HookRegistration, in as afterDelete, ln as createHookSystem, nn as HookSystemOptions, on as beforeCreate, rn as afterCreate, sn as beforeDelete, tn as HookSystem, un as defineHook } from "../index-Cl0uoKd5.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 };
|
package/dist/hooks/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as beforeCreate, c as createHookSystem, i as afterUpdate, l as defineHook, n as afterCreate, o as beforeDelete, r as afterDelete, s as beforeUpdate, t as HookSystem } from "../HookSystem-
|
|
1
|
+
import { a as beforeCreate, c as createHookSystem, i as afterUpdate, l as defineHook, n as afterCreate, o as beforeDelete, r as afterDelete, s as beforeUpdate, t as HookSystem } from "../HookSystem-BNYKnrXF.mjs";
|
|
2
2
|
export { HookSystem, afterCreate, afterDelete, afterUpdate, beforeCreate, beforeDelete, beforeUpdate, createHookSystem, defineHook };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { i as createIdempotencyResult, n as IdempotencyResult, r as IdempotencyStore, t as IdempotencyLock } from "../interface-
|
|
3
|
-
import { i as RedisIdempotencyStoreOptions, n as RedisClient } from "../redis-
|
|
1
|
+
import { kt as RepositoryLike } from "../index-Cl0uoKd5.mjs";
|
|
2
|
+
import { i as createIdempotencyResult, n as IdempotencyResult, r as IdempotencyStore, t as IdempotencyLock } from "../interface-CSbZdv_3.mjs";
|
|
3
|
+
import { i as RedisIdempotencyStoreOptions, n as RedisClient } from "../redis-DqyeggCa.mjs";
|
|
4
4
|
import { FastifyPluginAsync } from "fastify";
|
|
5
5
|
|
|
6
6
|
//#region src/idempotency/idempotencyPlugin.d.ts
|
|
@@ -82,6 +82,9 @@ declare module "fastify" {
|
|
|
82
82
|
declare const idempotencyPlugin: FastifyPluginAsync<IdempotencyPluginOptions>;
|
|
83
83
|
declare const _default: FastifyPluginAsync<IdempotencyPluginOptions>;
|
|
84
84
|
//#endregion
|
|
85
|
+
//#region src/idempotency/repository-idempotency-adapter.d.ts
|
|
86
|
+
declare function repositoryAsIdempotencyStore(repository: RepositoryLike, defaultTtlMs: number): IdempotencyStore;
|
|
87
|
+
//#endregion
|
|
85
88
|
//#region src/idempotency/stores/memory.d.ts
|
|
86
89
|
interface MemoryIdempotencyStoreOptions {
|
|
87
90
|
/** Default TTL in milliseconds (default: 86400000 = 24h) */
|
|
@@ -117,4 +120,4 @@ declare class MemoryIdempotencyStore implements IdempotencyStore {
|
|
|
117
120
|
private evictOldest;
|
|
118
121
|
}
|
|
119
122
|
//#endregion
|
|
120
|
-
export { type IdempotencyLock, type IdempotencyPluginOptions, type IdempotencyResult, type IdempotencyStore, MemoryIdempotencyStore, type MemoryIdempotencyStoreOptions, type RedisClient, type RedisIdempotencyStoreOptions, createIdempotencyResult, _default as idempotencyPlugin, idempotencyPlugin as idempotencyPluginFn };
|
|
123
|
+
export { type IdempotencyLock, type IdempotencyPluginOptions, type IdempotencyResult, type IdempotencyStore, MemoryIdempotencyStore, type MemoryIdempotencyStoreOptions, type RedisClient, type RedisIdempotencyStoreOptions, createIdempotencyResult, _default as idempotencyPlugin, idempotencyPlugin as idempotencyPluginFn, repositoryAsIdempotencyStore };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as createSafeGetOne, t as createIsDuplicateKeyError } from "../store-helpers-
|
|
1
|
+
import { n as createSafeGetOne, t as createIsDuplicateKeyError } from "../store-helpers-ZCSMJJAX.mjs";
|
|
2
2
|
import { createHash } from "node:crypto";
|
|
3
3
|
import fp from "fastify-plugin";
|
|
4
4
|
//#region src/idempotency/repository-idempotency-adapter.ts
|
|
@@ -361,6 +361,7 @@ const idempotencyPlugin = async (fastify, opts = {}) => {
|
|
|
361
361
|
return;
|
|
362
362
|
}
|
|
363
363
|
request._idempotencyFullKey = fullKey;
|
|
364
|
+
reply.header(HEADER_IDEMPOTENCY_KEY, idempotencyKey);
|
|
364
365
|
};
|
|
365
366
|
fastify.decorate("idempotency", {
|
|
366
367
|
invalidate: async (key) => {
|
|
@@ -371,15 +372,12 @@ const idempotencyPlugin = async (fastify, opts = {}) => {
|
|
|
371
372
|
},
|
|
372
373
|
middleware: idempotencyMiddleware
|
|
373
374
|
});
|
|
374
|
-
fastify.addHook("
|
|
375
|
+
fastify.addHook("preSerialization", async (request, reply, payload) => {
|
|
375
376
|
if (request.idempotencyReplayed) return payload;
|
|
376
377
|
const fullKey = request._idempotencyFullKey;
|
|
377
378
|
if (!fullKey) return payload;
|
|
378
379
|
const statusCode = reply.statusCode;
|
|
379
|
-
if (statusCode < 200 || statusCode >= 300)
|
|
380
|
-
await store.unlock(fullKey, request.id);
|
|
381
|
-
return payload;
|
|
382
|
-
}
|
|
380
|
+
if (statusCode < 200 || statusCode >= 300) return payload;
|
|
383
381
|
const headersToCache = {};
|
|
384
382
|
const excludeHeaders = new Set([
|
|
385
383
|
"content-length",
|
|
@@ -399,13 +397,13 @@ const idempotencyPlugin = async (fastify, opts = {}) => {
|
|
|
399
397
|
}
|
|
400
398
|
const result = createIdempotencyResult(statusCode, body, headersToCache, ttlMs);
|
|
401
399
|
await store.set(fullKey, result);
|
|
402
|
-
await store.unlock(fullKey, request.id);
|
|
403
|
-
reply.header(HEADER_IDEMPOTENCY_KEY, request.idempotencyKey);
|
|
404
400
|
return payload;
|
|
405
401
|
});
|
|
406
|
-
fastify.addHook("
|
|
402
|
+
fastify.addHook("onResponse", async (request) => {
|
|
403
|
+
if (request.idempotencyReplayed) return;
|
|
407
404
|
const fullKey = request._idempotencyFullKey;
|
|
408
|
-
if (fullKey)
|
|
405
|
+
if (!fullKey) return;
|
|
406
|
+
await store.unlock(fullKey, request.id);
|
|
409
407
|
});
|
|
410
408
|
fastify.addHook("onClose", async () => {
|
|
411
409
|
await store.close?.();
|
|
@@ -421,4 +419,4 @@ var idempotencyPlugin_default = fp(idempotencyPlugin, {
|
|
|
421
419
|
fastify: "5.x"
|
|
422
420
|
});
|
|
423
421
|
//#endregion
|
|
424
|
-
export { MemoryIdempotencyStore, createIdempotencyResult, idempotencyPlugin_default as idempotencyPlugin, idempotencyPlugin as idempotencyPluginFn };
|
|
422
|
+
export { MemoryIdempotencyStore, createIdempotencyResult, idempotencyPlugin_default as idempotencyPlugin, idempotencyPlugin as idempotencyPluginFn, repositoryAsIdempotencyStore };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as UpstashRedisLike, i as RedisIdempotencyStoreOptions, n as RedisClient, o as ioredisAsIdempotencyClient, r as RedisIdempotencyStore, s as upstashAsIdempotencyClient, t as IoredisLike } from "../redis-
|
|
1
|
+
import { a as UpstashRedisLike, i as RedisIdempotencyStoreOptions, n as RedisClient, o as ioredisAsIdempotencyClient, r as RedisIdempotencyStore, s as upstashAsIdempotencyClient, t as IoredisLike } from "../redis-DqyeggCa.mjs";
|
|
2
2
|
export { type IoredisLike, type RedisClient, RedisIdempotencyStore, type RedisIdempotencyStoreOptions, type UpstashRedisLike, ioredisAsIdempotencyClient, upstashAsIdempotencyClient };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { r as RequestScope } from "./types-BD85MlEK.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { c as PermissionCheck } from "./fields-Lo1VUDpt.mjs";
|
|
3
|
+
import { B as FastifyWithDecorators, G as ResourceDefinition, St as IRequestContext, Z as CrudController, bt as IController, dn as AnyRecord, lt as ResourceConfig, qt as RequestContext, w as CrudRouterOptions, xt as IControllerResponse } from "./index-Cl0uoKd5.mjs";
|
|
4
4
|
import { FastifyReply, FastifyRequest, RouteHandlerMethod } from "fastify";
|
|
5
5
|
|
|
6
6
|
//#region src/constants.d.ts
|