@classytic/arc 2.40.0 → 2.41.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/dist/{BaseController-BqJtbiUA.mjs → BaseController-DYJRZ0EJ.mjs} +18 -12
- package/dist/{EventTransport-BPOQsEer.d.mts → EventTransport-CbUKDzZZ.d.mts} +25 -0
- package/dist/{EventTransport-BUkTwY_x.mjs → EventTransport-n7qO5Cz3.mjs} +11 -2
- package/dist/{HookSystem-96nzZLmk.mjs → HookSystem-CxvZBo77.mjs} +2 -2
- package/dist/{ResourceRegistry-B9WnuG2Q.mjs → ResourceRegistry-Cu7uTJp9.mjs} +2 -2
- package/dist/{actionPermissions-4OGbe3Hf.mjs → actionPermissions-DPwPWPOV.mjs} +7 -6
- package/dist/audit/index.d.mts +2 -2
- package/dist/audit/index.mjs +10 -3
- package/dist/auth/audit.mjs +1 -1
- package/dist/auth/index.d.mts +2 -2
- package/dist/auth/index.mjs +12 -6
- package/dist/auth/redis-session.mjs +1 -1
- package/dist/{authorizationDecision-D_LFvMlm.mjs → authorizationDecision-2YY_Kaj1.mjs} +2 -2
- package/dist/{base-C-NL2fTi.d.mts → base-CxrV1LmG.d.mts} +10 -0
- package/dist/{buildHandler-BG_CHXqQ.mjs → buildHandler-CUhjGHGZ.mjs} +4 -4
- package/dist/cache/index.d.mts +4 -2
- package/dist/cache/index.mjs +4 -4
- package/dist/{caching-Bqcn3Brl.mjs → caching-DsWDjIxx.mjs} +2 -2
- package/dist/cleanup/index.d.mts +2 -2
- package/dist/cleanup/index.mjs +4 -4
- 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-BQ2FbhPB.mjs → constants-BxLgNFF7.mjs} +1 -1
- package/dist/context/index.mjs +36 -11
- package/dist/core/index.d.mts +2 -2
- package/dist/core/index.mjs +7 -7
- package/dist/{core-CsZR037F.mjs → core-iNGqYerO.mjs} +3 -3
- package/dist/{createActionRouter-BR93gCKg.mjs → createActionRouter-BBlbPs3k.mjs} +7 -7
- package/dist/{createAggregationRouter-CF40Aw95.mjs → createAggregationRouter-Dv5SuK2x.mjs} +7 -7
- package/dist/{createMcpServer-BVTs2S5G.d.mts → createMcpServer-CbDWkZ1T.d.mts} +1 -1
- package/dist/{defineAggregation-BDA2Tw7v.mjs → defineAggregation-UyeurGkp.mjs} +1 -1
- package/dist/{defineResource-DaIySrQr.mjs → defineResource-DzGT-2LP.mjs} +18 -18
- 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-CZy6n50b.mjs → elevation-BF-vhGxY.mjs} +4 -4
- package/dist/encryption/index.mjs +3 -3
- package/dist/{errorHandler-By9keRvX.mjs → errorHandler-CIMkCOWm.mjs} +3 -3
- package/dist/{errors-BHD3L8of.mjs → errors-C_YhELhe.mjs} +1 -1
- package/dist/{eventPlugin-DfHaKEWQ.d.mts → eventPlugin-B52abJ8W.d.mts} +1 -1
- package/dist/{eventPlugin-DB26V7uX.mjs → eventPlugin-CmXaPWLv.mjs} +5 -5
- package/dist/events/index.d.mts +4 -4
- package/dist/events/index.mjs +5 -5
- package/dist/events/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis-stream-entry.mjs +15 -6
- package/dist/events/transports/redis.d.mts +1 -1
- package/dist/events/transports/redis.mjs +2 -2
- package/dist/factory/index.d.mts +5 -5
- package/dist/factory/index.mjs +5 -5
- package/dist/{fastify-augmentation-HncZMmze.d.mts → fastify-augmentation-Cq2nHVaW.d.mts} +3 -3
- package/dist/{fields-fA-Dkou5.mjs → fields-BTyPLHK0.mjs} +1 -1
- package/dist/{generate-BSSdtiOy.mjs → generate-D_YmiCNf.mjs} +2 -2
- package/dist/{headers-BFEEshDS.mjs → headers-CNECDE6q.mjs} +2 -2
- package/dist/{health-BlGHjkqZ.mjs → health-CxQzbJmr.mjs} +10 -2
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.mjs +2 -2
- package/dist/idempotency/index.d.mts +1 -1
- package/dist/idempotency/index.mjs +4 -4
- package/dist/idempotency/redis.d.mts +1 -1
- package/dist/idempotency/redis.mjs +1 -1
- package/dist/{index-BtYoMip1.d.mts → index-BHdZD8zK.d.mts} +10 -2
- package/dist/{index-DbMglURO.d.mts → index-CFfLKMH4.d.mts} +1 -1
- package/dist/{index-eyg5WEcy.d.mts → index-CbJiYrfv.d.mts} +1 -1
- package/dist/{index-SCsOJxWB.d.mts → index-D4u76eQW.d.mts} +3 -3
- package/dist/{index-D3sIPcD4.d.mts → index-DHbyPo5j.d.mts} +6 -2
- package/dist/index.d.mts +5 -5
- package/dist/index.mjs +11 -11
- package/dist/{init-pl88PHzb.mjs → init-Y2MlSN9n.mjs} +1 -1
- 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 +2 -2
- package/dist/integrations/mcp/index.d.mts +4 -4
- package/dist/integrations/mcp/index.mjs +2 -2
- package/dist/integrations/mcp/testing.d.mts +2 -2
- package/dist/integrations/mcp/testing.mjs +2 -2
- package/dist/integrations/streamline.mjs +3 -3
- package/dist/integrations/webhooks.d.mts +2 -2
- package/dist/integrations/webhooks.mjs +3 -3
- package/dist/integrations/websocket-pushref-redis.d.mts +1 -1
- package/dist/integrations/websocket-pushref-redis.mjs +1 -1
- package/dist/integrations/websocket-redis.mjs +1 -1
- package/dist/integrations/websocket.mjs +12 -1
- package/dist/{interface-DjtFnZxH.mjs → interface-BIpgzbZl.mjs} +1 -1
- package/dist/{jsonBody-Dx6jH_Nb.mjs → jsonBody-Cq9KYl2Z.mjs} +2 -2
- package/dist/{keys-Ds3ekBiu.mjs → keys-Cmv4cBRa.mjs} +1 -1
- package/dist/{loadResources-E5UFlRrT.mjs → loadResources-CblF7xt2.mjs} +2 -2
- package/dist/{loadResourcesFromEntry-C2jrJbWG.mjs → loadResourcesFromEntry-99fIMC3p.mjs} +2 -2
- package/dist/logger/index.mjs +1 -1
- package/dist/{mcpPlugin-D-3OLxNz.mjs → mcpPlugin-xF3Gw-HW.mjs} +15 -15
- package/dist/{memory-CNvjxzB2.mjs → memory-CpDZ9NPw.mjs} +2 -2
- package/dist/{metrics-P37sNV5H.mjs → metrics-BaKnq8ag.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-CNcwCKUJ.mjs → module-BkQEesNQ.mjs} +1 -1
- package/dist/{multipartBody-Bl_gU3Wg.mjs → multipartBody-C92aJ8am.mjs} +1 -1
- package/dist/{openapi-BYrL8zvY.mjs → openapi-C3LFRzPq.mjs} +6 -6
- package/dist/outbox-admin/index.d.mts +2 -2
- package/dist/outbox-admin/index.mjs +4 -4
- package/dist/{outbox-module-CzsKRBvO.d.mts → outbox-module-BHdUnuuK.d.mts} +6 -2
- package/dist/{outbox-module-6DMC_WNu.mjs → outbox-module-dsCyLxXH.mjs} +9 -6
- package/dist/permissions/index.d.mts +2 -2
- package/dist/permissions/index.mjs +5 -5
- package/dist/{permissions-C0GpDsB_.mjs → permissions-DiHXy8Ck.mjs} +12 -6
- package/dist/{pipe-4_XamfxI.mjs → pipe-CBVmUJ-j.mjs} +2 -2
- package/dist/pipeline/index.d.mts +1 -1
- package/dist/pipeline/index.mjs +2 -2
- package/dist/plugins/index.d.mts +6 -36
- package/dist/plugins/index.mjs +33 -22
- package/dist/plugins/response-cache.mjs +9 -2
- package/dist/plugins/tracing-entry.mjs +2 -2
- package/dist/{pluralize-BaQ62hOW.mjs → pluralize-2_U6QZQg.mjs} +1 -1
- package/dist/{preloadResources-BAx5s9EF.mjs → preloadResources-Bbp4QJ8V.mjs} +33 -26
- package/dist/{preloadResources-DVgPCNcD.d.mts → preloadResources-CjS2OfpU.d.mts} +13 -8
- 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 +38 -1
- package/dist/presets/multiTenant.mjs +24 -6
- package/dist/presets/search.d.mts +2 -2
- package/dist/presets/search.mjs +2 -2
- package/dist/{presets-CAaqVVcW.mjs → presets-BdlugYTc.mjs} +4 -4
- package/dist/{projection-qbCOEvsh.mjs → projection-Uvgp-EEj.mjs} +2 -2
- package/dist/{queryCachePlugin-2Pp9w-8D.mjs → queryCachePlugin-B5F09bYr.mjs} +11 -5
- package/dist/{rateLimitKey-umrS6-vu.mjs → rateLimitKey-CK-EU2L8.mjs} +1 -1
- package/dist/{realtime-zzoNLDtj.mjs → realtime-FnnD0n3Z.mjs} +9 -9
- package/dist/{redis-CduhKsJi.d.mts → redis-Bzi1y3F9.d.mts} +10 -2
- package/dist/{redis-stream-DSsPyYzd.d.mts → redis-stream-BPKscsTB.d.mts} +6 -6
- package/dist/{registerRoute-_6zHiz0x.mjs → registerRoute-DRsSHPSM.mjs} +6 -6
- package/dist/registry/index.d.mts +2 -2
- package/dist/registry/index.mjs +3 -3
- package/dist/{registry-CEpoRpLP.mjs → registry-D3y8VEJ1.mjs} +2 -2
- package/dist/{renewingLease-B5Grm0pI.mjs → renewingLease-B3VYh5aU.mjs} +1 -1
- package/dist/{replyHelpers-9h-a592u.mjs → replyHelpers-DPHsdw-5.mjs} +2 -2
- package/dist/{requestContext-D4PuGhEw.mjs → requestContext-cSVKnYPk.mjs} +1 -1
- package/dist/{rolldown-runtime-DzE6ikSH.mjs → rolldown-runtime-DjDuyglE.mjs} +1 -1
- package/dist/{runtimeCapabilities-Bo7rSKjm.mjs → runtimeCapabilities-DSA_dH1_.mjs} +31 -5
- package/dist/{schedules-Dm21pqHU.mjs → schedules-BktJb3Y3.mjs} +4 -4
- package/dist/{schemaConverter-DENbixyA.mjs → schemaConverter-BLCSmNbr.mjs} +1 -1
- package/dist/{schemaIR-C2qUNzC6.mjs → schemaIR-K16Bb5BX.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-CdYxQVxt.mjs → scope-jSxuBTFM.mjs} +4 -4
- package/dist/{simpleEqualityMatcher-Cldubvul.mjs → simpleEqualityMatcher-BiOnyflP.mjs} +1 -1
- package/dist/{sse-DbyXoQun.mjs → sse-CH7Slxc1.mjs} +5 -5
- package/dist/{sseStream-BfZtL5-m.mjs → sseStream-CN-Lh1Tu.mjs} +2 -2
- package/dist/{store-helpers-BfyOd5i6.mjs → store-helpers-9DX9-1j_.mjs} +1 -1
- package/dist/{streaming-CFwCzEvU.mjs → streaming-dvppnxsr.mjs} +1 -1
- package/dist/{subscribe-helpers-KgVEcn8L.mjs → subscribe-helpers-AVYPgqTl.mjs} +2 -2
- package/dist/sync/changelog.mjs +1 -1
- package/dist/testing/cleanupStoreContract.mjs +1 -1
- package/dist/testing/index.d.mts +5 -5
- package/dist/testing/index.mjs +10 -10
- package/dist/testing/outboxStoreContract.mjs +1 -1
- package/dist/testing/storageContract.mjs +1 -1
- package/dist/{transactionContext-46KyUADP.mjs → transactionContext-DCWMI6hV.mjs} +1 -1
- package/dist/{typeGuards-t_CVgRXN.mjs → typeGuards-D7tHFdH6.mjs} +1 -1
- package/dist/types/index.d.mts +2 -2
- package/dist/types/index.mjs +1 -1
- package/dist/types/storage.mjs +1 -1
- package/dist/{types-CNQyOrLk.mjs → types-CDy3-zw1.mjs} +4 -4
- package/dist/{types-9rvxn5Ym.d.mts → types-CWQn9-IC.d.mts} +1 -1
- package/dist/{types-BVlowlm7.d.mts → types-DfVDvkdP.d.mts} +19 -1
- package/dist/usage/index.d.mts +58 -2
- package/dist/usage/index.mjs +55 -4
- package/dist/{userHelpers-DLueLQdQ.mjs → userHelpers-DDMOZ_Pm.mjs} +1 -1
- package/dist/utils/index.d.mts +107 -5
- package/dist/utils/index.mjs +12 -12
- package/dist/{utils-CUFBrhq-.mjs → utils-B-zj_b__.mjs} +50 -9
- package/dist/{validate-DV3hRbsz.mjs → validate-R0G_JrnK.mjs} +2 -2
- package/dist/{versioning-P3V6ATyC.d.mts → versioning-D6JIK8Tk.d.mts} +58 -2
- package/dist/{versioning-BXwmj5SD.mjs → versioning-DuVWcu-F.mjs} +3 -3
- package/dist/{workScope-CoGpuzDX.mjs → workScope-BhsWde4k.mjs} +3 -4
- package/package.json +574 -574
- package/skills/arc/SKILL.md +8 -4
- package/skills/arc/references/production.md +94 -9
package/dist/plugins/index.d.mts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
|
|
2
|
-
import { t as AnyRecord } from "../base-
|
|
3
|
-
import { At as RouteDefinition, J as PresetHook, Q as MiddlewareConfig, et as RouteSchemaOptions } from "../index-
|
|
2
|
+
import { t as AnyRecord } from "../base-CxrV1LmG.mjs";
|
|
3
|
+
import { At as RouteDefinition, J as PresetHook, Q as MiddlewareConfig, et as RouteSchemaOptions } from "../index-DHbyPo5j.mjs";
|
|
4
4
|
import { i as errorHandlerPlugin, n as ErrorMapper, r as defaultIsDuplicateKeyError, t as ErrorHandlerOptions } from "../errorHandler--4rSMMvq.mjs";
|
|
5
|
-
import { _ as HealthCheck, b as healthPlugin, f as ScheduleDefinition, g as schedulesPlugin, h as _default$8, m as SchedulesPluginOptions, p as ScheduleStats, v as HealthOptions, y as _default$3 } from "../types-
|
|
6
|
-
import { a as arcCorePlugin, i as _default, n as ArcCorePluginOptions, r as PluginMeta, t as ArcCore } from "../fastify-augmentation-
|
|
7
|
-
import { _ as CachingRule, a as MetricsCollector, c as metricsPlugin, d as _default$6, f as realtimePlugin, g as CachingOptions, h as ssePlugin, i as MetricEntry, l as ChangeOperation, m as _default$9, n as _default$10, o as MetricsOptions, p as SSEOptions, r as versioningPlugin, s as _default$4, t as VersioningOptions, u as RealtimeOptions, v as _default$1, y as cachingPlugin } from "../versioning-
|
|
5
|
+
import { _ as HealthCheck, b as healthPlugin, f as ScheduleDefinition, g as schedulesPlugin, h as _default$8, m as SchedulesPluginOptions, p as ScheduleStats, v as HealthOptions, y as _default$3 } from "../types-DfVDvkdP.mjs";
|
|
6
|
+
import { a as arcCorePlugin, i as _default, n as ArcCorePluginOptions, r as PluginMeta, t as ArcCore } from "../fastify-augmentation-Cq2nHVaW.mjs";
|
|
7
|
+
import { C as gracefulShutdownPlugin, S as _default$2, _ as CachingRule, a as MetricsCollector, b as GracefulShutdownOptions, c as metricsPlugin, d as _default$6, f as realtimePlugin, g as CachingOptions, h as ssePlugin, i as MetricEntry, l as ChangeOperation, m as _default$9, n as _default$10, o as MetricsOptions, p as SSEOptions, r as versioningPlugin, s as _default$4, t as VersioningOptions, u as RealtimeOptions, v as _default$1, x as ShutdownState, y as cachingPlugin } from "../versioning-D6JIK8Tk.mjs";
|
|
8
8
|
import { t as TracingOptions } from "../tracing-Dro5eH6j.mjs";
|
|
9
9
|
import { PaginatedResult } from "@classytic/repo-core/pagination";
|
|
10
10
|
import { FastifyInstance, FastifyPluginAsync } from "fastify";
|
|
@@ -59,36 +59,6 @@ interface ArcPlugin<TRootOpts extends AnyRecord = AnyRecord, TResourceOpts exten
|
|
|
59
59
|
*/
|
|
60
60
|
declare function createPlugin<TRootOpts extends AnyRecord = AnyRecord, TResourceOpts extends AnyRecord = AnyRecord>(name: string, definition: CreatePluginDefinition<TRootOpts, TResourceOpts>): ArcPlugin<TRootOpts, TResourceOpts>;
|
|
61
61
|
//#endregion
|
|
62
|
-
//#region src/plugins/gracefulShutdown.d.ts
|
|
63
|
-
interface GracefulShutdownOptions {
|
|
64
|
-
/** Maximum time to wait for graceful shutdown in ms (default: 30000) */
|
|
65
|
-
timeout?: number;
|
|
66
|
-
/** Custom cleanup function called before exit */
|
|
67
|
-
onShutdown?: () => Promise<void> | void;
|
|
68
|
-
/** Signals to handle (default: ['SIGTERM', 'SIGINT']) */
|
|
69
|
-
signals?: NodeJS.Signals[];
|
|
70
|
-
/** Whether to log shutdown events (default: true) */
|
|
71
|
-
logEvents?: boolean;
|
|
72
|
-
/**
|
|
73
|
-
* Called when shutdown times out or encounters an error.
|
|
74
|
-
* Defaults to `process.exit(1)` — appropriate for production but dangerous in:
|
|
75
|
-
* - **Tests**: kills the test runner. Pass `() => {}` or `() => { throw … }`.
|
|
76
|
-
* - **Shared runtimes** (e.g., serverless): may kill unrelated handlers.
|
|
77
|
-
*
|
|
78
|
-
* @param reason - `'timeout'` if shutdown exceeded `timeout` ms,
|
|
79
|
-
* `'error'` if `onShutdown` or `fastify.close()` threw.
|
|
80
|
-
*/
|
|
81
|
-
onForceExit?: (reason: "timeout" | "error") => void;
|
|
82
|
-
}
|
|
83
|
-
declare const gracefulShutdownPlugin: FastifyPluginAsync<GracefulShutdownOptions>;
|
|
84
|
-
declare module "fastify" {
|
|
85
|
-
interface FastifyInstance {
|
|
86
|
-
/** Trigger graceful shutdown manually */
|
|
87
|
-
shutdown: () => Promise<void>;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
declare const _default$2: FastifyPluginAsync<GracefulShutdownOptions>;
|
|
91
|
-
//#endregion
|
|
92
62
|
//#region src/plugins/pressure.d.ts
|
|
93
63
|
/**
|
|
94
64
|
* One measurable source of load, normalised by whoever owns it.
|
|
@@ -253,4 +223,4 @@ declare function createRequestIdGenerator(opts?: Pick<RequestIdOptions, "header"
|
|
|
253
223
|
declare const requestIdPlugin: FastifyPluginAsync<RequestIdOptions>;
|
|
254
224
|
declare const _default$7: FastifyPluginAsync<RequestIdOptions>;
|
|
255
225
|
//#endregion
|
|
256
|
-
export { type ArcCore, type ArcCorePluginOptions, type ArcPlugin, type CachingOptions, type CachingRule, type ChangeOperation, type CreatePluginDefinition, type ErrorHandlerOptions, type ErrorMapper, type GracefulShutdownOptions, type HealthCheck, type HealthOptions, type MetricEntry, type MetricsCollector, type MetricsOptions, type PluginMeta, type PluginResourceResult, type PressureApi, type PressureOptions, type PressureSignal, type PressureSnapshot, type PressureState, type PressureThresholds, type RealtimeOptions, type RequestIdOptions, type SSEOptions, type ScheduleDefinition, type ScheduleStats, type SchedulesPluginOptions, type TracingOptions, type VersioningOptions, _default as arcCorePlugin, arcCorePlugin as arcCorePluginFn, _default$1 as cachingPlugin, cachingPlugin as cachingPluginFn, createPlugin, createRequestIdGenerator, defaultIsDuplicateKeyError, errorHandlerPlugin, errorHandlerPlugin as errorHandlerPluginFn, _default$2 as gracefulShutdownPlugin, gracefulShutdownPlugin as gracefulShutdownPluginFn, _default$3 as healthPlugin, healthPlugin as healthPluginFn, _default$4 as metricsPlugin, metricsPlugin as metricsPluginFn, _default$5 as pressurePlugin, pressurePlugin as pressurePluginFn, _default$6 as realtimePlugin, realtimePlugin as realtimePluginFn, replyHelpersPlugin, _default$7 as requestIdPlugin, requestIdPlugin as requestIdPluginFn, sanitizeRequestId, _default$8 as schedulesPlugin, schedulesPlugin as schedulesPluginFn, _default$9 as ssePlugin, ssePlugin as ssePluginFn, _default$10 as versioningPlugin, versioningPlugin as versioningPluginFn };
|
|
226
|
+
export { type ArcCore, type ArcCorePluginOptions, type ArcPlugin, type CachingOptions, type CachingRule, type ChangeOperation, type CreatePluginDefinition, type ErrorHandlerOptions, type ErrorMapper, type GracefulShutdownOptions, type HealthCheck, type HealthOptions, type MetricEntry, type MetricsCollector, type MetricsOptions, type PluginMeta, type PluginResourceResult, type PressureApi, type PressureOptions, type PressureSignal, type PressureSnapshot, type PressureState, type PressureThresholds, type RealtimeOptions, type RequestIdOptions, type SSEOptions, type ScheduleDefinition, type ScheduleStats, type SchedulesPluginOptions, type ShutdownState, type TracingOptions, type VersioningOptions, _default as arcCorePlugin, arcCorePlugin as arcCorePluginFn, _default$1 as cachingPlugin, cachingPlugin as cachingPluginFn, createPlugin, createRequestIdGenerator, defaultIsDuplicateKeyError, errorHandlerPlugin, errorHandlerPlugin as errorHandlerPluginFn, _default$2 as gracefulShutdownPlugin, gracefulShutdownPlugin as gracefulShutdownPluginFn, _default$3 as healthPlugin, healthPlugin as healthPluginFn, _default$4 as metricsPlugin, metricsPlugin as metricsPluginFn, _default$5 as pressurePlugin, pressurePlugin as pressurePluginFn, _default$6 as realtimePlugin, realtimePlugin as realtimePluginFn, replyHelpersPlugin, _default$7 as requestIdPlugin, requestIdPlugin as requestIdPluginFn, sanitizeRequestId, _default$8 as schedulesPlugin, schedulesPlugin as schedulesPluginFn, _default$9 as ssePlugin, ssePlugin as ssePluginFn, _default$10 as versioningPlugin, versioningPlugin as versioningPluginFn };
|
package/dist/plugins/index.mjs
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { p as MUTATION_OPERATIONS } from "../constants-
|
|
1
|
+
/*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
|
|
2
|
+
import { p as MUTATION_OPERATIONS } from "../constants-BxLgNFF7.mjs";
|
|
3
3
|
import { arcLog } from "../logger/index.mjs";
|
|
4
|
-
import { c as getOrgId } from "../types-
|
|
5
|
-
import { n as requestContext } from "../requestContext-
|
|
6
|
-
import { t as hasEvents } from "../typeGuards-
|
|
7
|
-
import { t as HookSystem } from "../HookSystem-
|
|
8
|
-
import { t as ResourceRegistry } from "../ResourceRegistry-
|
|
9
|
-
import { a as requestIdPlugin, i as createRequestIdGenerator, n as health_default, o as requestId_default, s as sanitizeRequestId, t as healthPlugin } from "../health-
|
|
10
|
-
import { n as caching_default, t as cachingPlugin } from "../caching-
|
|
11
|
-
import { n as errorHandlerPlugin, t as defaultIsDuplicateKeyError } from "../errorHandler-
|
|
12
|
-
import { n as metrics_default, t as metricsPlugin } from "../metrics-
|
|
13
|
-
import { n as realtime_default, t as realtimePlugin } from "../realtime-
|
|
14
|
-
import { t as replyHelpersPlugin } from "../replyHelpers-
|
|
15
|
-
import { n as schedules_default, t as schedulesPlugin } from "../schedules-
|
|
16
|
-
import { n as sse_default, t as ssePlugin } from "../sse-
|
|
17
|
-
import { n as versioning_default, t as versioningPlugin } from "../versioning-
|
|
4
|
+
import { c as getOrgId } from "../types-CDy3-zw1.mjs";
|
|
5
|
+
import { n as requestContext } from "../requestContext-cSVKnYPk.mjs";
|
|
6
|
+
import { t as hasEvents } from "../typeGuards-D7tHFdH6.mjs";
|
|
7
|
+
import { t as HookSystem } from "../HookSystem-CxvZBo77.mjs";
|
|
8
|
+
import { t as ResourceRegistry } from "../ResourceRegistry-Cu7uTJp9.mjs";
|
|
9
|
+
import { a as requestIdPlugin, i as createRequestIdGenerator, n as health_default, o as requestId_default, s as sanitizeRequestId, t as healthPlugin } from "../health-CxQzbJmr.mjs";
|
|
10
|
+
import { n as caching_default, t as cachingPlugin } from "../caching-DsWDjIxx.mjs";
|
|
11
|
+
import { n as errorHandlerPlugin, t as defaultIsDuplicateKeyError } from "../errorHandler-CIMkCOWm.mjs";
|
|
12
|
+
import { n as metrics_default, t as metricsPlugin } from "../metrics-BaKnq8ag.mjs";
|
|
13
|
+
import { n as realtime_default, t as realtimePlugin } from "../realtime-FnnD0n3Z.mjs";
|
|
14
|
+
import { t as replyHelpersPlugin } from "../replyHelpers-DPHsdw-5.mjs";
|
|
15
|
+
import { n as schedules_default, t as schedulesPlugin } from "../schedules-BktJb3Y3.mjs";
|
|
16
|
+
import { n as sse_default, t as ssePlugin } from "../sse-CH7Slxc1.mjs";
|
|
17
|
+
import { n as versioning_default, t as versioningPlugin } from "../versioning-DuVWcu-F.mjs";
|
|
18
18
|
import fp from "fastify-plugin";
|
|
19
19
|
import { performance as performance$1 } from "node:perf_hooks";
|
|
20
20
|
//#region src/core/arcCorePlugin.ts
|
|
@@ -35,6 +35,7 @@ const arcCorePlugin = async (fastify, opts = {}) => {
|
|
|
35
35
|
for (const field of [
|
|
36
36
|
"_policyFilters",
|
|
37
37
|
"_ownershipCheck",
|
|
38
|
+
"_crossTenantRead",
|
|
38
39
|
"fieldMask",
|
|
39
40
|
"policyMetadata",
|
|
40
41
|
"document"
|
|
@@ -154,18 +155,20 @@ function createPlugin(name, definition) {
|
|
|
154
155
|
//#endregion
|
|
155
156
|
//#region src/plugins/gracefulShutdown.ts
|
|
156
157
|
const gracefulShutdownPlugin = async (fastify, opts = {}) => {
|
|
157
|
-
const { timeout = 3e4, onShutdown, signals = ["SIGTERM", "SIGINT"], logEvents = true, onForceExit = () => process.exit(1) } = opts;
|
|
158
|
-
|
|
158
|
+
const { timeout = 3e4, onShutdown, signals = ["SIGTERM", "SIGINT"], logEvents = true, drainDelayMs = 0, onForceExit = () => process.exit(1) } = opts;
|
|
159
|
+
const state = { draining: false };
|
|
159
160
|
const signalHandlers = /* @__PURE__ */ new Map();
|
|
160
161
|
const shutdown = async (signal) => {
|
|
161
|
-
if (
|
|
162
|
+
if (state.draining) {
|
|
162
163
|
if (logEvents) fastify.log?.warn?.({ signal }, "Shutdown already in progress, ignoring signal");
|
|
163
164
|
return;
|
|
164
165
|
}
|
|
165
|
-
|
|
166
|
+
state.draining = true;
|
|
167
|
+
state.since = /* @__PURE__ */ new Date();
|
|
166
168
|
if (logEvents) fastify.log?.info?.({
|
|
167
169
|
signal,
|
|
168
|
-
timeout
|
|
170
|
+
timeout,
|
|
171
|
+
drainDelayMs
|
|
169
172
|
}, "Shutdown signal received, starting graceful shutdown");
|
|
170
173
|
const forceExitTimer = setTimeout(() => {
|
|
171
174
|
if (logEvents) fastify.log?.error?.("Graceful shutdown timeout exceeded, forcing exit");
|
|
@@ -173,6 +176,10 @@ const gracefulShutdownPlugin = async (fastify, opts = {}) => {
|
|
|
173
176
|
}, timeout);
|
|
174
177
|
forceExitTimer.unref();
|
|
175
178
|
try {
|
|
179
|
+
if (drainDelayMs > 0) {
|
|
180
|
+
if (logEvents) fastify.log?.info?.({ drainDelayMs }, "Draining — readiness failing, still serving");
|
|
181
|
+
await new Promise((resolve) => setTimeout(resolve, drainDelayMs));
|
|
182
|
+
}
|
|
176
183
|
if (logEvents) fastify.log?.info?.("Closing server to new connections");
|
|
177
184
|
await fastify.close();
|
|
178
185
|
if (onShutdown) {
|
|
@@ -201,7 +208,11 @@ const gracefulShutdownPlugin = async (fastify, opts = {}) => {
|
|
|
201
208
|
fastify.decorate("shutdown", async () => {
|
|
202
209
|
await shutdown("MANUAL");
|
|
203
210
|
});
|
|
204
|
-
|
|
211
|
+
fastify.decorate("shutdownState", state);
|
|
212
|
+
if (logEvents) fastify.log?.debug?.({
|
|
213
|
+
signals,
|
|
214
|
+
drainDelayMs
|
|
215
|
+
}, "Graceful shutdown plugin registered");
|
|
205
216
|
};
|
|
206
217
|
var gracefulShutdown_default = fp(gracefulShutdownPlugin, {
|
|
207
218
|
name: "arc-graceful-shutdown",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import {
|
|
1
|
+
/*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
|
|
2
|
+
import { n as declareRuntimeCapability } from "../runtimeCapabilities-DSA_dH1_.mjs";
|
|
3
|
+
import { t as hasEvents } from "../typeGuards-D7tHFdH6.mjs";
|
|
3
4
|
import fp from "fastify-plugin";
|
|
4
5
|
//#region src/plugins/response-cache.ts
|
|
5
6
|
/**
|
|
@@ -96,6 +97,12 @@ const responseCachePluginImpl = async (fastify, opts = {}) => {
|
|
|
96
97
|
if (maxEntries > 5e3) fastify.log.warn(`[arc] responseCache maxEntries=${maxEntries}: prefix invalidation scans all entries synchronously on every mutating request — expect event-loop pauses at this size. This cache is an instance-local micro-cache; for large shared caching use the queryCache with a Redis store instead.`);
|
|
97
98
|
const cache = new LRUCache(maxEntries);
|
|
98
99
|
const invalidateMethods = new Set(invalidateOn.map((m) => m.toUpperCase()));
|
|
100
|
+
declareRuntimeCapability(fastify, {
|
|
101
|
+
subsystem: "http.response-cache",
|
|
102
|
+
durability: "memory",
|
|
103
|
+
accepted: true,
|
|
104
|
+
detail: "per-replica micro-cache; correctness comes from short TTLs, not shared state"
|
|
105
|
+
});
|
|
99
106
|
if (!fastify.hasRequestDecorator("__arcCacheTTL")) fastify.decorateRequest("__arcCacheTTL", void 0);
|
|
100
107
|
/** Find TTL for a given URL path (seconds) */
|
|
101
108
|
function getTTL(url) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
1
|
+
/*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import fp from "fastify-plugin";
|
|
4
4
|
//#region src/plugins/tracing.ts
|
|
@@ -59,7 +59,7 @@ try {
|
|
|
59
59
|
function createTracerProvider(options) {
|
|
60
60
|
if (!isAvailable || !NodeTracerProvider || !BatchSpanProcessor || !OTLPTraceExporter) return null;
|
|
61
61
|
const { serviceName = "@classytic/arc", serviceVersion, exporterUrl = "http://localhost:4318/v1/traces" } = options;
|
|
62
|
-
const resolvedVersion = serviceVersion ?? "2.
|
|
62
|
+
const resolvedVersion = serviceVersion ?? "2.41.0";
|
|
63
63
|
const exporter = new OTLPTraceExporter({ url: exporterUrl });
|
|
64
64
|
const provider = new NodeTracerProvider({ resource: { attributes: {
|
|
65
65
|
"service.name": serviceName,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { t as __exportAll } from "./rolldown-runtime-
|
|
1
|
+
/*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
|
|
2
|
+
import { t as __exportAll } from "./rolldown-runtime-DjDuyglE.mjs";
|
|
3
3
|
import { arcLog, configureArcLogger, createPinoWriter, enterArcLoggerScope, runWithArcLogger } from "./logger/index.mjs";
|
|
4
|
-
import { n as PUBLIC_SCOPE } from "./types-
|
|
5
|
-
import { t as auditRuntimeCapabilities } from "./runtimeCapabilities-
|
|
6
|
-
import { n as isScopeAwareKeyGenerator, t as createTenantKeyGenerator } from "./rateLimitKey-
|
|
7
|
-
import { i as createRequestIdGenerator, r as mergeHealthChecks } from "./health-
|
|
8
|
-
import { t as parseJsonBody } from "./jsonBody-
|
|
9
|
-
import { r as wrapWithBoundary } from "./subscribe-helpers-
|
|
4
|
+
import { n as PUBLIC_SCOPE } from "./types-CDy3-zw1.mjs";
|
|
5
|
+
import { r as initRuntimeCapabilityRegistry, t as auditRuntimeCapabilities } from "./runtimeCapabilities-DSA_dH1_.mjs";
|
|
6
|
+
import { n as isScopeAwareKeyGenerator, t as createTenantKeyGenerator } from "./rateLimitKey-CK-EU2L8.mjs";
|
|
7
|
+
import { i as createRequestIdGenerator, r as mergeHealthChecks } from "./health-CxQzbJmr.mjs";
|
|
8
|
+
import { t as parseJsonBody } from "./jsonBody-Cq9KYl2Z.mjs";
|
|
9
|
+
import { r as wrapWithBoundary } from "./subscribe-helpers-AVYPgqTl.mjs";
|
|
10
10
|
import { isProductionEnv } from "@classytic/primitives/environment";
|
|
11
11
|
import Fastify from "fastify";
|
|
12
12
|
import qs from "qs";
|
|
@@ -851,7 +851,7 @@ async function registerArcCore(fastify, config, trackPlugin) {
|
|
|
851
851
|
await fastify.register(arcCorePlugin, { emitEvents: config.arcPlugins?.emitEvents !== false });
|
|
852
852
|
trackPlugin("arc-core");
|
|
853
853
|
if (config.arcPlugins?.events !== false) {
|
|
854
|
-
const { default: eventPlugin } = await import("./eventPlugin-
|
|
854
|
+
const { default: eventPlugin } = await import("./eventPlugin-CmXaPWLv.mjs").then((n) => n.n);
|
|
855
855
|
const eventOpts = typeof config.arcPlugins?.events === "object" ? config.arcPlugins.events : {};
|
|
856
856
|
await fastify.register(eventPlugin, {
|
|
857
857
|
/**
|
|
@@ -906,19 +906,20 @@ async function registerArcPlugins(fastify, config, trackPlugin, modules, moduleH
|
|
|
906
906
|
trackPlugin("arc-health", { checkCount: healthOpts.checks?.length ?? 0 });
|
|
907
907
|
}
|
|
908
908
|
if (config.arcPlugins?.gracefulShutdown !== false) {
|
|
909
|
-
|
|
910
|
-
|
|
909
|
+
const shutdownOpts = typeof config.arcPlugins?.gracefulShutdown === "object" ? config.arcPlugins.gracefulShutdown : {};
|
|
910
|
+
await fastify.register(gracefulShutdownPlugin, shutdownOpts);
|
|
911
|
+
trackPlugin("arc-graceful-shutdown", shutdownOpts);
|
|
911
912
|
}
|
|
912
913
|
if (config.arcPlugins?.caching) {
|
|
913
|
-
const { default: cachingPlugin } = await import("./caching-
|
|
914
|
+
const { default: cachingPlugin } = await import("./caching-DsWDjIxx.mjs").then((n) => n.r);
|
|
914
915
|
const opts = config.arcPlugins.caching === true ? {} : config.arcPlugins.caching;
|
|
915
916
|
await fastify.register(cachingPlugin, opts);
|
|
916
917
|
trackPlugin("arc-caching", opts);
|
|
917
918
|
}
|
|
918
919
|
if (config.arcPlugins?.queryCache) {
|
|
919
|
-
const { queryCachePlugin } = await import("./queryCachePlugin-
|
|
920
|
+
const { queryCachePlugin } = await import("./queryCachePlugin-B5F09bYr.mjs").then((n) => n.n);
|
|
920
921
|
const opts = config.arcPlugins.queryCache === true ? {} : config.arcPlugins.queryCache;
|
|
921
|
-
const store = config.stores?.queryCache ?? new (await (import("./memory-
|
|
922
|
+
const store = config.stores?.queryCache ?? new (await (import("./memory-CpDZ9NPw.mjs").then((n) => n.n))).MemoryCacheStore();
|
|
922
923
|
await fastify.register(queryCachePlugin, {
|
|
923
924
|
store,
|
|
924
925
|
...opts
|
|
@@ -928,7 +929,7 @@ async function registerArcPlugins(fastify, config, trackPlugin, modules, moduleH
|
|
|
928
929
|
if (config.arcPlugins?.sse) {
|
|
929
930
|
if (config.arcPlugins?.events === false) fastify.log.warn("SSE plugin requires events plugin (arcPlugins.events). SSE disabled.");
|
|
930
931
|
else {
|
|
931
|
-
const { default: ssePlugin } = await import("./sse-
|
|
932
|
+
const { default: ssePlugin } = await import("./sse-CH7Slxc1.mjs").then((n) => n.r);
|
|
932
933
|
const opts = config.arcPlugins.sse === true ? {} : config.arcPlugins.sse;
|
|
933
934
|
await fastify.register(ssePlugin, opts);
|
|
934
935
|
trackPlugin("arc-sse", opts);
|
|
@@ -937,20 +938,20 @@ async function registerArcPlugins(fastify, config, trackPlugin, modules, moduleH
|
|
|
937
938
|
if (config.arcPlugins?.realtime) {
|
|
938
939
|
if (config.arcPlugins?.events === false) fastify.log.warn("Realtime plugin requires events plugin (arcPlugins.events). Realtime disabled.");
|
|
939
940
|
else {
|
|
940
|
-
const { default: realtimePlugin } = await import("./realtime-
|
|
941
|
+
const { default: realtimePlugin } = await import("./realtime-FnnD0n3Z.mjs").then((n) => n.r);
|
|
941
942
|
const opts = config.arcPlugins.realtime === true ? {} : config.arcPlugins.realtime;
|
|
942
943
|
await fastify.register(realtimePlugin, opts);
|
|
943
944
|
trackPlugin("arc-realtime", opts);
|
|
944
945
|
}
|
|
945
946
|
}
|
|
946
947
|
if (config.arcPlugins?.metrics) {
|
|
947
|
-
const { default: metricsPlugin } = await import("./metrics-
|
|
948
|
+
const { default: metricsPlugin } = await import("./metrics-BaKnq8ag.mjs").then((n) => n.r);
|
|
948
949
|
const opts = config.arcPlugins.metrics === true ? {} : config.arcPlugins.metrics;
|
|
949
950
|
await fastify.register(metricsPlugin, opts);
|
|
950
951
|
trackPlugin("arc-metrics", opts);
|
|
951
952
|
}
|
|
952
953
|
if (config.arcPlugins?.versioning) {
|
|
953
|
-
const { default: versioningPlugin } = await import("./versioning-
|
|
954
|
+
const { default: versioningPlugin } = await import("./versioning-DuVWcu-F.mjs").then((n) => n.r);
|
|
954
955
|
await fastify.register(versioningPlugin, config.arcPlugins.versioning);
|
|
955
956
|
trackPlugin("arc-versioning", config.arcPlugins.versioning);
|
|
956
957
|
}
|
|
@@ -1027,7 +1028,7 @@ async function registerAuth(fastify, config, trackPlugin) {
|
|
|
1027
1028
|
*/
|
|
1028
1029
|
async function registerElevation(fastify, config, trackPlugin) {
|
|
1029
1030
|
if (!config.elevation) return;
|
|
1030
|
-
const { elevationPlugin } = await import("./elevation-
|
|
1031
|
+
const { elevationPlugin } = await import("./elevation-BF-vhGxY.mjs").then((n) => n.r);
|
|
1031
1032
|
await fastify.register(elevationPlugin, config.elevation);
|
|
1032
1033
|
trackPlugin("arc-elevation", config.elevation);
|
|
1033
1034
|
fastify.log.debug("Elevation plugin enabled");
|
|
@@ -1042,7 +1043,7 @@ async function registerElevation(fastify, config, trackPlugin) {
|
|
|
1042
1043
|
*/
|
|
1043
1044
|
async function registerErrorHandler(fastify, config, trackPlugin, moduleErrorMappers) {
|
|
1044
1045
|
if (config.errorHandler === false) return;
|
|
1045
|
-
const { errorHandlerPlugin } = await import("./errorHandler-
|
|
1046
|
+
const { errorHandlerPlugin } = await import("./errorHandler-CIMkCOWm.mjs").then((n) => n.r);
|
|
1046
1047
|
/**
|
|
1047
1048
|
* DISCLOSURE DEFAULTS MERGE — they used to be REPLACED, and that was two bugs.
|
|
1048
1049
|
*
|
|
@@ -1266,7 +1267,7 @@ async function registerResources(fastify, config, preResolvedModules) {
|
|
|
1266
1267
|
let discoveryPath;
|
|
1267
1268
|
let discoveryYieldedZero = false;
|
|
1268
1269
|
if (resolvedResources === void 0 && config.resourceDir) {
|
|
1269
|
-
const { loadResources } = await import("./loadResources-
|
|
1270
|
+
const { loadResources } = await import("./loadResources-CblF7xt2.mjs").then((n) => n.n);
|
|
1270
1271
|
const { resolve, dirname } = await import("node:path");
|
|
1271
1272
|
const { fileURLToPath } = await import("node:url");
|
|
1272
1273
|
const rawDir = config.resourceDir;
|
|
@@ -1392,7 +1393,7 @@ Resources supplied by "${m.name}": ${provided}.`);
|
|
|
1392
1393
|
if (fastify.hasDecorator("getScheduleStats")) throw new Error("[arc] modules declare scheduledJobs but schedulesPlugin was already registered manually. Configure their runner through arcPlugins.schedules so Arc can compose one schedule table.");
|
|
1393
1394
|
const frozenJobs = Object.freeze(scheduledJobs.map((job) => Object.freeze({ ...job })));
|
|
1394
1395
|
const scheduleOptions = typeof config.arcPlugins?.schedules === "object" ? config.arcPlugins.schedules : {};
|
|
1395
|
-
const { default: schedulesPlugin } = await import("./schedules-
|
|
1396
|
+
const { default: schedulesPlugin } = await import("./schedules-BktJb3Y3.mjs").then((n) => n.r);
|
|
1396
1397
|
await fastify.register(schedulesPlugin, {
|
|
1397
1398
|
...scheduleOptions,
|
|
1398
1399
|
schedules: frozenJobs
|
|
@@ -1648,8 +1649,9 @@ async function registerSecurityPlugins(fastify, config) {
|
|
|
1648
1649
|
timeWindow: "1 minute"
|
|
1649
1650
|
});
|
|
1650
1651
|
await fastify.register(rateLimit, rateLimitOpts);
|
|
1651
|
-
|
|
1652
|
-
|
|
1652
|
+
const rateLimitRecord = typeof rateLimitOpts === "object" && rateLimitOpts !== null ? rateLimitOpts : void 0;
|
|
1653
|
+
if (!(rateLimitRecord !== void 0 && (rateLimitRecord.store != null || rateLimitRecord.redis != null))) {
|
|
1654
|
+
if (config.runtime === "distributed") throw new Error("[Arc] runtime: 'distributed' with rate limiting requires a shared store.\nProvide rateLimit: { redis: ioredisClient } (or { store: CustomStore }) or disable rate limiting: rateLimit: false");
|
|
1653
1655
|
else if (config.preset === "production") fastify.log.warn("Rate limiting is using in-memory store. In multi-instance deployments, each instance tracks limits independently. Configure a Redis store for distributed rate limiting.");
|
|
1654
1656
|
}
|
|
1655
1657
|
fastify.log.debug("Rate limiting enabled");
|
|
@@ -1790,6 +1792,7 @@ const DEFAULT_LOGGER_REDACT_PATHS = [
|
|
|
1790
1792
|
"req.headers.authorization",
|
|
1791
1793
|
"req.headers[\"x-api-key\"]",
|
|
1792
1794
|
"req.headers[\"x-internal-api-key\"]",
|
|
1795
|
+
"req.headers[\"x-device-token\"]",
|
|
1793
1796
|
"req.headers.cookie",
|
|
1794
1797
|
"req.headers[\"set-cookie\"]",
|
|
1795
1798
|
"res.headers[\"set-cookie\"]",
|
|
@@ -1861,7 +1864,10 @@ function validateDistributedRuntime(options) {
|
|
|
1861
1864
|
});
|
|
1862
1865
|
}
|
|
1863
1866
|
const schedules = options.arcPlugins?.schedules;
|
|
1864
|
-
if (schedules && typeof schedules === "object" && schedules.enabled !== false && !schedules.lock
|
|
1867
|
+
if (schedules && typeof schedules === "object" && schedules.enabled !== false && !schedules.lock && !schedules.singleReplica) missing.push({
|
|
1868
|
+
key: "arcPlugins.schedules.lock",
|
|
1869
|
+
hint: "a LockAdapter for single-firer leases (e.g. createMongoLockAdapter) — or `arcPlugins.schedules.singleReplica: true` if exactly one replica arms schedules"
|
|
1870
|
+
});
|
|
1865
1871
|
if (missing.length > 0) {
|
|
1866
1872
|
const lines = missing.map((m) => ` • ${m.key.padEnd(20)} → ${m.hint}`).join("\n");
|
|
1867
1873
|
throw new Error(`[Arc] runtime: 'distributed' requires durable (Redis/MongoDB) adapters, not memory.
|
|
@@ -1986,6 +1992,7 @@ async function buildApp(options, loggerScope, onInstance) {
|
|
|
1986
1992
|
} }
|
|
1987
1993
|
});
|
|
1988
1994
|
onInstance(fastify);
|
|
1995
|
+
initRuntimeCapabilityRegistry(fastify);
|
|
1989
1996
|
if (resolvedLogger !== false) {
|
|
1990
1997
|
const writer = createPinoWriter(fastify.log);
|
|
1991
1998
|
loggerScope.writer = writer;
|
|
@@ -2048,7 +2055,7 @@ async function buildApp(options, loggerScope, onInstance) {
|
|
|
2048
2055
|
await registerErrorHandler(fastify, config, trackPlugin, moduleErrorMappers);
|
|
2049
2056
|
await registerResources(fastify, config, resolvedModules);
|
|
2050
2057
|
if (config.replyHelpers) {
|
|
2051
|
-
const { replyHelpersPlugin } = await import("./replyHelpers-
|
|
2058
|
+
const { replyHelpersPlugin } = await import("./replyHelpers-DPHsdw-5.mjs").then((n) => n.n);
|
|
2052
2059
|
await fastify.register(replyHelpersPlugin);
|
|
2053
2060
|
}
|
|
2054
2061
|
if (config.serializeBigInt) {
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
|
|
2
|
-
import { It as Authenticator } from "./index-
|
|
2
|
+
import { It as Authenticator } from "./index-DHbyPo5j.mjs";
|
|
3
3
|
import { r as CacheStore } from "./interface-BOk3YnTz.mjs";
|
|
4
4
|
import { n as ElevationOptions } from "./elevation-BXCfVcNG.mjs";
|
|
5
|
-
import { a as EventTransport } from "./EventTransport-
|
|
5
|
+
import { a as EventTransport } from "./EventTransport-CbUKDzZZ.mjs";
|
|
6
6
|
import { t as ExternalOpenApiPaths } from "./externalPaths-CmGOxOtD.mjs";
|
|
7
7
|
import { r as QueryCachePluginOptions } from "./queryCachePlugin-BzqxconG.mjs";
|
|
8
8
|
import { t as ErrorHandlerOptions } from "./errorHandler--4rSMMvq.mjs";
|
|
9
|
-
import { l as ResourceLike, m as SchedulesPluginOptions, n as ArcModuleInput, v as HealthOptions } from "./types-
|
|
10
|
-
import "./index-
|
|
11
|
-
import { t as EventPluginOptions } from "./eventPlugin-
|
|
12
|
-
import { g as CachingOptions, o as MetricsOptions, p as SSEOptions, t as VersioningOptions, u as RealtimeOptions } from "./versioning-
|
|
9
|
+
import { l as ResourceLike, m as SchedulesPluginOptions, n as ArcModuleInput, v as HealthOptions } from "./types-DfVDvkdP.mjs";
|
|
10
|
+
import "./index-CFfLKMH4.mjs";
|
|
11
|
+
import { t as EventPluginOptions } from "./eventPlugin-B52abJ8W.mjs";
|
|
12
|
+
import { b as GracefulShutdownOptions, g as CachingOptions, o as MetricsOptions, p as SSEOptions, t as VersioningOptions, u as RealtimeOptions } from "./versioning-D6JIK8Tk.mjs";
|
|
13
13
|
import { r as IdempotencyStore } from "./interface-DEWNOMza.mjs";
|
|
14
14
|
import { FastifyInstance, FastifyPluginAsync, FastifyReply, FastifyRequest, FastifyServerOptions } from "fastify";
|
|
15
15
|
//#region src/factory/types/assets.d.ts
|
|
@@ -652,8 +652,13 @@ interface CreateAppOptions {
|
|
|
652
652
|
* ```
|
|
653
653
|
*/
|
|
654
654
|
health?: boolean | HealthOptions;
|
|
655
|
-
/**
|
|
656
|
-
|
|
655
|
+
/**
|
|
656
|
+
* Graceful shutdown handling (default: true). Pass `GracefulShutdownOptions`
|
|
657
|
+
* to configure it inline — in particular `drainDelayMs`, the lame-duck
|
|
658
|
+
* window behind a load balancer (readiness fails first, the server keeps
|
|
659
|
+
* serving until the LB has deregistered the instance, then closes).
|
|
660
|
+
*/
|
|
661
|
+
gracefulShutdown?: boolean | GracefulShutdownOptions;
|
|
657
662
|
/** Emit events for CRUD operations (default: true) */
|
|
658
663
|
emitEvents?: boolean;
|
|
659
664
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
import { i as RequestScope } from "../types-Ddl9OjmE.mjs";
|
|
3
|
-
import { l as PermissionCheck } from "../base-
|
|
4
|
-
import { Y as PresetResult } from "../index-
|
|
3
|
+
import { l as PermissionCheck } from "../base-CxrV1LmG.mjs";
|
|
4
|
+
import { Y as PresetResult } from "../index-DHbyPo5j.mjs";
|
|
5
5
|
import { a as StorageReadResult, i as StorageReadRange, n as StorageContext, o as StorageUploadInput, r as StorageFile, t as Storage } from "../storage-Cx9Sz3Ou.mjs";
|
|
6
6
|
//#region src/presets/filesUpload.d.ts
|
|
7
7
|
interface FilesUploadPresetRoutes {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { i as NotFoundError, u as ValidationError } from "../errors-
|
|
3
|
-
import { c as getOrgId, g as getUserId } from "../types-
|
|
4
|
-
import { B as requireAuth, F as allowPublic } from "../permissions-
|
|
5
|
-
import { t as multipartBody } from "../multipartBody-
|
|
1
|
+
/*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
|
|
2
|
+
import { i as NotFoundError, u as ValidationError } from "../errors-C_YhELhe.mjs";
|
|
3
|
+
import { c as getOrgId, g as getUserId } from "../types-CDy3-zw1.mjs";
|
|
4
|
+
import { B as requireAuth, F as allowPublic } from "../permissions-DiHXy8Ck.mjs";
|
|
5
|
+
import { t as multipartBody } from "../multipartBody-C92aJ8am.mjs";
|
|
6
6
|
//#region src/presets/filesUpload.ts
|
|
7
7
|
const DEFAULT_FIELD_NAME = "file";
|
|
8
8
|
const DEFAULT_MAX_FILE_SIZE = 10485760;
|
package/dist/presets/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
|
-
import { t as AnyRecord } from "../base-
|
|
3
|
-
import { Fn as IControllerResponse, In as IRequestContext, U as ResourceConfig, Y as PresetResult, d as PaginationResult } from "../index-
|
|
2
|
+
import { t as AnyRecord } from "../base-CxrV1LmG.mjs";
|
|
3
|
+
import { Fn as IControllerResponse, In as IRequestContext, U as ResourceConfig, Y as PresetResult, d as PaginationResult } from "../index-DHbyPo5j.mjs";
|
|
4
4
|
import { FilesUploadPresetOptions, FilesUploadPresetPermissions, FilesUploadPresetRoutes, filesUploadPreset } from "./filesUpload.mjs";
|
|
5
5
|
import { MultiTenantOptions, TenantFieldSpec, multiTenantPreset } from "./multiTenant.mjs";
|
|
6
6
|
import { SearchHandler, SearchPresetOptions, SearchRouteConfig, searchPreset } from "./search.mjs";
|
package/dist/presets/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
1
|
+
/*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
|
|
2
2
|
import { multiTenantPreset } from "./multiTenant.mjs";
|
|
3
|
-
import { a as registerPreset, c as auditedPreset, d as ownedByUserPreset, i as getPreset, l as softDeletePreset, n as flexibleMultiTenantPreset, o as treePreset, r as getAvailablePresets, s as bulkPreset, t as applyPresets, u as slugLookupPreset } from "../presets-
|
|
3
|
+
import { a as registerPreset, c as auditedPreset, d as ownedByUserPreset, i as getPreset, l as softDeletePreset, n as flexibleMultiTenantPreset, o as treePreset, r as getAvailablePresets, s as bulkPreset, t as applyPresets, u as slugLookupPreset } from "../presets-BdlugYTc.mjs";
|
|
4
4
|
import { filesUploadPreset } from "./filesUpload.mjs";
|
|
5
5
|
import { searchPreset } from "./search.mjs";
|
|
6
6
|
export { applyPresets, auditedPreset, bulkPreset, filesUploadPreset, flexibleMultiTenantPreset, getAvailablePresets, getPreset, multiTenantPreset, ownedByUserPreset, registerPreset, searchPreset, slugLookupPreset, softDeletePreset, treePreset };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import { X as CrudRouteKey, Y as PresetResult } from "../index-
|
|
2
|
+
import { X as CrudRouteKey, Y as PresetResult } from "../index-DHbyPo5j.mjs";
|
|
3
3
|
//#region src/presets/multiTenant.d.ts
|
|
4
4
|
/**
|
|
5
5
|
* One tenant dimension for multi-field filtering. Discriminated by source:
|
|
@@ -65,6 +65,43 @@ interface MultiTenantOptions {
|
|
|
65
65
|
* multiTenantPreset({ allowPublic: ['list', 'get'] })
|
|
66
66
|
*/
|
|
67
67
|
allowPublic?: CrudRouteKey[];
|
|
68
|
+
/**
|
|
69
|
+
* Reads that are NOT scoped to a tenant at all — a marketplace listing.
|
|
70
|
+
*
|
|
71
|
+
* `allowPublic` answers "may an anonymous caller reach this route?". That is a different
|
|
72
|
+
* question from "is this listing scoped to a tenant?", and until this option there was no way
|
|
73
|
+
* to answer the second one with "no". An `allowPublic` route still filters by the caller's
|
|
74
|
+
* organization whenever they have one, and a signed-in user of a multi-org product ALWAYS has
|
|
75
|
+
* one, because choosing an organization writes it onto the session. So a cross-tenant catalog
|
|
76
|
+
* silently became single-tenant the moment one of its own sellers browsed it: the same URL,
|
|
77
|
+
* with no header and no query parameter to explain the difference, returned a different world
|
|
78
|
+
* depending on who was asking.
|
|
79
|
+
*
|
|
80
|
+
* The only escape was to drop this preset from the resource entirely, which also drops tenant
|
|
81
|
+
* INJECTION on create/update — the thing that stops a member moving a document into another
|
|
82
|
+
* organization. Trading a write guarantee for a read behaviour is not a real choice.
|
|
83
|
+
*
|
|
84
|
+
* Listed routes get no tenant middleware: no filter, and nothing stashed for the repo layer.
|
|
85
|
+
* Everything else keeps its filter, so writes are unaffected.
|
|
86
|
+
*
|
|
87
|
+
* READS ONLY, by type. A cross-tenant `create` or `update` is not a listing, it is an escape
|
|
88
|
+
* from tenancy, and it should never be one option away by accident.
|
|
89
|
+
*
|
|
90
|
+
* THIS DOES NOT AUTHORIZE ANYTHING. Removing the tenant filter widens what the query can
|
|
91
|
+
* return, so the resource owes a row-level `policy` from its permission check saying what a
|
|
92
|
+
* stranger may see (`{ status: 'active' }`, `{ visibility: 'public' }`). Declaring this without
|
|
93
|
+
* one publishes every row in every tenant.
|
|
94
|
+
*
|
|
95
|
+
* @default []
|
|
96
|
+
* @example
|
|
97
|
+
* // A public catalog: anyone may browse every seller's LIVE products,
|
|
98
|
+
* // while create/update/delete stay pinned to the caller's own shop.
|
|
99
|
+
* multiTenantPreset({
|
|
100
|
+
* allowPublic: ['list', 'get'],
|
|
101
|
+
* crossTenant: ['list', 'get'],
|
|
102
|
+
* })
|
|
103
|
+
*/
|
|
104
|
+
crossTenant?: readonly Extract<CrudRouteKey, "list" | "get">[];
|
|
68
105
|
}
|
|
69
106
|
declare function multiTenantPreset(options?: MultiTenantOptions): PresetResult;
|
|
70
107
|
//#endregion
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import "../constants-
|
|
3
|
-
import { b as isElevated, c as getOrgId, d as getScopeContext, m as getTeamId, u as getRequestScope, v as hasOrgAccess } from "../types-
|
|
1
|
+
/*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
|
|
2
|
+
import "../constants-BxLgNFF7.mjs";
|
|
3
|
+
import { b as isElevated, c as getOrgId, d as getScopeContext, m as getTeamId, u as getRequestScope, v as hasOrgAccess } from "../types-CDy3-zw1.mjs";
|
|
4
4
|
//#region src/presets/multiTenant.ts
|
|
5
5
|
/**
|
|
6
6
|
* Resolve a single TenantFieldSpec against the current scope.
|
|
@@ -162,7 +162,7 @@ function createTenantInjection(specs) {
|
|
|
162
162
|
};
|
|
163
163
|
}
|
|
164
164
|
function multiTenantPreset(options = {}) {
|
|
165
|
-
const { tenantField, tenantFields, allowPublic = [] } = options;
|
|
165
|
+
const { tenantField, tenantFields, allowPublic = [], crossTenant = [] } = options;
|
|
166
166
|
if (tenantField !== void 0 && tenantFields !== void 0) throw new Error("multiTenantPreset: pass either `tenantField` (single-field) or `tenantFields` (multi-field), not both");
|
|
167
167
|
const specs = tenantFields ?? [{
|
|
168
168
|
field: tenantField ?? "organizationId",
|
|
@@ -173,6 +173,24 @@ function multiTenantPreset(options = {}) {
|
|
|
173
173
|
const flexibleTenantFilter = createFlexibleTenantFilter(specs);
|
|
174
174
|
const tenantInjection = createTenantInjection(specs);
|
|
175
175
|
const getFilter = (route) => allowPublic.includes(route) ? flexibleTenantFilter : strictTenantFilter;
|
|
176
|
+
/**
|
|
177
|
+
* A cross-tenant read MARKS the request rather than simply skipping the filter.
|
|
178
|
+
*
|
|
179
|
+
* Skipping is not enough, because this middleware is only the first of four places that scope a
|
|
180
|
+
* read, and the other three each re-derive the organization from the request scope on their own:
|
|
181
|
+
* `QueryResolver` adds the tenant filter for `list`, `buildTenantRepoOptions` forwards it to the
|
|
182
|
+
* repository as tenant context, and `checkOrgScope` re-checks it post-fetch on `get`. Removing
|
|
183
|
+
* one of four changes nothing observable, which is exactly what made this look unfixable from the
|
|
184
|
+
* preset: the listing stayed single-tenant no matter what the preset decided.
|
|
185
|
+
*
|
|
186
|
+
* So the decision travels on the request instead, and each of those layers honours it. The
|
|
187
|
+
* repository layer needs no change of its own — kits already accept `bypassTenant`, which is the
|
|
188
|
+
* same door elevated cross-tenant reads have always used.
|
|
189
|
+
*/
|
|
190
|
+
const markCrossTenantRead = async (request) => {
|
|
191
|
+
request._crossTenantRead = true;
|
|
192
|
+
};
|
|
193
|
+
const readMiddleware = (route) => crossTenant.includes(route) ? [markCrossTenantRead] : [getFilter(route)];
|
|
176
194
|
const fieldRules = {};
|
|
177
195
|
for (const spec of specs) fieldRules[spec.field] = {
|
|
178
196
|
systemManaged: true,
|
|
@@ -182,8 +200,8 @@ function multiTenantPreset(options = {}) {
|
|
|
182
200
|
name: "multiTenant",
|
|
183
201
|
schemaOptions: { fieldRules },
|
|
184
202
|
middlewares: {
|
|
185
|
-
list:
|
|
186
|
-
get:
|
|
203
|
+
list: readMiddleware("list"),
|
|
204
|
+
get: readMiddleware("get"),
|
|
187
205
|
create: [tenantInjection],
|
|
188
206
|
update: [getFilter("update"), tenantInjection],
|
|
189
207
|
delete: [getFilter("delete")],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
|
-
import { l as PermissionCheck } from "../base-
|
|
3
|
-
import { At as RouteDefinition, Y as PresetResult, jn as ControllerHandler, jt as RouteMcpConfig } from "../index-
|
|
2
|
+
import { l as PermissionCheck } from "../base-CxrV1LmG.mjs";
|
|
3
|
+
import { At as RouteDefinition, Y as PresetResult, jn as ControllerHandler, jt as RouteMcpConfig } from "../index-DHbyPo5j.mjs";
|
|
4
4
|
//#region src/presets/search.d.ts
|
|
5
5
|
/**
|
|
6
6
|
* Search Preset — backend-agnostic search / vector / embed routes
|
package/dist/presets/search.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { B as requireAuth, F as allowPublic } from "../permissions-
|
|
1
|
+
/*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
|
|
2
|
+
import { B as requireAuth, F as allowPublic } from "../permissions-DiHXy8Ck.mjs";
|
|
3
3
|
//#region src/presets/search.ts
|
|
4
4
|
const BUILTINS = [
|
|
5
5
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { l as UnauthorizedError } from "./errors-
|
|
3
|
-
import { b as isElevated, n as PUBLIC_SCOPE } from "./types-
|
|
4
|
-
import { B as requireAuth, F as allowPublic, U as requireRoles } from "./permissions-
|
|
1
|
+
/*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
|
|
2
|
+
import { l as UnauthorizedError } from "./errors-C_YhELhe.mjs";
|
|
3
|
+
import { b as isElevated, n as PUBLIC_SCOPE } from "./types-CDy3-zw1.mjs";
|
|
4
|
+
import { B as requireAuth, F as allowPublic, U as requireRoles } from "./permissions-DiHXy8Ck.mjs";
|
|
5
5
|
import { multiTenantPreset } from "./presets/multiTenant.mjs";
|
|
6
6
|
//#region src/presets/ownedByUser.ts
|
|
7
7
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { c as getOrgId, f as getScopeContextMap, g as getUserId, m as getTeamId, x as isMember } from "./types-
|
|
1
|
+
/*! @classytic/arc v2.41.0 | MIT | https://classytic.com */
|
|
2
|
+
import { c as getOrgId, f as getScopeContextMap, g as getUserId, m as getTeamId, x as isMember } from "./types-CDy3-zw1.mjs";
|
|
3
3
|
//#region src/scope/projection.ts
|
|
4
4
|
/**
|
|
5
5
|
* Compute the request-scope projection. Returns `undefined` when no
|