@classytic/arc 2.32.0 → 2.33.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-CaQC5EXX.mjs} +293 -33
- 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-B3mP_QTy.mjs} +2 -2
- package/dist/{types-B7XeLEgK.d.mts → base-Csjc2oF-.d.mts} +74 -74
- package/dist/{buildHandler-Dn7rzUJo.mjs → buildHandler-DLE9xX-V.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 +2 -2
- package/dist/core/index.mjs +7 -7
- package/dist/{core-BwwmNSp7.mjs → core-dxhcHhUD.mjs} +3 -3
- package/dist/{createActionRouter-DkJZWo0m.mjs → createActionRouter-DVpoA0do.mjs} +8 -8
- package/dist/{createAggregationRouter-B1exOVD8.mjs → createAggregationRouter-B_B48JZ-.mjs} +7 -7
- package/dist/{createApp-Bv0m-Q6_.mjs → createApp-CLGegqiG.mjs} +128 -24
- package/dist/{defineAggregation-gX4No1gt.mjs → defineAggregation-Nv-DwfOf.mjs} +1 -1
- package/dist/{defineResource-XFPPUu2c.mjs → defineResource-DR9vsUYy.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 +91 -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-DXlHwvuE.d.mts → index-Brin0ODU.d.mts} +4 -4
- package/dist/{index-ZWhLTp_s.d.mts → index-C5NnMEKF.d.mts} +1 -1
- package/dist/{index-C-481Zf2.d.mts → index-ugr1tQlW.d.mts} +17 -1
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +11 -11
- 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-aJg5TqHi.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-BN5cQaO2.mjs} +6 -6
- package/dist/outbox-admin/index.d.mts +2 -2
- package/dist/outbox-admin/index.mjs +4 -4
- package/dist/outbox-module-CXB79bvt.mjs +839 -0
- package/dist/outbox-module-D-VFq37T.d.mts +368 -0
- package/dist/permissions/index.d.mts +2 -2
- package/dist/permissions/index.mjs +5 -5
- package/dist/{permissions-Dl_m0NCe.mjs → permissions-BAfwgBxc.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-D-h0uWtP.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-CTkv3O59.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-DNnd3vkz.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-DotlxG3L.mjs → repositoryFilter-DKny7PDn.mjs} +1 -1
- 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
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
|
|
2
|
-
import { n as RedisStreamTransport, r as RedisStreamTransportOptions, t as RedisStreamLike } from "../../redis-stream-
|
|
2
|
+
import { n as RedisStreamTransport, r as RedisStreamTransportOptions, t as RedisStreamLike } from "../../redis-stream-mwLWlfHG.mjs";
|
|
3
3
|
export { type RedisStreamLike, RedisStreamTransport, type RedisStreamTransportOptions };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import { a as EventTransport, i as EventLogger, n as DomainEvent, r as EventHandler } from "../../EventTransport-
|
|
2
|
+
import { a as EventTransport, i as EventLogger, n as DomainEvent, r as EventHandler } from "../../EventTransport-BEVP50ka.mjs";
|
|
3
3
|
//#region src/events/transports/redis.d.ts
|
|
4
4
|
interface RedisLike {
|
|
5
5
|
publish(channel: string, message: string): Promise<number>;
|
package/dist/factory/index.d.mts
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
|
|
2
|
-
import { _ as HealthCheck, a as ModuleContribution, c as LoadResourcesOptions, d as loadResources, i as EventHandlerDefinition, l as ResourceLike, n as ArcModuleInput, o as ModuleDisposer, r as ArcModuleRegistry, s as ModuleSetupContext, t as ArcModule, u as ResourceModule } from "../types-
|
|
3
|
-
import { _ as collectModuleScheduledJobs, a as lazyModuleExports, c as getModuleState, d as resolveModule, f as orderModules, g as collectModuleHealthChecks, h as extendModule, i as hasModuleExports, l as hasModule, m as ModuleExtension, n as getModuleExports, o as lazyRequiredModuleExports, p as subscribeModuleEventHandlers, r as getOptionalModuleExports, s as ModuleState, t as defineModule, u as resolveContribution, v as collectModuleWorkflows } from "../index-
|
|
4
|
-
import { c as ResolvedResourceDescriptor, l as describeResolvedModule, o as ResolvedModuleDescriptor, s as ResolvedModuleLifecycle } from "../fastify-augmentation-
|
|
5
|
-
import { a as RawBodyOptions, c as BetterAuthOption, d as JwtAuthOption, i as MultipartOptions, l as CustomAuthenticatorOption, n as preloadResourcesAsync, o as UnderPressureOptions, r as CreateAppOptions, s as AuthOption, t as preloadResources, u as CustomPluginAuthOption } from "../preloadResources-
|
|
2
|
+
import { _ as HealthCheck, a as ModuleContribution, c as LoadResourcesOptions, d as loadResources, i as EventHandlerDefinition, l as ResourceLike, n as ArcModuleInput, o as ModuleDisposer, r as ArcModuleRegistry, s as ModuleSetupContext, t as ArcModule, u as ResourceModule } from "../types-BcTumAz_.mjs";
|
|
3
|
+
import { _ as collectModuleScheduledJobs, a as lazyModuleExports, c as getModuleState, d as resolveModule, f as orderModules, g as collectModuleHealthChecks, h as extendModule, i as hasModuleExports, l as hasModule, m as ModuleExtension, n as getModuleExports, o as lazyRequiredModuleExports, p as subscribeModuleEventHandlers, r as getOptionalModuleExports, s as ModuleState, t as defineModule, u as resolveContribution, v as collectModuleWorkflows } from "../index-C5NnMEKF.mjs";
|
|
4
|
+
import { c as ResolvedResourceDescriptor, l as describeResolvedModule, o as ResolvedModuleDescriptor, s as ResolvedModuleLifecycle } from "../fastify-augmentation-DVsTAy6X.mjs";
|
|
5
|
+
import { a as RawBodyOptions, c as BetterAuthOption, d as JwtAuthOption, i as MultipartOptions, l as CustomAuthenticatorOption, n as preloadResourcesAsync, o as UnderPressureOptions, r as CreateAppOptions, s as AuthOption, t as preloadResources, u as CustomPluginAuthOption } from "../preloadResources-g07ldtzh.mjs";
|
|
6
6
|
import { FastifyInstance, FastifyServerOptions } from "fastify";
|
|
7
7
|
//#region src/factory/createApp.d.ts
|
|
8
|
+
/**
|
|
9
|
+
* Default redact paths layered into Fastify's pino logger when the host
|
|
10
|
+
* doesn't supply a `logger.redact` of their own. Covers the common token /
|
|
11
|
+
* cookie / password leak surfaces — `Authorization` and `Cookie` headers
|
|
12
|
+
* (and their case-variants because Node lower-cases incoming headers but
|
|
13
|
+
* outgoing logs may carry either), API-key headers, and any nested
|
|
14
|
+
* `password` / `token` / `secret` / `apiKey` fields anywhere in the log
|
|
15
|
+
* tree.
|
|
16
|
+
*
|
|
17
|
+
* Hosts that need NO redaction (test fixtures, security audits) opt out
|
|
18
|
+
* with `logger: { redact: [] }`. Hosts that need MORE redaction supply
|
|
19
|
+
* their own `redact` and arc steps aside — this default never overrides
|
|
20
|
+
* an explicit setting. (2.15.1)
|
|
21
|
+
*/
|
|
22
|
+
declare const DEFAULT_LOGGER_REDACT_PATHS: readonly ["req.headers.authorization", 'req.headers["x-api-key"]', 'req.headers["x-internal-api-key"]', "req.headers.cookie", 'req.headers["set-cookie"]', 'res.headers["set-cookie"]', "*.password", "*.passwordHash", "*.token", "*.accessToken", "*.refreshToken", "*.secret", "*.apiKey"];
|
|
8
23
|
/**
|
|
9
24
|
* Create a production-ready Fastify application with Arc framework.
|
|
10
25
|
*
|
|
@@ -137,4 +152,4 @@ declare const testingPreset: Partial<CreateAppOptions>;
|
|
|
137
152
|
declare const edgePreset: Partial<CreateAppOptions>;
|
|
138
153
|
declare function getPreset(name: "production" | "development" | "testing" | "edge" | "worker"): Partial<CreateAppOptions>;
|
|
139
154
|
//#endregion
|
|
140
|
-
export { ArcFactory, type ArcModule, type ArcModuleInput, type ArcModuleRegistry, type ArcWorker, type AuthOption, type BetterAuthOption, type CreateAppOptions, type CreateWorkerOptions, type CustomAuthenticatorOption, type CustomPluginAuthOption, type EventHandlerDefinition, type FetchHandlerOptions, type JwtAuthOption, type LoadResourcesOptions, type ModuleContribution, type ModuleDisposer, type ModuleExtension, type ModuleSetupContext, type ModuleState, type MultipartOptions, type RawBodyOptions, type ResolvedModuleDescriptor, type ResolvedModuleLifecycle, type ResolvedResourceDescriptor, type ResourceLike, type ResourceModule, type UnderPressureOptions, type WorkerHealthOptions, collectModuleHealthChecks, collectModuleScheduledJobs, collectModuleWorkflows, createApp, createWorker, defineModule, describeResolvedModule, developmentPreset, edgePreset, extendModule, getModuleExports, getModuleState, getOptionalModuleExports, getPreset, hasModule, hasModuleExports, lazyModuleExports, lazyRequiredModuleExports, loadResources, orderModules, preloadResources, preloadResourcesAsync, productionPreset, resolveContribution, resolveModule, subscribeModuleEventHandlers, testingPreset, toFetchHandler };
|
|
155
|
+
export { ArcFactory, type ArcModule, type ArcModuleInput, type ArcModuleRegistry, type ArcWorker, type AuthOption, type BetterAuthOption, type CreateAppOptions, type CreateWorkerOptions, type CustomAuthenticatorOption, type CustomPluginAuthOption, DEFAULT_LOGGER_REDACT_PATHS, type EventHandlerDefinition, type FetchHandlerOptions, type JwtAuthOption, type LoadResourcesOptions, type ModuleContribution, type ModuleDisposer, type ModuleExtension, type ModuleSetupContext, type ModuleState, type MultipartOptions, type RawBodyOptions, type ResolvedModuleDescriptor, type ResolvedModuleLifecycle, type ResolvedResourceDescriptor, type ResourceLike, type ResourceModule, type UnderPressureOptions, type WorkerHealthOptions, collectModuleHealthChecks, collectModuleScheduledJobs, collectModuleWorkflows, createApp, createWorker, defineModule, describeResolvedModule, developmentPreset, edgePreset, extendModule, getModuleExports, getModuleState, getOptionalModuleExports, getPreset, hasModule, hasModuleExports, lazyModuleExports, lazyRequiredModuleExports, loadResources, orderModules, preloadResources, preloadResourcesAsync, productionPreset, resolveContribution, resolveModule, subscribeModuleEventHandlers, testingPreset, toFetchHandler };
|
package/dist/factory/index.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { r as mergeHealthChecks, t as healthPlugin } from "../health-
|
|
3
|
-
import { _ as
|
|
4
|
-
import { a as lazyModuleExports, i as hasModuleExports, n as getModuleExports, o as lazyRequiredModuleExports, r as getOptionalModuleExports, t as defineModule } from "../module-
|
|
5
|
-
import { t as loadResources } from "../loadResources-
|
|
6
|
-
import { n as preloadResourcesAsync, t as preloadResources } from "../preloadResources-
|
|
1
|
+
/*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
|
|
2
|
+
import { r as mergeHealthChecks, t as healthPlugin } from "../health-CasG2A28.mjs";
|
|
3
|
+
import { _ as collectModuleScheduledJobs, a as developmentPreset, b as resolveModule, c as productionPreset, d as getModuleState, f as hasModule, g as collectModuleHealthChecks, h as describeResolvedModule, l as testingPreset, m as subscribeModuleEventHandlers, n as DEFAULT_LOGGER_REDACT_PATHS, o as edgePreset, p as orderModules, r as createApp, s as getPreset, t as ArcFactory, u as workerPreset, v as collectModuleWorkflows, y as resolveContribution } from "../createApp-CLGegqiG.mjs";
|
|
4
|
+
import { a as lazyModuleExports, i as hasModuleExports, n as getModuleExports, o as lazyRequiredModuleExports, r as getOptionalModuleExports, t as defineModule } from "../module-CwKsgZXp.mjs";
|
|
5
|
+
import { t as loadResources } from "../loadResources-Bj-aSsXi.mjs";
|
|
6
|
+
import { n as preloadResourcesAsync, t as preloadResources } from "../preloadResources-BkyqeTDz.mjs";
|
|
7
7
|
//#region src/factory/module/extend.ts
|
|
8
8
|
/** Concatenate two contributions, resolving factories only when arc asks. */
|
|
9
9
|
function mergeContribution(own, extra) {
|
|
@@ -244,4 +244,4 @@ function payloadTooLarge(limit) {
|
|
|
244
244
|
});
|
|
245
245
|
}
|
|
246
246
|
//#endregion
|
|
247
|
-
export { ArcFactory, collectModuleHealthChecks, collectModuleScheduledJobs, collectModuleWorkflows, createApp, createWorker, defineModule, describeResolvedModule, developmentPreset, edgePreset, extendModule, getModuleExports, getModuleState, getOptionalModuleExports, getPreset, hasModule, hasModuleExports, lazyModuleExports, lazyRequiredModuleExports, loadResources, orderModules, preloadResources, preloadResourcesAsync, productionPreset, resolveContribution, resolveModule, subscribeModuleEventHandlers, testingPreset, toFetchHandler };
|
|
247
|
+
export { ArcFactory, DEFAULT_LOGGER_REDACT_PATHS, collectModuleHealthChecks, collectModuleScheduledJobs, collectModuleWorkflows, createApp, createWorker, defineModule, describeResolvedModule, developmentPreset, edgePreset, extendModule, getModuleExports, getModuleState, getOptionalModuleExports, getPreset, hasModule, hasModuleExports, lazyModuleExports, lazyRequiredModuleExports, loadResources, orderModules, preloadResources, preloadResourcesAsync, productionPreset, resolveContribution, resolveModule, subscribeModuleEventHandlers, testingPreset, toFetchHandler };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
|
-
import {
|
|
2
|
+
import { on as HookSystem, z as ResourceRegistry } from "./index-BcR2bFZQ.mjs";
|
|
3
3
|
import { t as ExternalOpenApiPaths } from "./externalPaths-CmGOxOtD.mjs";
|
|
4
|
-
import { _ as HealthCheck, f as ScheduleDefinition, r as ArcModuleRegistry, t as ArcModule } from "./types-
|
|
5
|
-
import { s as ModuleState } from "./index-
|
|
4
|
+
import { _ as HealthCheck, f as ScheduleDefinition, r as ArcModuleRegistry, t as ArcModule } from "./types-BcTumAz_.mjs";
|
|
5
|
+
import { s as ModuleState } from "./index-C5NnMEKF.mjs";
|
|
6
6
|
import { FastifyPluginAsync } from "fastify";
|
|
7
7
|
//#region src/factory/module/descriptor.d.ts
|
|
8
8
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { t as pluralize } from "./pluralize-
|
|
1
|
+
/*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
|
|
2
|
+
import { t as pluralize } from "./pluralize-B7xf8qZF.mjs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
5
5
|
//#region src/cli/commands/generate/name-helpers.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { u as ValidationError } from "./errors-
|
|
1
|
+
/*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
|
|
2
|
+
import { u as ValidationError } from "./errors-Cd_yy7aW.mjs";
|
|
3
3
|
//#region src/utils/headers.ts
|
|
4
4
|
/**
|
|
5
5
|
* Canonical header typing + accessor.
|
package/dist/hooks/index.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
|
|
2
|
-
import {
|
|
2
|
+
import { an as HookRegistration, cn as afterCreate, dn as beforeCreate, en as DefineHookOptions, fn as beforeDelete, hn as defineHook, in as HookPhase, ln as afterDelete, mn as createHookSystem, nn as HookHandler, on as HookSystem, pn as beforeUpdate, rn as HookOperation, sn as HookSystemOptions, tn as HookContext, un as afterUpdate } from "../index-BcR2bFZQ.mjs";
|
|
3
3
|
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,3 +1,3 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
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
|
+
/*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
|
|
2
|
+
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-DqXkMXkB.mjs";
|
|
3
3
|
export { HookSystem, afterCreate, afterDelete, afterUpdate, beforeCreate, beforeDelete, beforeUpdate, createHookSystem, defineHook };
|
|
@@ -47,6 +47,22 @@ interface IdempotencyPluginOptions {
|
|
|
47
47
|
* Omit for the common case where the store is per-deployment.
|
|
48
48
|
*/
|
|
49
49
|
namespace?: string;
|
|
50
|
+
/**
|
|
51
|
+
* Boot-time store self-check (default: true). Writes one probe entry,
|
|
52
|
+
* verifies it reads back under ITS OWN key and NOT under a different key,
|
|
53
|
+
* then deletes it. Registration THROWS if the store fails — because the
|
|
54
|
+
* failure mode this catches is silent and catastrophic: a repository
|
|
55
|
+
* whose schema strips the key filter (observed live: a pathless Mongoose
|
|
56
|
+
* schema under `strictQuery: true`) collapses every idempotency key onto
|
|
57
|
+
* one shared row, and every request then replays the most recent cached
|
|
58
|
+
* response across keys AND across users. A store that cannot round-trip
|
|
59
|
+
* a key must never be allowed to serve traffic.
|
|
60
|
+
*
|
|
61
|
+
* Disable only for a store that genuinely cannot accept a probe write at
|
|
62
|
+
* boot — and if you disable it, the adapter's per-read identity checks
|
|
63
|
+
* remain as the runtime backstop.
|
|
64
|
+
*/
|
|
65
|
+
selfCheck?: boolean;
|
|
50
66
|
}
|
|
51
67
|
declare module "fastify" {
|
|
52
68
|
interface FastifyRequest {
|
|
@@ -92,6 +108,34 @@ declare const idempotencyPlugin: FastifyPluginAsync<IdempotencyPluginOptions>;
|
|
|
92
108
|
declare const _default: FastifyPluginAsync<IdempotencyPluginOptions>;
|
|
93
109
|
//#endregion
|
|
94
110
|
//#region src/idempotency/repository-idempotency-adapter.d.ts
|
|
111
|
+
/**
|
|
112
|
+
* The backing repository returned a document whose key does not match the
|
|
113
|
+
* key that was asked for — which means the repository is NOT applying the
|
|
114
|
+
* key filter. Concretely observed (2026-08-14, be-prod): a Mongoose schema
|
|
115
|
+
* with no declared paths (`new Schema({}, { _id: false })`) under a global
|
|
116
|
+
* `mongoose.set('strictQuery', true)` strips EVERY filter key as an
|
|
117
|
+
* "unknown path", so `getOne({ _id: key })` becomes `getOne({})` — one
|
|
118
|
+
* shared document then absorbs every idempotency key, and every request
|
|
119
|
+
* replays the most recent cached response ACROSS KEYS AND ACROSS USERS
|
|
120
|
+
* (a cancel response for order A was served as "success" for order B,
|
|
121
|
+
* which was never actually canceled).
|
|
122
|
+
*
|
|
123
|
+
* That failure mode is silent by construction — every read "succeeds" with
|
|
124
|
+
* a plausible document — so the adapter verifies the identity of every
|
|
125
|
+
* document it gets back and THROWS this instead of trusting it. Returning
|
|
126
|
+
* `undefined` (treat as miss) would be worse, not safer: the very next
|
|
127
|
+
* `tryLock`/`set` on the same broken repository would corrupt the shared
|
|
128
|
+
* document again.
|
|
129
|
+
*
|
|
130
|
+
* Fix on the host side: declare the key path on the schema (e.g.
|
|
131
|
+
* `_id: String`) and/or set `strictQuery: false` in the SCHEMA options so
|
|
132
|
+
* filters on it are never stripped — see `idempotencyPlugin`'s
|
|
133
|
+
* `repository` option docs.
|
|
134
|
+
*/
|
|
135
|
+
declare class IdempotencyStoreMisconfiguredError extends Error {
|
|
136
|
+
readonly code = "IDEMPOTENCY_STORE_MISCONFIGURED";
|
|
137
|
+
constructor(operation: string, expectedKey: string, actualKey: unknown);
|
|
138
|
+
}
|
|
95
139
|
declare function repositoryAsIdempotencyStore(repository: RepositoryLike, defaultTtlMs: number): IdempotencyStore;
|
|
96
140
|
//#endregion
|
|
97
141
|
//#region src/idempotency/stores/memory.d.ts
|
|
@@ -129,4 +173,4 @@ declare class MemoryIdempotencyStore implements IdempotencyStore {
|
|
|
129
173
|
private evictOldest;
|
|
130
174
|
}
|
|
131
175
|
//#endregion
|
|
132
|
-
export { type IdempotencyLock, type IdempotencyPluginOptions, type IdempotencyResult, type IdempotencyStore, MemoryIdempotencyStore, type MemoryIdempotencyStoreOptions, type RedisClient, type RedisIdempotencyStoreOptions, createIdempotencyResult, _default as idempotencyPlugin, idempotencyPlugin as idempotencyPluginFn, repositoryAsIdempotencyStore };
|
|
176
|
+
export { type IdempotencyLock, type IdempotencyPluginOptions, type IdempotencyResult, type IdempotencyStore, IdempotencyStoreMisconfiguredError, MemoryIdempotencyStore, type MemoryIdempotencyStoreOptions, type RedisClient, type RedisIdempotencyStoreOptions, createIdempotencyResult, _default as idempotencyPlugin, idempotencyPlugin as idempotencyPluginFn, repositoryAsIdempotencyStore };
|
|
@@ -1,12 +1,43 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { n as requireSingleHeaderValue } from "../headers-
|
|
3
|
-
import { n as createSafeGetOne, t as createIsDuplicateKeyError } from "../store-helpers-
|
|
4
|
-
import { t as createIdempotencyResult } from "../interface-
|
|
1
|
+
/*! @classytic/arc v2.34.0 | MIT | https://classytic.com */
|
|
2
|
+
import { n as requireSingleHeaderValue } from "../headers-CveNO9gR.mjs";
|
|
3
|
+
import { n as createSafeGetOne, t as createIsDuplicateKeyError } from "../store-helpers-B88p99Z2.mjs";
|
|
4
|
+
import { t as createIdempotencyResult } from "../interface-DznJrm9R.mjs";
|
|
5
5
|
import { and, eq, exists, gt, lt, or, startsWith } from "@classytic/repo-core/filter";
|
|
6
6
|
import { createHash } from "node:crypto";
|
|
7
7
|
import fp from "fastify-plugin";
|
|
8
8
|
import { update } from "@classytic/repo-core/update";
|
|
9
9
|
//#region src/idempotency/repository-idempotency-adapter.ts
|
|
10
|
+
/**
|
|
11
|
+
* The backing repository returned a document whose key does not match the
|
|
12
|
+
* key that was asked for — which means the repository is NOT applying the
|
|
13
|
+
* key filter. Concretely observed (2026-08-14, be-prod): a Mongoose schema
|
|
14
|
+
* with no declared paths (`new Schema({}, { _id: false })`) under a global
|
|
15
|
+
* `mongoose.set('strictQuery', true)` strips EVERY filter key as an
|
|
16
|
+
* "unknown path", so `getOne({ _id: key })` becomes `getOne({})` — one
|
|
17
|
+
* shared document then absorbs every idempotency key, and every request
|
|
18
|
+
* replays the most recent cached response ACROSS KEYS AND ACROSS USERS
|
|
19
|
+
* (a cancel response for order A was served as "success" for order B,
|
|
20
|
+
* which was never actually canceled).
|
|
21
|
+
*
|
|
22
|
+
* That failure mode is silent by construction — every read "succeeds" with
|
|
23
|
+
* a plausible document — so the adapter verifies the identity of every
|
|
24
|
+
* document it gets back and THROWS this instead of trusting it. Returning
|
|
25
|
+
* `undefined` (treat as miss) would be worse, not safer: the very next
|
|
26
|
+
* `tryLock`/`set` on the same broken repository would corrupt the shared
|
|
27
|
+
* document again.
|
|
28
|
+
*
|
|
29
|
+
* Fix on the host side: declare the key path on the schema (e.g.
|
|
30
|
+
* `_id: String`) and/or set `strictQuery: false` in the SCHEMA options so
|
|
31
|
+
* filters on it are never stripped — see `idempotencyPlugin`'s
|
|
32
|
+
* `repository` option docs.
|
|
33
|
+
*/
|
|
34
|
+
var IdempotencyStoreMisconfiguredError = class extends Error {
|
|
35
|
+
code = "IDEMPOTENCY_STORE_MISCONFIGURED";
|
|
36
|
+
constructor(operation, expectedKey, actualKey) {
|
|
37
|
+
super(`idempotency repository store: ${operation} for key '${expectedKey}' returned a document keyed '${String(actualKey)}' — the repository is not applying the key filter (commonly: a pathless Mongoose schema under strictQuery:true strips the filter to {}). Declare the key path on the schema (e.g. _id: String) and set strictQuery: false in the schema options. Refusing to serve cross-key results.`);
|
|
38
|
+
this.name = "IdempotencyStoreMisconfiguredError";
|
|
39
|
+
}
|
|
40
|
+
};
|
|
10
41
|
function repositoryAsIdempotencyStore(repository, defaultTtlMs) {
|
|
11
42
|
const missing = [];
|
|
12
43
|
if (typeof repository.getOne !== "function") missing.push("getOne");
|
|
@@ -17,11 +48,23 @@ function repositoryAsIdempotencyStore(repository, defaultTtlMs) {
|
|
|
17
48
|
const idField = repository.idField ?? "_id";
|
|
18
49
|
const isDuplicateKeyError = createIsDuplicateKeyError(repository);
|
|
19
50
|
const safeGetOne = createSafeGetOne(repository);
|
|
51
|
+
/**
|
|
52
|
+
* Every document read back MUST carry the key it was fetched by. A
|
|
53
|
+
* mismatch means the repository dropped the filter (see
|
|
54
|
+
* {@link IdempotencyStoreMisconfiguredError}) — fail loud, never serve
|
|
55
|
+
* or mutate a cross-key document.
|
|
56
|
+
*/
|
|
57
|
+
function assertKeyIdentity(operation, doc, expectedKey) {
|
|
58
|
+
const actual = doc[idField];
|
|
59
|
+
if (String(actual) !== expectedKey) throw new IdempotencyStoreMisconfiguredError(operation, expectedKey, actual);
|
|
60
|
+
}
|
|
20
61
|
return {
|
|
21
62
|
name: "repository",
|
|
22
63
|
async get(key) {
|
|
23
64
|
const doc = await safeGetOne(eq(idField, key));
|
|
24
|
-
if (!doc
|
|
65
|
+
if (!doc) return void 0;
|
|
66
|
+
assertKeyIdentity("get", doc, key);
|
|
67
|
+
if (!doc.result) return void 0;
|
|
25
68
|
if (new Date(doc.expiresAt) < /* @__PURE__ */ new Date()) return void 0;
|
|
26
69
|
return {
|
|
27
70
|
key,
|
|
@@ -33,7 +76,7 @@ function repositoryAsIdempotencyStore(repository, defaultTtlMs) {
|
|
|
33
76
|
};
|
|
34
77
|
},
|
|
35
78
|
async set(key, result) {
|
|
36
|
-
await r.findOneAndUpdate(eq(idField, key), update({
|
|
79
|
+
const doc = await r.findOneAndUpdate(eq(idField, key), update({
|
|
37
80
|
set: {
|
|
38
81
|
result: {
|
|
39
82
|
statusCode: result.statusCode,
|
|
@@ -43,11 +86,13 @@ function repositoryAsIdempotencyStore(repository, defaultTtlMs) {
|
|
|
43
86
|
createdAt: result.createdAt,
|
|
44
87
|
expiresAt: result.expiresAt
|
|
45
88
|
},
|
|
89
|
+
setOnInsert: { [idField]: key },
|
|
46
90
|
unset: ["lock"]
|
|
47
91
|
}), {
|
|
48
92
|
upsert: true,
|
|
49
93
|
returnDocument: "after"
|
|
50
94
|
});
|
|
95
|
+
if (doc) assertKeyIdentity("set", doc, key);
|
|
51
96
|
},
|
|
52
97
|
async tryLock(key, requestId, ttlMs) {
|
|
53
98
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -60,6 +105,7 @@ function repositoryAsIdempotencyStore(repository, defaultTtlMs) {
|
|
|
60
105
|
expiresAt: lockExpiresAt
|
|
61
106
|
} },
|
|
62
107
|
setOnInsert: {
|
|
108
|
+
[idField]: key,
|
|
63
109
|
createdAt: now,
|
|
64
110
|
expiresAt: docExpiresAt
|
|
65
111
|
}
|
|
@@ -67,6 +113,7 @@ function repositoryAsIdempotencyStore(repository, defaultTtlMs) {
|
|
|
67
113
|
upsert: true,
|
|
68
114
|
returnDocument: "after"
|
|
69
115
|
});
|
|
116
|
+
if (doc) assertKeyIdentity("tryLock", doc, key);
|
|
70
117
|
return doc !== null && doc !== void 0;
|
|
71
118
|
} catch (err) {
|
|
72
119
|
if (isDuplicateKeyError(err)) return false;
|
|
@@ -90,6 +137,7 @@ function repositoryAsIdempotencyStore(repository, defaultTtlMs) {
|
|
|
90
137
|
async findByPrefix(prefix) {
|
|
91
138
|
const doc = await safeGetOne(and(startsWith(idField, prefix, "sensitive"), exists("result", true), gt("expiresAt", /* @__PURE__ */ new Date())));
|
|
92
139
|
if (!doc?.result) return void 0;
|
|
140
|
+
if (!String(doc[idField] ?? "").startsWith(prefix)) throw new IdempotencyStoreMisconfiguredError("findByPrefix", prefix, doc[idField]);
|
|
93
141
|
return {
|
|
94
142
|
key: String(doc[idField] ?? prefix),
|
|
95
143
|
statusCode: doc.result.statusCode,
|
|
@@ -287,8 +335,42 @@ const idempotencyPlugin = async (fastify, opts = {}) => {
|
|
|
287
335
|
"POST",
|
|
288
336
|
"PUT",
|
|
289
337
|
"PATCH"
|
|
290
|
-
], include, exclude, repository, store: explicitStore, retryAfterSeconds = 1, namespace } = opts;
|
|
338
|
+
], include, exclude, repository, store: explicitStore, retryAfterSeconds = 1, namespace, selfCheck = true } = opts;
|
|
291
339
|
const store = repository ? repositoryAsIdempotencyStore(repository, ttlMs) : explicitStore ?? new MemoryIdempotencyStore({ ttlMs });
|
|
340
|
+
/**
|
|
341
|
+
* Who owns the store's lifecycle — arc closes ONLY what arc built.
|
|
342
|
+
*
|
|
343
|
+
* A host-supplied `store` may outlive this app: two arc apps in one process
|
|
344
|
+
* (a documented topology) can share one, and `MemoryIdempotencyStore.close()`
|
|
345
|
+
* CLEARS its maps. Closing on the first app's shutdown therefore wiped the
|
|
346
|
+
* second app's live idempotency records — replayable requests silently
|
|
347
|
+
* became re-executable. A store handed in from outside is the host's to
|
|
348
|
+
* close. The same rule now applies to the events transport and the
|
|
349
|
+
* query-cache store, which had the identical defect.
|
|
350
|
+
*
|
|
351
|
+
* The `repository` path builds its own adapter here, so arc owns that
|
|
352
|
+
* wrapper — but the adapter has no `close`, and the underlying repository
|
|
353
|
+
* (host-owned) is never touched.
|
|
354
|
+
*/
|
|
355
|
+
const ownsStore = !explicitStore;
|
|
356
|
+
if (enabled && selfCheck) {
|
|
357
|
+
const probeSuffix = createHash("sha256").update(`${process.pid}:${Date.now()}:${Math.random()}`).digest("hex").slice(0, 12);
|
|
358
|
+
const probeKeyA = `__arc_idempotency_selfcheck__:${probeSuffix}:a`;
|
|
359
|
+
const probeKeyB = `__arc_idempotency_selfcheck__:${probeSuffix}:b`;
|
|
360
|
+
/** Correctness verdicts rethrow; everything else degrades to a warning. */
|
|
361
|
+
class SelfCheckViolation extends Error {}
|
|
362
|
+
try {
|
|
363
|
+
await store.set(probeKeyA, createIdempotencyResult(299, { probe: true }, {}, 6e4));
|
|
364
|
+
const own = await store.get(probeKeyA);
|
|
365
|
+
if (!own || own.statusCode !== 299) fastify.log?.warn?.({ probe: "own-key" }, "idempotencyPlugin self-check: probe entry did not read back under its own key. This is usually the store being unreachable at boot (connection not ready), not a misconfiguration — continuing, with the adapter's per-read key-identity checks as the runtime backstop. If keyed requests later fail with IDEMPOTENCY_STORE_MISCONFIGURED, the store's key filter is being stripped (see IdempotencyStoreMisconfiguredError).");
|
|
366
|
+
else if (await store.get(probeKeyB)) throw new SelfCheckViolation("idempotencyPlugin self-check: a probe read under key B returned key A's entry — the store is ignoring the key filter, which in production replays cached responses across keys and users (observed cause: a pathless Mongoose schema under strictQuery:true strips every filter to {}). Declare the key path on the schema (e.g. _id: String) and set strictQuery: false in the schema options.");
|
|
367
|
+
} catch (err) {
|
|
368
|
+
if (err instanceof SelfCheckViolation || err?.code === "IDEMPOTENCY_STORE_MISCONFIGURED") throw err;
|
|
369
|
+
fastify.log?.warn?.({ err }, "idempotencyPlugin self-check could not complete (store unreachable at boot?) — continuing. The adapter's per-read key-identity checks remain the runtime backstop.");
|
|
370
|
+
} finally {
|
|
371
|
+
await store.deleteByPrefix(`__arc_idempotency_selfcheck__:${probeSuffix}:`).catch(() => {});
|
|
372
|
+
}
|
|
373
|
+
}
|
|
292
374
|
if (!enabled) {
|
|
293
375
|
fastify.decorate("idempotency", {
|
|
294
376
|
invalidate: async () => {},
|
|
@@ -431,7 +513,7 @@ const idempotencyPlugin = async (fastify, opts = {}) => {
|
|
|
431
513
|
await store.unlock(fullKey, request.id);
|
|
432
514
|
});
|
|
433
515
|
fastify.addHook("onClose", async () => {
|
|
434
|
-
await store.close?.();
|
|
516
|
+
if (ownsStore) await store.close?.();
|
|
435
517
|
});
|
|
436
518
|
fastify.log?.debug?.({
|
|
437
519
|
headerName,
|
|
@@ -444,4 +526,4 @@ var idempotencyPlugin_default = fp(idempotencyPlugin, {
|
|
|
444
526
|
fastify: "5.x"
|
|
445
527
|
});
|
|
446
528
|
//#endregion
|
|
447
|
-
export { MemoryIdempotencyStore, createIdempotencyResult, idempotencyPlugin_default as idempotencyPlugin, idempotencyPlugin as idempotencyPluginFn, repositoryAsIdempotencyStore };
|
|
529
|
+
export { IdempotencyStoreMisconfiguredError, MemoryIdempotencyStore, createIdempotencyResult, idempotencyPlugin_default as idempotencyPlugin, idempotencyPlugin as idempotencyPluginFn, repositoryAsIdempotencyStore };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
|
-
import { r as CacheStore, t as CacheLogger } from "./interface-BOk3YnTz.mjs";
|
|
3
2
|
import { i as RequestScope, n as Mandate } from "./types-ChuShpCP.mjs";
|
|
4
|
-
import {
|
|
3
|
+
import { l as PermissionCheck, s as AuthorizationDecision, u as PermissionContext } from "./base-Csjc2oF-.mjs";
|
|
4
|
+
import { r as CacheStore, t as CacheLogger } from "./interface-BOk3YnTz.mjs";
|
|
5
5
|
import { FastifyReply, FastifyRequest } from "fastify";
|
|
6
6
|
//#region src/permissions/agent.d.ts
|
|
7
7
|
/**
|
|
@@ -1021,6 +1021,16 @@ interface PermissionMatrixRegistry {
|
|
|
1021
1021
|
name: string;
|
|
1022
1022
|
permissions?: unknown;
|
|
1023
1023
|
}>;
|
|
1024
|
+
/**
|
|
1025
|
+
* Custom routes. Only those declaring `capability` are published — see the
|
|
1026
|
+
* loop in `introspectRegistry` for why a route needs an explicit name.
|
|
1027
|
+
*/
|
|
1028
|
+
customRoutes?: ReadonlyArray<{
|
|
1029
|
+
method: string;
|
|
1030
|
+
path: string;
|
|
1031
|
+
capability?: string;
|
|
1032
|
+
permissions?: unknown;
|
|
1033
|
+
}>;
|
|
1024
1034
|
}>;
|
|
1025
1035
|
}
|
|
1026
1036
|
interface PermissionMatrixOptions {
|