@classytic/arc 2.33.0 → 2.35.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-CaQC5EXX.mjs → BaseController-C-pofd0v.mjs} +131 -16
- package/dist/{EventTransport-tq4CEB-q.mjs → EventTransport-BrPeGUil.mjs} +1 -1
- package/dist/{HookSystem-DqXkMXkB.mjs → HookSystem-LlPm3Anm.mjs} +6 -4
- package/dist/{ResourceRegistry-DoALUlOO.mjs → ResourceRegistry-yuD1Ra53.mjs} +2 -2
- package/dist/{pipeline-q69DZzgG.mjs → actionPermissions-LFuOra7W.mjs} +30 -7
- 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 +6 -6
- package/dist/auth/redis-session.mjs +1 -1
- package/dist/{authorizationDecision-B3mP_QTy.mjs → authorizationDecision-DYXBBgtg.mjs} +6 -2
- package/dist/{base-Csjc2oF-.d.mts → base-GZU3LlzP.d.mts} +1 -1
- package/dist/{buildHandler-DLE9xX-V.mjs → buildHandler-Do9aMIvL.mjs} +4 -4
- package/dist/cache/index.mjs +4 -4
- package/dist/{caching-BcGmvnHh.mjs → caching-cN5X9VEL.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-BxCoxmiN.mjs → constants-BhzLXCfN.mjs} +1 -1
- package/dist/context/index.d.mts +16 -1
- package/dist/context/index.mjs +64 -4
- package/dist/core/index.d.mts +3 -3
- package/dist/core/index.mjs +8 -8
- package/dist/{core-dxhcHhUD.mjs → core-DdEvmmkY.mjs} +3 -3
- package/dist/{createActionRouter-DVpoA0do.mjs → createActionRouter-EYWgd0ly.mjs} +27 -64
- package/dist/{createAggregationRouter-B_B48JZ-.mjs → createAggregationRouter-ByOK9Iev.mjs} +7 -7
- package/dist/defineAggregation-DoIijIFq.mjs +25 -0
- package/dist/{defineResource-DR9vsUYy.mjs → defineResource-BOrGeocE.mjs} +62 -66
- 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-B0tlY8y1.mjs → elevation-tGIAldco.mjs} +4 -4
- package/dist/encryption/index.mjs +3 -3
- package/dist/{errorHandler-C7xBqHsI.mjs → errorHandler-BbQ1nQdk.mjs} +3 -3
- package/dist/{errors-Cd_yy7aW.mjs → errors-CLid6atr.mjs} +1 -1
- package/dist/{eventPlugin-DSNEZWfV.d.mts → eventPlugin-B47sfCJ8.d.mts} +1 -1
- package/dist/{eventPlugin-Dar8qRaj.mjs → eventPlugin-ClPn5kjn.mjs} +5 -5
- package/dist/events/index.d.mts +2 -2
- package/dist/events/index.mjs +5 -5
- package/dist/events/transports/redis-stream-entry.mjs +1 -1
- package/dist/events/transports/redis.mjs +1 -1
- package/dist/factory/index.d.mts +5 -5
- package/dist/factory/index.mjs +5 -6
- package/dist/{fastify-augmentation-DVsTAy6X.d.mts → fastify-augmentation-CMMTL3cj.d.mts} +3 -3
- package/dist/{fields-CojeUkS4.mjs → fields-UtpiJO5R.mjs} +1 -1
- package/dist/{generate-DiB0nHPR.mjs → generate-BoAVy3_b.mjs} +2 -2
- package/dist/{headers-CveNO9gR.mjs → headers-DODWf7aC.mjs} +2 -2
- package/dist/{health-CasG2A28.mjs → health-_Zs3R_Sb.mjs} +1 -1
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.mjs +2 -2
- package/dist/idempotency/index.mjs +23 -58
- package/dist/idempotency/redis.mjs +1 -1
- package/dist/{index-C5NnMEKF.d.mts → index-C50BUxKs.d.mts} +1 -1
- package/dist/{index-BcR2bFZQ.d.mts → index-C5K78SXo.d.mts} +33 -105
- package/dist/{index-ugr1tQlW.d.mts → index-CJCcbADG.d.mts} +1 -1
- package/dist/{index-B-DvUzsr.d.mts → index-K7auNNW0.d.mts} +2 -2
- package/dist/{index-Brin0ODU.d.mts → index-h-mTgMqy.d.mts} +21 -31
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +12 -12
- package/dist/{init-mdJ-v4Xp.mjs → init-Ce4R0ZGK.mjs} +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 +1 -1
- package/dist/integrations/mcp/testing.mjs +3 -3
- package/dist/integrations/streamline.mjs +3 -3
- package/dist/integrations/webhooks.d.mts +1 -1
- package/dist/integrations/webhooks.mjs +11 -24
- 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-DznJrm9R.mjs → interface-my7sxjw5.mjs} +1 -1
- package/dist/{jsonBody-CfGH-GxO.mjs → jsonBody-CVKA7C5m.mjs} +2 -2
- package/dist/{keys-WeKvY1dE.mjs → keys-GlU7XpmG.mjs} +1 -1
- package/dist/{loadResources-Bj-aSsXi.mjs → loadResources-DdQb0qgV.mjs} +2 -2
- package/dist/{loadResourcesFromEntry-DwaxNcE2.mjs → loadResourcesFromEntry-s6aGs6-0.mjs} +2 -2
- package/dist/logger/index.d.mts +23 -4
- package/dist/logger/index.mjs +50 -7
- package/dist/{mcpPlugin-aJg5TqHi.mjs → mcpPlugin-DkzZ7Nfx.mjs} +15 -16
- package/dist/{memory-qYSB7rMQ.mjs → memory-BwedEXau.mjs} +2 -2
- package/dist/{metrics-D7uchLjN.mjs → metrics-5LNPvL3P.mjs} +2 -2
- package/dist/middleware/index.d.mts +1 -1
- package/dist/middleware/index.mjs +3 -3
- package/dist/migrations/index.mjs +7 -4
- package/dist/{module-CwKsgZXp.mjs → module-Bh5OC7ww.mjs} +1 -1
- package/dist/{multipartBody-4w-S3-PU.mjs → multipartBody-DjilSDAT.mjs} +1 -1
- package/dist/{openapi-BN5cQaO2.mjs → openapi-ItLH12_L.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 → outbox-module-SGIZz6oS.mjs} +14 -5
- package/dist/{outbox-module-D-VFq37T.d.mts → outbox-module-b1TyDGGi.d.mts} +40 -3
- package/dist/permissions/index.d.mts +2 -2
- package/dist/permissions/index.mjs +5 -5
- package/dist/{permissions-BAfwgBxc.mjs → permissions-CpSBlFXZ.mjs} +6 -6
- package/dist/{pipe-BzzoEhHj.mjs → pipe-DNOuCfAs.mjs} +2 -2
- package/dist/pipeline/index.d.mts +1 -1
- package/dist/pipeline/index.mjs +2 -2
- package/dist/plugins/index.d.mts +92 -7
- package/dist/plugins/index.mjs +168 -17
- package/dist/plugins/response-cache.mjs +2 -2
- package/dist/plugins/tracing-entry.mjs +2 -2
- package/dist/{pluralize-B7xf8qZF.mjs → pluralize-DGAQQKL8.mjs} +1 -1
- package/dist/{preloadResources-g07ldtzh.d.mts → preloadResources--ZtY9pe9.d.mts} +54 -270
- package/dist/{createApp-CLGegqiG.mjs → preloadResources-DYMzmUk1.mjs} +112 -31
- package/dist/presets/filesUpload.d.mts +3 -3
- 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 +9 -47
- package/dist/presets/search.mjs +2 -2
- package/dist/{presets-D-h0uWtP.mjs → presets-Bi0Z6Iq8.mjs} +4 -4
- package/dist/{projection-BKM0Ui-s.mjs → projection-aevMua7Q.mjs} +2 -2
- package/dist/{queryCachePlugin-DhsZ0ZIc.mjs → queryCachePlugin-BI7Z88Cx.mjs} +5 -5
- package/dist/{rateLimitKey-XngqVNEV.mjs → rateLimitKey-pyevMUVf.mjs} +1 -1
- package/dist/{realtime-CTkv3O59.mjs → realtime-Cfl2bVjj.mjs} +9 -9
- package/dist/{rateLimit-D4-ASwsI.mjs → registerRoute-u1opU66a.mjs} +114 -3
- package/dist/registry/index.d.mts +2 -2
- package/dist/registry/index.mjs +3 -3
- package/dist/{registry-CLxCR5LF.mjs → registry-B4sf9Rfm.mjs} +15 -56
- package/dist/{renewingLease-BnWtbA2U.mjs → renewingLease-5ESPMxp0.mjs} +14 -2
- package/dist/{replyHelpers-BSBVCwL3.mjs → replyHelpers-2jfmMnnV.mjs} +2 -2
- package/dist/{requestContext-uYE35JxI.mjs → requestContext-DzOUGNdY.mjs} +1 -1
- package/dist/{rolldown-runtime-DNg-KNCk.mjs → rolldown-runtime-CEvvVXTC.mjs} +1 -1
- package/dist/{runtimeCapabilities-Dm88DaTW.mjs → runtimeCapabilities-BagWc3TI.mjs} +1 -1
- package/dist/{schedules-CAcZgia0.mjs → schedules-BLpZLWGF.mjs} +6 -4
- package/dist/{schemaConverter-XH1RZRyu.mjs → schemaConverter-D2_bHGil.mjs} +19 -32
- package/dist/{schemaIR-CDvclAew.mjs → schemaIR-s3-ouZmP.mjs} +2 -2
- package/dist/schemas/index.mjs +1 -1
- package/dist/scim/index.mjs +2 -2
- package/dist/scope/index.d.mts +1 -1
- package/dist/scope/index.mjs +5 -5
- package/dist/{scope-BaWcqBvr.mjs → scope-DgepeCv6.mjs} +4 -4
- package/dist/simpleEqualityMatcher-BO-sFTQf.mjs +43 -0
- package/dist/{sse-Cf0jUHsh.mjs → sse-DUIP1XH6.mjs} +5 -5
- package/dist/{sseStream-Bvpi-UXQ.mjs → sseStream-ByFGyIVr.mjs} +2 -2
- package/dist/{store-helpers-B88p99Z2.mjs → store-helpers-kIJCY0wI.mjs} +1 -1
- package/dist/{streaming-DsT1B5zJ.mjs → streaming-DOpZVht6.mjs} +1 -1
- package/dist/{subscribe-helpers-CLIOHsOK.mjs → subscribe-helpers-Dh2BnzJf.mjs} +12 -46
- package/dist/sync/changelog.mjs +1 -1
- package/dist/testing/cleanupStoreContract.mjs +1 -1
- package/dist/testing/index.d.mts +6 -6
- package/dist/testing/index.mjs +10 -11
- package/dist/testing/outboxStoreContract.mjs +1 -1
- package/dist/testing/storageContract.mjs +1 -1
- package/dist/{transactionContext-BYtWnwAS.mjs → transactionContext-BTZzEcRo.mjs} +1 -1
- package/dist/{typeGuards-jjKJDN13.mjs → typeGuards-B-_jqaMi.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-BcTumAz_.d.mts → types-DDD5RKTu.d.mts} +30 -87
- package/dist/{types-BfC83KsP.d.mts → types-DSvHH0uR.d.mts} +1 -1
- package/dist/{types-ChuShpCP.d.mts → types-Ddl9OjmE.d.mts} +18 -121
- package/dist/{types-CoqIRrkY.mjs → types-GY4kATJb.mjs} +10 -53
- package/dist/usage/index.d.mts +2 -2
- package/dist/usage/index.mjs +0 -0
- package/dist/{userHelpers-CWF5pbZD.mjs → userHelpers-AKcB4V03.mjs} +1 -1
- package/dist/utils/index.d.mts +16 -42
- package/dist/utils/index.mjs +11 -11
- package/dist/{utils-h1V_sT-t.mjs → utils-CBK9HQOI.mjs} +3 -3
- package/dist/{validate-CdQlz52F.mjs → validate-dosAIvQU.mjs} +2 -2
- package/dist/{versioning-rZbyLVD-.mjs → versioning-BbTs4pwM.mjs} +3 -3
- package/package.json +8 -8
- package/skills/arc/SKILL.md +9 -9
- package/skills/arc/references/api-reference.md +1 -1
- package/dist/actionPermissions-CUeCmpUd.mjs +0 -25
- package/dist/defineAggregation-Nv-DwfOf.mjs +0 -48
- package/dist/preloadResources-BkyqeTDz.mjs +0 -46
- package/dist/registerRoute-DNnd3vkz.mjs +0 -113
- package/dist/repositoryFilter-DKny7PDn.mjs +0 -45
- package/dist/simpleEqualityMatcher-Se8VrsaP.mjs +0 -69
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { t as __exportAll } from "./rolldown-runtime-
|
|
3
|
-
import { arcLog, configureArcLogger, createPinoWriter } from "./logger/index.mjs";
|
|
4
|
-
import { n as PUBLIC_SCOPE } from "./types-
|
|
5
|
-
import { t as auditRuntimeCapabilities } from "./runtimeCapabilities-
|
|
6
|
-
import { 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-
|
|
1
|
+
/*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
|
|
2
|
+
import { t as __exportAll } from "./rolldown-runtime-CEvvVXTC.mjs";
|
|
3
|
+
import { arcLog, configureArcLogger, createPinoWriter, enterArcLoggerScope, runWithArcLogger } from "./logger/index.mjs";
|
|
4
|
+
import { n as PUBLIC_SCOPE } from "./types-GY4kATJb.mjs";
|
|
5
|
+
import { t as auditRuntimeCapabilities } from "./runtimeCapabilities-BagWc3TI.mjs";
|
|
6
|
+
import { t as createTenantKeyGenerator } from "./rateLimitKey-pyevMUVf.mjs";
|
|
7
|
+
import { i as createRequestIdGenerator, r as mergeHealthChecks } from "./health-_Zs3R_Sb.mjs";
|
|
8
|
+
import { t as parseJsonBody } from "./jsonBody-CVKA7C5m.mjs";
|
|
9
|
+
import { r as wrapWithBoundary } from "./subscribe-helpers-Dh2BnzJf.mjs";
|
|
10
10
|
import { isProductionEnv } from "@classytic/primitives/environment";
|
|
11
11
|
import Fastify from "fastify";
|
|
12
12
|
import qs from "qs";
|
|
@@ -801,7 +801,7 @@ async function registerArcCore(fastify, config, trackPlugin) {
|
|
|
801
801
|
await fastify.register(arcCorePlugin, { emitEvents: config.arcPlugins?.emitEvents !== false });
|
|
802
802
|
trackPlugin("arc-core");
|
|
803
803
|
if (config.arcPlugins?.events !== false) {
|
|
804
|
-
const { default: eventPlugin } = await import("./eventPlugin-
|
|
804
|
+
const { default: eventPlugin } = await import("./eventPlugin-ClPn5kjn.mjs").then((n) => n.n);
|
|
805
805
|
const eventOpts = typeof config.arcPlugins?.events === "object" ? config.arcPlugins.events : {};
|
|
806
806
|
await fastify.register(eventPlugin, {
|
|
807
807
|
/**
|
|
@@ -860,15 +860,15 @@ async function registerArcPlugins(fastify, config, trackPlugin, modules, moduleH
|
|
|
860
860
|
trackPlugin("arc-graceful-shutdown");
|
|
861
861
|
}
|
|
862
862
|
if (config.arcPlugins?.caching) {
|
|
863
|
-
const { default: cachingPlugin } = await import("./caching-
|
|
863
|
+
const { default: cachingPlugin } = await import("./caching-cN5X9VEL.mjs").then((n) => n.r);
|
|
864
864
|
const opts = config.arcPlugins.caching === true ? {} : config.arcPlugins.caching;
|
|
865
865
|
await fastify.register(cachingPlugin, opts);
|
|
866
866
|
trackPlugin("arc-caching", opts);
|
|
867
867
|
}
|
|
868
868
|
if (config.arcPlugins?.queryCache) {
|
|
869
|
-
const { queryCachePlugin } = await import("./queryCachePlugin-
|
|
869
|
+
const { queryCachePlugin } = await import("./queryCachePlugin-BI7Z88Cx.mjs").then((n) => n.n);
|
|
870
870
|
const opts = config.arcPlugins.queryCache === true ? {} : config.arcPlugins.queryCache;
|
|
871
|
-
const store = config.stores?.queryCache ?? new (await (import("./memory-
|
|
871
|
+
const store = config.stores?.queryCache ?? new (await (import("./memory-BwedEXau.mjs").then((n) => n.n))).MemoryCacheStore();
|
|
872
872
|
await fastify.register(queryCachePlugin, {
|
|
873
873
|
store,
|
|
874
874
|
...opts
|
|
@@ -878,7 +878,7 @@ async function registerArcPlugins(fastify, config, trackPlugin, modules, moduleH
|
|
|
878
878
|
if (config.arcPlugins?.sse) {
|
|
879
879
|
if (config.arcPlugins?.events === false) fastify.log.warn("SSE plugin requires events plugin (arcPlugins.events). SSE disabled.");
|
|
880
880
|
else {
|
|
881
|
-
const { default: ssePlugin } = await import("./sse-
|
|
881
|
+
const { default: ssePlugin } = await import("./sse-DUIP1XH6.mjs").then((n) => n.r);
|
|
882
882
|
const opts = config.arcPlugins.sse === true ? {} : config.arcPlugins.sse;
|
|
883
883
|
await fastify.register(ssePlugin, opts);
|
|
884
884
|
trackPlugin("arc-sse", opts);
|
|
@@ -887,20 +887,20 @@ async function registerArcPlugins(fastify, config, trackPlugin, modules, moduleH
|
|
|
887
887
|
if (config.arcPlugins?.realtime) {
|
|
888
888
|
if (config.arcPlugins?.events === false) fastify.log.warn("Realtime plugin requires events plugin (arcPlugins.events). Realtime disabled.");
|
|
889
889
|
else {
|
|
890
|
-
const { default: realtimePlugin } = await import("./realtime-
|
|
890
|
+
const { default: realtimePlugin } = await import("./realtime-Cfl2bVjj.mjs").then((n) => n.r);
|
|
891
891
|
const opts = config.arcPlugins.realtime === true ? {} : config.arcPlugins.realtime;
|
|
892
892
|
await fastify.register(realtimePlugin, opts);
|
|
893
893
|
trackPlugin("arc-realtime", opts);
|
|
894
894
|
}
|
|
895
895
|
}
|
|
896
896
|
if (config.arcPlugins?.metrics) {
|
|
897
|
-
const { default: metricsPlugin } = await import("./metrics-
|
|
897
|
+
const { default: metricsPlugin } = await import("./metrics-5LNPvL3P.mjs").then((n) => n.r);
|
|
898
898
|
const opts = config.arcPlugins.metrics === true ? {} : config.arcPlugins.metrics;
|
|
899
899
|
await fastify.register(metricsPlugin, opts);
|
|
900
900
|
trackPlugin("arc-metrics", opts);
|
|
901
901
|
}
|
|
902
902
|
if (config.arcPlugins?.versioning) {
|
|
903
|
-
const { default: versioningPlugin } = await import("./versioning-
|
|
903
|
+
const { default: versioningPlugin } = await import("./versioning-BbTs4pwM.mjs").then((n) => n.r);
|
|
904
904
|
await fastify.register(versioningPlugin, config.arcPlugins.versioning);
|
|
905
905
|
trackPlugin("arc-versioning", config.arcPlugins.versioning);
|
|
906
906
|
}
|
|
@@ -977,7 +977,7 @@ async function registerAuth(fastify, config, trackPlugin) {
|
|
|
977
977
|
*/
|
|
978
978
|
async function registerElevation(fastify, config, trackPlugin) {
|
|
979
979
|
if (!config.elevation) return;
|
|
980
|
-
const { elevationPlugin } = await import("./elevation-
|
|
980
|
+
const { elevationPlugin } = await import("./elevation-tGIAldco.mjs").then((n) => n.r);
|
|
981
981
|
await fastify.register(elevationPlugin, config.elevation);
|
|
982
982
|
trackPlugin("arc-elevation", config.elevation);
|
|
983
983
|
fastify.log.debug("Elevation plugin enabled");
|
|
@@ -992,7 +992,7 @@ async function registerElevation(fastify, config, trackPlugin) {
|
|
|
992
992
|
*/
|
|
993
993
|
async function registerErrorHandler(fastify, config, trackPlugin, moduleErrorMappers) {
|
|
994
994
|
if (config.errorHandler === false) return;
|
|
995
|
-
const { errorHandlerPlugin } = await import("./errorHandler-
|
|
995
|
+
const { errorHandlerPlugin } = await import("./errorHandler-BbQ1nQdk.mjs").then((n) => n.r);
|
|
996
996
|
/**
|
|
997
997
|
* DISCLOSURE DEFAULTS MERGE — they used to be REPLACED, and that was two bugs.
|
|
998
998
|
*
|
|
@@ -1216,7 +1216,7 @@ async function registerResources(fastify, config, preResolvedModules) {
|
|
|
1216
1216
|
let discoveryPath;
|
|
1217
1217
|
let discoveryYieldedZero = false;
|
|
1218
1218
|
if (resolvedResources === void 0 && config.resourceDir) {
|
|
1219
|
-
const { loadResources } = await import("./loadResources-
|
|
1219
|
+
const { loadResources } = await import("./loadResources-DdQb0qgV.mjs").then((n) => n.n);
|
|
1220
1220
|
const { resolve, dirname } = await import("node:path");
|
|
1221
1221
|
const { fileURLToPath } = await import("node:url");
|
|
1222
1222
|
const rawDir = config.resourceDir;
|
|
@@ -1342,7 +1342,7 @@ Resources supplied by "${m.name}": ${provided}.`);
|
|
|
1342
1342
|
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.");
|
|
1343
1343
|
const frozenJobs = Object.freeze(scheduledJobs.map((job) => Object.freeze({ ...job })));
|
|
1344
1344
|
const scheduleOptions = typeof config.arcPlugins?.schedules === "object" ? config.arcPlugins.schedules : {};
|
|
1345
|
-
const { default: schedulesPlugin } = await import("./schedules-
|
|
1345
|
+
const { default: schedulesPlugin } = await import("./schedules-BLpZLWGF.mjs").then((n) => n.r);
|
|
1346
1346
|
await fastify.register(schedulesPlugin, {
|
|
1347
1347
|
...scheduleOptions,
|
|
1348
1348
|
schedules: frozenJobs
|
|
@@ -1696,7 +1696,7 @@ const MEMORY_STORE_NAMES = /* @__PURE__ */ new Set(["memory", "memory-cache"]);
|
|
|
1696
1696
|
* Hosts that need NO redaction (test fixtures, security audits) opt out
|
|
1697
1697
|
* with `logger: { redact: [] }`. Hosts that need MORE redaction supply
|
|
1698
1698
|
* their own `redact` and arc steps aside — this default never overrides
|
|
1699
|
-
* an explicit setting.
|
|
1699
|
+
* an explicit setting.
|
|
1700
1700
|
*/
|
|
1701
1701
|
const DEFAULT_LOGGER_REDACT_PATHS = [
|
|
1702
1702
|
"req.headers.authorization",
|
|
@@ -1813,11 +1813,22 @@ async function createApp(options) {
|
|
|
1813
1813
|
*/
|
|
1814
1814
|
const declaredRole = options.role ?? "all";
|
|
1815
1815
|
if ((declaredRole === "relay" || declaredRole === "scheduler") && (options.resources !== void 0 || options.resourceDir !== void 0)) throw new Error(`createApp: role '${declaredRole}' declares HTTP resources — a ${declaredRole} process must not serve routes. Remove \`resources\`/\`resourceDir\`, or change the role.`);
|
|
1816
|
+
/**
|
|
1817
|
+
* This app's own `arcLog` config, entered for the WHOLE boot.
|
|
1818
|
+
*
|
|
1819
|
+
* Held by reference and mutated in `buildApp` once `fastify.log` exists:
|
|
1820
|
+
* boot starts before Fastify does, so a copied snapshot would send every
|
|
1821
|
+
* post-construction boot warning to the console instead of this app's
|
|
1822
|
+
* logger. Scoping it per app is what stops two apps in one process from
|
|
1823
|
+
* overwriting each other's writer — see `src/logger/index.ts`.
|
|
1824
|
+
*/
|
|
1825
|
+
const loggerScope = {};
|
|
1826
|
+
if (options.debug !== void 0 && options.debug !== false) loggerScope.debug = options.debug;
|
|
1816
1827
|
let partial;
|
|
1817
1828
|
try {
|
|
1818
|
-
return await buildApp(options, (instance) => {
|
|
1829
|
+
return await runWithArcLogger(loggerScope, () => buildApp(options, loggerScope, (instance) => {
|
|
1819
1830
|
partial = instance;
|
|
1820
|
-
});
|
|
1831
|
+
}));
|
|
1821
1832
|
} catch (err) {
|
|
1822
1833
|
if (partial) try {
|
|
1823
1834
|
await partial.close();
|
|
@@ -1827,8 +1838,7 @@ async function createApp(options) {
|
|
|
1827
1838
|
throw err;
|
|
1828
1839
|
}
|
|
1829
1840
|
}
|
|
1830
|
-
async function buildApp(options, onInstance) {
|
|
1831
|
-
if (options.debug !== void 0 && options.debug !== false) configureArcLogger({ debug: options.debug });
|
|
1841
|
+
async function buildApp(options, loggerScope, onInstance) {
|
|
1832
1842
|
validateAuthOptions(options);
|
|
1833
1843
|
const deferredWarnings = validateDistributedRuntime(options);
|
|
1834
1844
|
if (options.beforeBoot) await options.beforeBoot();
|
|
@@ -1837,6 +1847,25 @@ async function buildApp(options, onInstance) {
|
|
|
1837
1847
|
...options
|
|
1838
1848
|
};
|
|
1839
1849
|
const inheritedTrustProxyDefault = options.preset === "production" && options.trustProxy === void 0;
|
|
1850
|
+
/**
|
|
1851
|
+
* A NUMERIC `trustProxy` is a no-op on Fastify >= 5.12.1.
|
|
1852
|
+
*
|
|
1853
|
+
* Fastify made hop-count trust fail-closed on purpose — the comment in
|
|
1854
|
+
* `lib/request.js` is explicit: "Hop-count-only trust cannot validate the
|
|
1855
|
+
* immediate peer. Fail closed so direct clients cannot spoof X-Forwarded-*
|
|
1856
|
+
* values by supplying enough hops." So `trustProxy: 1` now trusts NOTHING.
|
|
1857
|
+
*
|
|
1858
|
+
* That is the right call upstream and the wrong thing to inherit silently:
|
|
1859
|
+
* `request.ip` becomes the proxy's address, which is the exact failure the
|
|
1860
|
+
* production-preset warning below describes — rate-limit keys collapse onto
|
|
1861
|
+
* one bucket and audit rows record the wrong client. The host asked for
|
|
1862
|
+
* proxy trust and got none, with no error.
|
|
1863
|
+
*
|
|
1864
|
+
* Warn rather than refuse: the app still serves, and a hard boot failure on
|
|
1865
|
+
* a transitive `fastify` bump would be a harsher surprise than the one being
|
|
1866
|
+
* reported. The replacement is named so the fix is a copy-paste.
|
|
1867
|
+
*/
|
|
1868
|
+
const numericTrustProxy = typeof config.trustProxy === "number";
|
|
1840
1869
|
const resolvedModules = orderModules(await Promise.all((config.modules ?? []).map((m) => resolveModule(m))));
|
|
1841
1870
|
const moduleErrorMappers = resolvedModules.flatMap((m) => m.errorMappers ?? []);
|
|
1842
1871
|
const moduleHealthChecks = collectModuleHealthChecks(resolvedModules);
|
|
@@ -1869,11 +1898,19 @@ async function buildApp(options, onInstance) {
|
|
|
1869
1898
|
} }
|
|
1870
1899
|
});
|
|
1871
1900
|
onInstance(fastify);
|
|
1872
|
-
if (resolvedLogger !== false)
|
|
1873
|
-
|
|
1874
|
-
writer
|
|
1901
|
+
if (resolvedLogger !== false) {
|
|
1902
|
+
const writer = createPinoWriter(fastify.log);
|
|
1903
|
+
loggerScope.writer = writer;
|
|
1904
|
+
configureArcLogger({
|
|
1905
|
+
...options.debug !== void 0 && options.debug !== false ? { debug: options.debug } : {},
|
|
1906
|
+
writer
|
|
1907
|
+
});
|
|
1908
|
+
}
|
|
1909
|
+
fastify.addHook("onRequest", (_request, _reply, done) => {
|
|
1910
|
+
enterArcLoggerScope(loggerScope, done);
|
|
1875
1911
|
});
|
|
1876
1912
|
for (const warning of deferredWarnings) fastify.log.warn(warning);
|
|
1913
|
+
if (numericTrustProxy) fastify.log.warn(`[arc] trustProxy: ${String(config.trustProxy)} (a hop COUNT) trusts nothing on Fastify >= 5.12.1 — hop-count trust cannot validate the immediate peer, so it fails closed upstream to stop clients spoofing X-Forwarded-* with padded hops. \`request.ip\` is therefore the PROXY's address: rate-limit keys collapse onto one bucket and audit rows record the wrong client. Name the proxies instead — trustProxy: 'loopback', '10.0.0.0/8', a comma-separated list, or \`true\` if every upstream hop is genuinely trusted.`);
|
|
1877
1914
|
if (inheritedTrustProxyDefault) fastify.log.warn("[arc] preset: 'production' now defaults to trustProxy: false (fail-closed; was true before 2.24). If this app runs behind a load balancer or reverse proxy, request.ip is currently the PROXY's address — rate-limit keys collapse onto one bucket and audit logs record the wrong client. Set trustProxy explicitly: a hop count (trustProxy: 1), a CIDR allow-list ('10.0.0.0/8'), a resolver function, or false if clients truly connect directly.");
|
|
1878
1915
|
fastify.removeContentTypeParser("application/json");
|
|
1879
1916
|
fastify.addContentTypeParser("application/json", { parseAs: "string" }, (_req, body, done) => {
|
|
@@ -1907,7 +1944,7 @@ async function buildApp(options, onInstance) {
|
|
|
1907
1944
|
await registerErrorHandler(fastify, config, trackPlugin, moduleErrorMappers);
|
|
1908
1945
|
await registerResources(fastify, config, resolvedModules);
|
|
1909
1946
|
if (config.replyHelpers) {
|
|
1910
|
-
const { replyHelpersPlugin } = await import("./replyHelpers-
|
|
1947
|
+
const { replyHelpersPlugin } = await import("./replyHelpers-2jfmMnnV.mjs").then((n) => n.n);
|
|
1911
1948
|
await fastify.register(replyHelpersPlugin);
|
|
1912
1949
|
}
|
|
1913
1950
|
if (config.serializeBigInt) {
|
|
@@ -1959,4 +1996,48 @@ const ArcFactory = {
|
|
|
1959
1996
|
}
|
|
1960
1997
|
};
|
|
1961
1998
|
//#endregion
|
|
1962
|
-
|
|
1999
|
+
//#region src/factory/preloadResources.ts
|
|
2000
|
+
/**
|
|
2001
|
+
* Normalize an eager `import.meta.glob` result into a `ResourceLike[]`.
|
|
2002
|
+
*
|
|
2003
|
+
* Accepts either:
|
|
2004
|
+
* - `{ import: 'default' }` form: values are the resource directly
|
|
2005
|
+
* - default form: values are the full module — picks first export with `toPlugin()`
|
|
2006
|
+
*
|
|
2007
|
+
* Throws if any module doesn't yield a valid `ResourceLike`.
|
|
2008
|
+
*/
|
|
2009
|
+
function preloadResources(globResult) {
|
|
2010
|
+
const resources = [];
|
|
2011
|
+
for (const [path, value] of Object.entries(globResult)) {
|
|
2012
|
+
const resource = pickResource(value);
|
|
2013
|
+
if (!resource) throw new Error(`preloadResources: ${path} does not export a valid resource.\n Expected: a default export OR a named export with toPlugin().`);
|
|
2014
|
+
resources.push(resource);
|
|
2015
|
+
}
|
|
2016
|
+
return resources.sort((a, b) => (a.name ?? "").localeCompare(b.name ?? ""));
|
|
2017
|
+
}
|
|
2018
|
+
/**
|
|
2019
|
+
* Normalize a lazy `import.meta.glob` result into a `Promise<ResourceLike[]>`.
|
|
2020
|
+
*
|
|
2021
|
+
* Use this when resources depend on prior bootstrap (e.g., engine init) and
|
|
2022
|
+
* cannot be evaluated at import time of the preload file.
|
|
2023
|
+
*/
|
|
2024
|
+
async function preloadResourcesAsync(globResult) {
|
|
2025
|
+
return (await Promise.all(Object.entries(globResult).map(async ([path, loader]) => {
|
|
2026
|
+
const resource = pickResource(await loader());
|
|
2027
|
+
if (!resource) throw new Error(`preloadResourcesAsync: ${path} does not export a valid resource.\n Expected: a default export OR a named export with toPlugin().`);
|
|
2028
|
+
return resource;
|
|
2029
|
+
}))).sort((a, b) => (a.name ?? "").localeCompare(b.name ?? ""));
|
|
2030
|
+
}
|
|
2031
|
+
function pickResource(value) {
|
|
2032
|
+
if (!value || typeof value !== "object") return void 0;
|
|
2033
|
+
if (typeof value.toPlugin === "function") return value;
|
|
2034
|
+
const mod = value;
|
|
2035
|
+
const candidates = [
|
|
2036
|
+
mod.default,
|
|
2037
|
+
mod.resource,
|
|
2038
|
+
...Object.values(mod)
|
|
2039
|
+
];
|
|
2040
|
+
for (const c of candidates) if (c && typeof c === "object" && typeof c.toPlugin === "function") return c;
|
|
2041
|
+
}
|
|
2042
|
+
//#endregion
|
|
2043
|
+
export { resolveModule as S, describeResolvedModule as _, createApp as a, collectModuleWorkflows as b, edgePreset as c, testingPreset as d, workerPreset as f, subscribeModuleEventHandlers as g, orderModules as h, DEFAULT_LOGGER_REDACT_PATHS as i, getPreset as l, hasModule as m, preloadResourcesAsync as n, createApp_exports as o, getModuleState as p, ArcFactory as r, developmentPreset as s, preloadResources as t, productionPreset as u, collectModuleHealthChecks as v, resolveContribution as x, collectModuleScheduledJobs as y };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
|
-
import { i as RequestScope } from "../types-
|
|
3
|
-
import { l as PermissionCheck } from "../base-
|
|
4
|
-
import { Y as PresetResult } from "../index-
|
|
2
|
+
import { i as RequestScope } from "../types-Ddl9OjmE.mjs";
|
|
3
|
+
import { l as PermissionCheck } from "../base-GZU3LlzP.mjs";
|
|
4
|
+
import { Y as PresetResult } from "../index-C5K78SXo.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.35.0 | MIT | https://classytic.com */
|
|
2
|
+
import { i as NotFoundError, u as ValidationError } from "../errors-CLid6atr.mjs";
|
|
3
|
+
import { c as getOrgId, g as getUserId } from "../types-GY4kATJb.mjs";
|
|
4
|
+
import { B as requireAuth, F as allowPublic } from "../permissions-CpSBlFXZ.mjs";
|
|
5
|
+
import { t as multipartBody } from "../multipartBody-DjilSDAT.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-GZU3LlzP.mjs";
|
|
3
|
+
import { Fn as IControllerResponse, In as IRequestContext, U as ResourceConfig, Y as PresetResult, d as PaginationResult } from "../index-C5K78SXo.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.35.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-Bi0Z6Iq8.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-C5K78SXo.mjs";
|
|
3
3
|
//#region src/presets/multiTenant.d.ts
|
|
4
4
|
/**
|
|
5
5
|
* One tenant dimension for multi-field filtering. Discriminated by source:
|
|
@@ -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.35.0 | MIT | https://classytic.com */
|
|
2
|
+
import "../constants-BhzLXCfN.mjs";
|
|
3
|
+
import { b as isElevated, c as getOrgId, d as getScopeContext, m as getTeamId, u as getRequestScope, v as hasOrgAccess } from "../types-GY4kATJb.mjs";
|
|
4
4
|
//#region src/presets/multiTenant.ts
|
|
5
5
|
/**
|
|
6
6
|
* Resolve a single TenantFieldSpec against the current scope.
|
|
@@ -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-GZU3LlzP.mjs";
|
|
3
|
+
import { At as RouteDefinition, Y as PresetResult, jn as ControllerHandler, jt as RouteMcpConfig } from "../index-C5K78SXo.mjs";
|
|
4
4
|
//#region src/presets/search.d.ts
|
|
5
5
|
/**
|
|
6
6
|
* Search Preset — backend-agnostic search / vector / embed routes
|
|
@@ -23,55 +23,17 @@ import { At as RouteDefinition, Y as PresetResult, jn as ControllerHandler, jt a
|
|
|
23
23
|
* GET-based autocomplete, pass `path`/`method` overrides or use `routes` for
|
|
24
24
|
* fully bespoke endpoints.
|
|
25
25
|
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```typescript
|
|
28
|
-
* import { Repository, methodRegistryPlugin, elasticSearchPlugin } from '@classytic/mongokit';
|
|
29
|
-
* import { vectorPlugin } from '@classytic/mongokit/ai';
|
|
30
|
-
* import { searchPreset } from '@classytic/arc/presets/search';
|
|
31
|
-
*
|
|
32
|
-
* const productRepo = new Repository(Product, [
|
|
33
|
-
* methodRegistryPlugin(),
|
|
34
|
-
* elasticSearchPlugin({ client: esClient, indexName: 'products' }),
|
|
35
|
-
* vectorPlugin({ fields: [{ path: 'embedding', dimensions: 1536 }], embedFn }),
|
|
36
|
-
* ]);
|
|
37
|
-
*
|
|
38
|
-
* defineResource({
|
|
39
|
-
* name: 'product',
|
|
40
|
-
* adapter: createMongooseAdapter({ model: Product, repository: productRepo }),
|
|
41
|
-
* presets: [
|
|
42
|
-
* searchPreset({
|
|
43
|
-
* search: { handler: (req) => productRepo.search(req.body.query, req.body) },
|
|
44
|
-
* similar: { handler: (req) => productRepo.searchSimilar(req.body.query, req.body) },
|
|
45
|
-
* }),
|
|
46
|
-
* ],
|
|
47
|
-
* });
|
|
48
|
-
* ```
|
|
49
|
-
*
|
|
50
|
-
* @example Custom vector backend (Pinecone)
|
|
26
|
+
* @example
|
|
51
27
|
* ```typescript
|
|
52
28
|
* searchPreset({
|
|
29
|
+
* search: { handler: (req) => repo.search(req.body.query, req.body) },
|
|
53
30
|
* similar: {
|
|
54
|
-
* path: '/vector-search',
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* vector: req.body.vector,
|
|
58
|
-
* topK: req.body.topK ?? 10,
|
|
59
|
-
* });
|
|
60
|
-
* return hits.matches;
|
|
61
|
-
* },
|
|
62
|
-
* schema: { body: { type: 'object', properties: { vector: { type: 'array' }, topK: { type: 'integer' } } } },
|
|
63
|
-
* mcp: false, // no MCP tool for this one
|
|
31
|
+
* path: '/vector-search', // override the default path
|
|
32
|
+
* mcp: false, // and skip the MCP tool for this one
|
|
33
|
+
* handler: (req) => pinecone.query({ vector: req.body.vector }),
|
|
64
34
|
* },
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
* {
|
|
68
|
-
* method: 'GET',
|
|
69
|
-
* path: '/autocomplete',
|
|
70
|
-
* handler: async (req) => algolia.suggest(req.query.q as string),
|
|
71
|
-
* permissions: allowPublic(),
|
|
72
|
-
* },
|
|
73
|
-
* ],
|
|
74
|
-
* });
|
|
35
|
+
* routes: [{ method: 'GET', path: '/autocomplete', handler, permissions }],
|
|
36
|
+
* })
|
|
75
37
|
* ```
|
|
76
38
|
*/
|
|
77
39
|
/**
|
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.35.0 | MIT | https://classytic.com */
|
|
2
|
+
import { B as requireAuth, F as allowPublic } from "../permissions-CpSBlFXZ.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.35.0 | MIT | https://classytic.com */
|
|
2
|
+
import { l as UnauthorizedError } from "./errors-CLid6atr.mjs";
|
|
3
|
+
import { b as isElevated, n as PUBLIC_SCOPE } from "./types-GY4kATJb.mjs";
|
|
4
|
+
import { B as requireAuth, F as allowPublic, U as requireRoles } from "./permissions-CpSBlFXZ.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.35.0 | MIT | https://classytic.com */
|
|
2
|
+
import { c as getOrgId, f as getScopeContextMap, g as getUserId, m as getTeamId, x as isMember } from "./types-GY4kATJb.mjs";
|
|
3
3
|
//#region src/scope/projection.ts
|
|
4
4
|
/**
|
|
5
5
|
* Compute the request-scope projection. Returns `undefined` when no
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { t as __exportAll } from "./rolldown-runtime-
|
|
3
|
-
import { t as hasEvents } from "./typeGuards-
|
|
4
|
-
import { i as versionKey, r as tagVersionKey } from "./keys-
|
|
5
|
-
import { t as MemoryCacheStore } from "./memory-
|
|
1
|
+
/*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
|
|
2
|
+
import { t as __exportAll } from "./rolldown-runtime-CEvvVXTC.mjs";
|
|
3
|
+
import { t as hasEvents } from "./typeGuards-B-_jqaMi.mjs";
|
|
4
|
+
import { i as versionKey, r as tagVersionKey } from "./keys-GlU7XpmG.mjs";
|
|
5
|
+
import { t as MemoryCacheStore } from "./memory-BwedEXau.mjs";
|
|
6
6
|
import fp from "fastify-plugin";
|
|
7
7
|
//#region src/cache/QueryCache.ts
|
|
8
8
|
var QueryCache = class {
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { t as __exportAll } from "./rolldown-runtime-
|
|
1
|
+
/*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
|
|
2
|
+
import { t as __exportAll } from "./rolldown-runtime-CEvvVXTC.mjs";
|
|
3
3
|
import { arcLog } from "./logger/index.mjs";
|
|
4
|
-
import { n as evaluateAndApplyPermission } from "./authorizationDecision-
|
|
5
|
-
import { n as getUserRoles } from "./userHelpers-
|
|
6
|
-
import { c as getOrgId } from "./types-
|
|
7
|
-
import { t as simpleEqualityMatcher } from "./simpleEqualityMatcher-
|
|
8
|
-
import { t as applyFieldReadPermissions } from "./fields-
|
|
9
|
-
import { a as promoteStreamTokenToHeader } from "./streaming-
|
|
10
|
-
import { t as openSseStream } from "./sseStream-
|
|
4
|
+
import { n as evaluateAndApplyPermission } from "./authorizationDecision-DYXBBgtg.mjs";
|
|
5
|
+
import { n as getUserRoles } from "./userHelpers-AKcB4V03.mjs";
|
|
6
|
+
import { c as getOrgId } from "./types-GY4kATJb.mjs";
|
|
7
|
+
import { t as simpleEqualityMatcher } from "./simpleEqualityMatcher-BO-sFTQf.mjs";
|
|
8
|
+
import { t as applyFieldReadPermissions } from "./fields-UtpiJO5R.mjs";
|
|
9
|
+
import { a as promoteStreamTokenToHeader } from "./streaming-DOpZVht6.mjs";
|
|
10
|
+
import { t as openSseStream } from "./sseStream-ByFGyIVr.mjs";
|
|
11
11
|
import fp from "fastify-plugin";
|
|
12
12
|
//#region src/plugins/realtime.ts
|
|
13
13
|
var realtime_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
/*! @classytic/arc v2.
|
|
2
|
-
import { n as
|
|
1
|
+
/*! @classytic/arc v2.35.0 | MIT | https://classytic.com */
|
|
2
|
+
import { n as evaluateAndApplyPermission } from "./authorizationDecision-DYXBBgtg.mjs";
|
|
3
|
+
import { f as createError } from "./errors-CLid6atr.mjs";
|
|
4
|
+
import { u as getRequestScope } from "./types-GY4kATJb.mjs";
|
|
5
|
+
import { n as requestContext } from "./requestContext-DzOUGNdY.mjs";
|
|
3
6
|
//#region src/core/middlewares/arcDecorator.ts
|
|
4
7
|
/**
|
|
5
8
|
* Build the `arcDecorator` preHandler for a resource.
|
|
@@ -178,6 +181,79 @@ function describeValue(v) {
|
|
|
178
181
|
return `${typeof v} (${JSON.stringify(v).slice(0, 80)})`;
|
|
179
182
|
}
|
|
180
183
|
//#endregion
|
|
184
|
+
//#region src/core/middlewares/permissions.ts
|
|
185
|
+
/**
|
|
186
|
+
* Build a PermissionContext from a Fastify request. Extracted so the CRUD
|
|
187
|
+
* permission middleware and the dynamic action-permission check use the same
|
|
188
|
+
* field layout — divergence here silently broke policy filters for actions.
|
|
189
|
+
*/
|
|
190
|
+
function buildPermissionContext(req, opts) {
|
|
191
|
+
const reqWithExtras = req;
|
|
192
|
+
const params = req.params;
|
|
193
|
+
return {
|
|
194
|
+
user: reqWithExtras.user ?? null,
|
|
195
|
+
scope: getRequestScope(req),
|
|
196
|
+
request: req,
|
|
197
|
+
resource: opts.resource,
|
|
198
|
+
action: opts.action,
|
|
199
|
+
resourceId: opts.resourceId ?? params?.id,
|
|
200
|
+
params,
|
|
201
|
+
data: opts.data ?? req.body
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Static per-route CRUD permission gate. The permission and action are known
|
|
206
|
+
* at route-registration time, so the gate is a plain preHandler.
|
|
207
|
+
*
|
|
208
|
+
* Actions use the dynamic counterpart `buildActionPermissionMw` — their
|
|
209
|
+
* permission is resolved from `body.action` at request time.
|
|
210
|
+
*/
|
|
211
|
+
function buildCrudPermissionMw(permissionCheck, resourceName, action) {
|
|
212
|
+
if (!permissionCheck) return null;
|
|
213
|
+
return async (req, reply) => {
|
|
214
|
+
const context = buildPermissionContext(req, {
|
|
215
|
+
resource: resourceName,
|
|
216
|
+
action
|
|
217
|
+
});
|
|
218
|
+
await evaluateAndApplyPermission(permissionCheck, context, req, reply);
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Dynamic per-action permission gate for the action router.
|
|
223
|
+
*
|
|
224
|
+
* Resolves the permission from `body.action` at request time and runs
|
|
225
|
+
* `evaluateAndApplyPermission` from the canonical `permissionMw` slot — so
|
|
226
|
+
* `_policyFilters` and `request.scope` are installed BEFORE `pluginMw`
|
|
227
|
+
* (idempotency) and `routeGuards` run. Previously this check lived inside
|
|
228
|
+
* the main action handler, which meant idempotency recorded unauthorized
|
|
229
|
+
* requests and route guards saw unfiltered scope — the very divergence
|
|
230
|
+
* routerShared exists to prevent.
|
|
231
|
+
*
|
|
232
|
+
* Also acts as a defensive fallback for invalid action names — the
|
|
233
|
+
* `oneOf` body schema normally rejects these at AJV validation, but
|
|
234
|
+
* hosts that disable schema validation still get a 400 here.
|
|
235
|
+
*/
|
|
236
|
+
function buildActionPermissionMw(actionEnum, actionPermissions, globalAuth, resourceName) {
|
|
237
|
+
const enumSet = new Set(actionEnum);
|
|
238
|
+
const validActions = [...actionEnum];
|
|
239
|
+
return async (req, reply) => {
|
|
240
|
+
const body = req.body ?? {};
|
|
241
|
+
const action = body.action;
|
|
242
|
+
if (!action || !enumSet.has(action)) throw createError(400, `Invalid action '${action ?? ""}'. Valid actions: ${validActions.join(", ")}`, { validActions });
|
|
243
|
+
const permissionCheck = actionPermissions[action] ?? globalAuth;
|
|
244
|
+
if (!permissionCheck) return;
|
|
245
|
+
const { action: _discard, ...data } = body;
|
|
246
|
+
const params = req.params;
|
|
247
|
+
const context = buildPermissionContext(req, {
|
|
248
|
+
resource: resourceName,
|
|
249
|
+
action,
|
|
250
|
+
resourceId: params?.id,
|
|
251
|
+
data
|
|
252
|
+
});
|
|
253
|
+
await evaluateAndApplyPermission(permissionCheck, context, req, reply, { defaultDenialMessage: (user) => user ? `Permission denied for '${action}'` : "Authentication required" });
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
//#endregion
|
|
181
257
|
//#region src/core/middlewares/pluginMw.ts
|
|
182
258
|
/**
|
|
183
259
|
* Pick the request-lifecycle plugin middleware for an HTTP method:
|
|
@@ -246,4 +322,39 @@ function buildRateLimitConfig(rateLimit) {
|
|
|
246
322
|
} };
|
|
247
323
|
}
|
|
248
324
|
//#endregion
|
|
249
|
-
|
|
325
|
+
//#region src/core/middlewares/registerRoute.ts
|
|
326
|
+
/**
|
|
327
|
+
* Register a route with friendly handling of `FST_ERR_DUPLICATED_ROUTE`.
|
|
328
|
+
*
|
|
329
|
+
* Boot-time `validateRouteCrudCollisions()` catches custom-route → auto-CRUD
|
|
330
|
+
* overlaps before Fastify ever runs, but a few cases still slip through to
|
|
331
|
+
* Fastify itself: two presets contributing the same `routes` entry, hosts
|
|
332
|
+
* mounting two resources at the same prefix, custom routes that share a
|
|
333
|
+
* URL with another plugin. Fastify's default message ("Method 'GET'
|
|
334
|
+
* already declared for route '/'") gives no hint at the resource-shaped
|
|
335
|
+
* fix — `disabledRoutes: ['list']` — so wrap it with one.
|
|
336
|
+
*/
|
|
337
|
+
function tryRegisterRoute(fastify, opts, context) {
|
|
338
|
+
try {
|
|
339
|
+
fastify.route(opts);
|
|
340
|
+
} catch (err) {
|
|
341
|
+
const fastifyErr = err;
|
|
342
|
+
if (fastifyErr?.code !== "FST_ERR_DUPLICATED_ROUTE") throw err;
|
|
343
|
+
const method = opts.method;
|
|
344
|
+
const url = opts.url;
|
|
345
|
+
const opHint = context.op ? ` (op: ${context.op})` : "";
|
|
346
|
+
const fixHint = context.op && [
|
|
347
|
+
"list",
|
|
348
|
+
"get",
|
|
349
|
+
"create",
|
|
350
|
+
"update",
|
|
351
|
+
"delete"
|
|
352
|
+
].includes(context.op) ? ` Suppress the auto-CRUD route with \`disabledRoutes: ['${context.op}']\`.` : " If a custom route in `routes:` collides with auto-CRUD, add `disabledRoutes: ['list' | 'get' | 'create' | 'update' | 'delete']` to `defineResource()` to suppress the matching auto-CRUD route.";
|
|
353
|
+
const enhanced = /* @__PURE__ */ new Error(`[arc] Duplicate route ${method} ${url} on resource "${context.resourceName}"${opHint}.${fixHint} Original: ${fastifyErr.message ?? "FST_ERR_DUPLICATED_ROUTE"}`);
|
|
354
|
+
enhanced.code = "FST_ERR_DUPLICATED_ROUTE";
|
|
355
|
+
enhanced.cause = err;
|
|
356
|
+
throw enhanced;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
//#endregion
|
|
360
|
+
export { selectPluginMw as a, buildRouteHooks as c, buildAuthMiddleware as d, buildAuthMiddlewareForPermissions as f, resolveRouterPluginMw as i, resolveRoutePreHandlers as l, buildRateLimitConfig as n, buildActionPermissionMw as o, buildArcDecorator as p, buildRouteConfig as r, buildCrudPermissionMw as s, tryRegisterRoute as t, routeHookOptions as u };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
|
-
import { K as ResolvedTenantPurge, R as RegisterOptions, V as ResourceDefinition, X as CrudRouteKey, k as IntrospectionPluginOptions, p as RegistryEntry, z as ResourceRegistry } from "../index-
|
|
3
|
-
import "../fastify-augmentation-
|
|
2
|
+
import { K as ResolvedTenantPurge, R as RegisterOptions, V as ResourceDefinition, X as CrudRouteKey, k as IntrospectionPluginOptions, p as RegistryEntry, z as ResourceRegistry } from "../index-C5K78SXo.mjs";
|
|
3
|
+
import "../fastify-augmentation-CMMTL3cj.mjs";
|
|
4
4
|
import { TenantPurgeProgress, TenantPurgeStrategy } from "@classytic/repo-core/repository";
|
|
5
5
|
import { FastifyPluginAsync } from "fastify";
|
|
6
6
|
//#region src/registry/assertNoTenantData.d.ts
|