@classytic/arc 2.8.5 → 2.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -38
- package/dist/{BaseController-DAGGc5Xn.mjs → BaseController-CbKKIflT.mjs} +193 -143
- package/dist/EventTransport-CUw5NNWe.d.mts +293 -0
- package/dist/{ResourceRegistry-C6uXlWe3.mjs → ResourceRegistry-BPd6NQDm.mjs} +1 -1
- package/dist/adapters/index.d.mts +3 -3
- package/dist/adapters/index.mjs +2 -2
- package/dist/{adapters-BBqAVvPK.mjs → adapters-BXY4i-hw.mjs} +210 -41
- package/dist/audit/index.d.mts +135 -11
- package/dist/audit/index.mjs +107 -20
- package/dist/auth/index.d.mts +17 -9
- package/dist/auth/index.mjs +14 -7
- package/dist/auth/redis-session.d.mts +1 -1
- package/dist/{betterAuthOpenApi-BuUcUEJq.mjs → betterAuthOpenApi-BBRVhjQN.mjs} +1 -1
- package/dist/cache/index.d.mts +17 -15
- package/dist/cache/index.mjs +15 -14
- package/dist/{caching-IMuYVjTL.mjs → caching-CBpK_SCM.mjs} +8 -3
- package/dist/cli/commands/describe.mjs +1 -1
- package/dist/cli/commands/docs.mjs +2 -2
- package/dist/cli/commands/generate.mjs +1 -1
- package/dist/cli/commands/init.mjs +1 -1
- package/dist/cli/commands/introspect.mjs +1 -1
- package/dist/core/index.d.mts +3 -3
- package/dist/core/index.mjs +4 -6
- package/dist/{defineResource-tcgySDo1.mjs → core-CcR01lup.mjs} +58 -61
- package/dist/{createActionRouter-BORM8f17.mjs → createActionRouter-Bp_5c_2b.mjs} +3 -3
- package/dist/{createApp-B1EY8zxa.mjs → createApp-BuvPma24.mjs} +15 -14
- package/dist/docs/index.d.mts +2 -2
- package/dist/docs/index.mjs +2 -2
- package/dist/{elevation-DtFxrG0s.mjs → elevation-C7hgL_aI.mjs} +22 -8
- package/dist/{errorHandler-f869_8PQ.mjs → errorHandler-Bb49BvPD.mjs} +59 -7
- package/dist/{errorHandler-Bah5JhBd.d.mts → errorHandler-DRQ3EqfL.d.mts} +37 -2
- package/dist/{eventPlugin-D9DKB2zM.d.mts → eventPlugin-CxWgpd6K.d.mts} +14 -2
- package/dist/{eventPlugin-CDjVTM82.mjs → eventPlugin-DCUjuiQT.mjs} +83 -5
- package/dist/events/index.d.mts +150 -36
- package/dist/events/index.mjs +355 -101
- package/dist/events/transports/redis-stream-entry.d.mts +1 -1
- package/dist/events/transports/redis.d.mts +1 -1
- package/dist/factory/index.d.mts +1 -1
- package/dist/factory/index.mjs +2 -2
- package/dist/{types-DZi1aYhm.d.mts → fields-Lo1VUDpt.d.mts} +121 -1
- package/dist/{fields-ipsbIRPK.mjs → fields-bxkeltzz.mjs} +18 -5
- package/dist/{filesUpload-C7r7HIeA.mjs → filesUpload-t21LS-py.mjs} +65 -7
- package/dist/hooks/index.d.mts +1 -1
- package/dist/hooks/index.mjs +1 -1
- package/dist/idempotency/index.d.mts +32 -5
- package/dist/idempotency/index.mjs +119 -12
- package/dist/idempotency/redis.d.mts +1 -1
- package/dist/{index-DtDzOBn8.d.mts → index-8qw4y6ff.d.mts} +4 -135
- package/dist/{index-BLXBmWud.d.mts → index-ChIw3776.d.mts} +283 -408
- package/dist/{interface-CMRutPfe.d.mts → index-Cl0uoKd5.d.mts} +1758 -2506
- package/dist/{index-C1meYuDn.d.mts → index-DStwgFUK.d.mts} +81 -7
- package/dist/index.d.mts +7 -8
- package/dist/index.mjs +11 -12
- package/dist/integrations/event-gateway.d.mts +1 -1
- package/dist/integrations/event-gateway.mjs +1 -1
- package/dist/integrations/index.d.mts +1 -1
- package/dist/integrations/mcp/index.d.mts +26 -8
- package/dist/integrations/mcp/index.mjs +96 -17
- package/dist/integrations/mcp/testing.d.mts +1 -1
- package/dist/integrations/mcp/testing.mjs +1 -1
- package/dist/integrations/webhooks.d.mts +5 -0
- package/dist/integrations/webhooks.mjs +6 -0
- package/dist/interface-D218ikEo.d.mts +77 -0
- package/dist/{memory-Cp7_cAko.mjs → memory-B5Amv9A1.mjs} +23 -8
- package/dist/{openapi-CbKUJY_m.mjs → openapi-B5F8AddX.mjs} +3 -3
- package/dist/org/index.d.mts +2 -2
- package/dist/permissions/index.d.mts +3 -4
- package/dist/permissions/index.mjs +5 -5
- package/dist/{permissions-CH4cNwJi.mjs → permissions-Dk6mshja.mjs} +315 -397
- package/dist/plugins/index.d.mts +7 -7
- package/dist/plugins/index.mjs +14 -16
- package/dist/plugins/response-cache.mjs +2 -2
- package/dist/plugins/tracing-entry.d.mts +1 -1
- package/dist/plugins/tracing-entry.mjs +1 -1
- package/dist/presets/filesUpload.d.mts +27 -5
- package/dist/presets/filesUpload.mjs +1 -1
- package/dist/presets/index.d.mts +3 -2
- package/dist/presets/index.mjs +4 -3
- package/dist/presets/multiTenant.d.mts +1 -1
- package/dist/presets/multiTenant.mjs +2 -2
- package/dist/presets/search.d.mts +178 -0
- package/dist/presets/search.mjs +150 -0
- package/dist/{presets-C2xgzW6x.mjs → presets-fLJVXdVn.mjs} +1 -1
- package/dist/{queryCachePlugin-BJJGBTlu.d.mts → queryCachePlugin-BKbWjgDG.d.mts} +1 -1
- package/dist/{queryCachePlugin-BH-fidlv.mjs → queryCachePlugin-DQCEfJis.mjs} +9 -9
- package/dist/{queryParser-CgCtsjti.mjs → queryParser-DBqBB6AC.mjs} +1 -1
- package/dist/{redis-BM00zaPB.d.mts → redis-DqyeggCa.d.mts} +1 -1
- package/dist/{redis-stream-CrsfUmPt.d.mts → redis-stream-CakIQmwR.d.mts} +1 -1
- package/dist/registry/index.d.mts +1 -1
- package/dist/registry/index.mjs +2 -2
- package/dist/{resourceToTools-8s-EsCCe.mjs → resourceToTools-BElv3xPT.mjs} +65 -48
- package/dist/{schemaConverter-Y7nCYaLJ.mjs → schemaConverter-BxFDdtXu.mjs} +1 -1
- package/dist/scope/index.d.mts +1 -1
- package/dist/scope/index.mjs +2 -2
- package/dist/{sse-Ad7ypl9e.mjs → sse-yBCgOLGu.mjs} +1 -1
- package/dist/store-helpers-ZCSMJJAX.mjs +57 -0
- package/dist/testing/index.d.mts +9 -17
- package/dist/testing/index.mjs +27 -83
- package/dist/testing/storageContract.d.mts +1 -1
- package/dist/types/index.d.mts +4 -4
- package/dist/types/index.mjs +1 -31
- package/dist/types/storage.d.mts +1 -1
- package/dist/{types-BsbNMEDR.d.mts → types-Btdda02s.d.mts} +1 -1
- package/dist/{types-Ch9pTQbf.d.mts → types-Co8k3NyS.d.mts} +11 -9
- package/dist/types-Csi3FLfq.mjs +27 -0
- package/dist/utils/index.d.mts +208 -4
- package/dist/utils/index.mjs +5 -6
- package/dist/{utils-yYT3HDXt.mjs → utils-B2fNOD_i.mjs} +285 -2
- package/dist/{versioning-CDugduqI.mjs → versioning-C2U_bLY0.mjs} +3 -5
- package/package.json +20 -26
- package/skills/arc/SKILL.md +97 -23
- package/skills/arc/references/auth.md +94 -0
- package/skills/arc/references/events.md +200 -12
- package/skills/arc/references/mcp.md +4 -17
- package/skills/arc/references/multi-tenancy.md +43 -0
- package/skills/arc/references/production.md +34 -60
- package/dist/EventTransport-BXja8NOc.d.mts +0 -135
- package/dist/audit/mongodb.d.mts +0 -2
- package/dist/audit/mongodb.mjs +0 -2
- package/dist/circuitBreaker-cmi5XDv5.mjs +0 -284
- package/dist/circuitBreaker-dTtG-UyS.d.mts +0 -206
- package/dist/core-F0QoWBt2.mjs +0 -34
- package/dist/dynamic/index.d.mts +0 -93
- package/dist/dynamic/index.mjs +0 -122
- package/dist/fields-DpZQa_Q3.d.mts +0 -109
- package/dist/idempotency/mongodb.d.mts +0 -2
- package/dist/idempotency/mongodb.mjs +0 -123
- package/dist/interface-4y979v99.d.mts +0 -54
- package/dist/mongodb-BsP-WbhN.d.mts +0 -127
- package/dist/mongodb-CTcp0hQZ.d.mts +0 -80
- package/dist/mongodb-Utc5k_-0.mjs +0 -90
- package/dist/policies/index.d.mts +0 -432
- package/dist/policies/index.mjs +0 -318
- package/dist/rpc/index.d.mts +0 -90
- package/dist/rpc/index.mjs +0 -248
- /package/dist/{HookSystem-HprTmvVY.mjs → HookSystem-BNYKnrXF.mjs} +0 -0
- /package/dist/{applyPermissionResult-D6GPMsvh.mjs → applyPermissionResult-QhV1Pa-g.mjs} +0 -0
- /package/dist/{constants-Cxde4rpC.mjs → constants-BhY1OHoH.mjs} +0 -0
- /package/dist/{elevation-B6S5csVA.d.mts → elevation-C5SwtkAn.d.mts} +0 -0
- /package/dist/{errors-Ck2h67pm.d.mts → errors-CCSsMpXE.d.mts} +0 -0
- /package/dist/{errors-BF2bIOIS.mjs → errors-D5c-5BJL.mjs} +0 -0
- /package/dist/{externalPaths-BnkYrNzp.d.mts → externalPaths-BQ8QijNH.d.mts} +0 -0
- /package/dist/{interface-DfLGcus7.d.mts → interface-CSbZdv_3.d.mts} +0 -0
- /package/dist/{loadResources-PWd0OCpV.mjs → loadResources-BAzJItAJ.mjs} +0 -0
- /package/dist/{logger-D1YrIImS.mjs → logger-DLg8-Ueg.mjs} +0 -0
- /package/dist/{metrics-B-PU4-Yu.mjs → metrics-DuhiSEZI.mjs} +0 -0
- /package/dist/{pluralize-CWP6MB39.mjs → pluralize-A0tWEl1K.mjs} +0 -0
- /package/dist/{registry-BiTKT1Dg.mjs → registry-B3lRFBWo.mjs} +0 -0
- /package/dist/{replyHelpers-CxkYGT81.mjs → replyHelpers-CXtJDAZ0.mjs} +0 -0
- /package/dist/{requestContext-DYvHl113.mjs → requestContext-xHIKedG6.mjs} +0 -0
- /package/dist/{sessionManager-DDCmiNIo.d.mts → sessionManager-BkzVU8h2.d.mts} +0 -0
- /package/dist/{storage-Dfzt4VTl.d.mts → storage-CVk_SEn2.d.mts} +0 -0
- /package/dist/{tracing-DdN2-wHJ.d.mts → tracing-65B51Dw3.d.mts} +0 -0
- /package/dist/{typeGuards-CcFZXgU7.mjs → typeGuards-Cj5Rgvlg.mjs} +0 -0
- /package/dist/{types-ZUu_h0jp.mjs → types-DV9WDfeg.mjs} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { O as IntrospectionPluginOptions, U as RegisterOptions, W as ResourceRegistry } from "../index-Cl0uoKd5.mjs";
|
|
2
2
|
import { FastifyPluginAsync } from "fastify";
|
|
3
3
|
|
|
4
4
|
//#region src/registry/introspectionPlugin.d.ts
|
package/dist/registry/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as introspectionPlugin_default, t as introspectionPlugin } from "../registry-
|
|
2
|
-
import { t as ResourceRegistry } from "../ResourceRegistry-
|
|
1
|
+
import { n as introspectionPlugin_default, t as introspectionPlugin } from "../registry-B3lRFBWo.mjs";
|
|
2
|
+
import { t as ResourceRegistry } from "../ResourceRegistry-BPd6NQDm.mjs";
|
|
3
3
|
export { ResourceRegistry, introspectionPlugin_default as introspectionPlugin, introspectionPlugin as introspectionPluginFn };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { t as BaseController } from "./BaseController-
|
|
2
|
-
import { n as normalizePermissionResult } from "./applyPermissionResult-
|
|
3
|
-
import { t as pluralize } from "./pluralize-
|
|
1
|
+
import { t as BaseController } from "./BaseController-CbKKIflT.mjs";
|
|
2
|
+
import { n as normalizePermissionResult } from "./applyPermissionResult-QhV1Pa-g.mjs";
|
|
3
|
+
import { t as pluralize } from "./pluralize-A0tWEl1K.mjs";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
//#region src/integrations/mcp/createMcpServer.ts
|
|
6
6
|
/**
|
|
@@ -568,7 +568,7 @@ function resourceToTools(resource, config = {}) {
|
|
|
568
568
|
const hasSoftDelete = resource._appliedPresets?.includes("softDelete") ?? false;
|
|
569
569
|
const tools = [];
|
|
570
570
|
const prefix = config.toolNamePrefix;
|
|
571
|
-
if (
|
|
571
|
+
if (controller) {
|
|
572
572
|
let ops = ALL_CRUD_OPS.filter((op) => {
|
|
573
573
|
if (resource.disabledRoutes?.includes(op)) return false;
|
|
574
574
|
return true;
|
|
@@ -595,50 +595,51 @@ function resourceToTools(resource, config = {}) {
|
|
|
595
595
|
handler: createHandler(op, controller, resource.name, resource.permissions)
|
|
596
596
|
});
|
|
597
597
|
}
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
}
|
|
631
|
-
|
|
598
|
+
}
|
|
599
|
+
for (const route of resource.routes ?? []) {
|
|
600
|
+
if (route.mcp === false) continue;
|
|
601
|
+
const mcpHandler = route.mcpHandler;
|
|
602
|
+
if (!!route.raw && !mcpHandler) continue;
|
|
603
|
+
if (!mcpHandler && ![
|
|
604
|
+
"POST",
|
|
605
|
+
"PUT",
|
|
606
|
+
"PATCH",
|
|
607
|
+
"DELETE"
|
|
608
|
+
].includes(route.method)) continue;
|
|
609
|
+
if (!mcpHandler && typeof route.handler === "string" && !controller) continue;
|
|
610
|
+
const opName = route.operation ?? slugifyRoute(route.method, route.path);
|
|
611
|
+
const hasId = route.path.includes(":id");
|
|
612
|
+
const mcpConfig = typeof route.mcp === "object" && route.mcp !== null ? route.mcp : void 0;
|
|
613
|
+
const toolDescription = mcpConfig?.description ?? route.summary ?? route.description ?? `${opName} on ${resource.displayName}`;
|
|
614
|
+
const toolAnnotations = mcpConfig?.annotations ? { ...mcpConfig.annotations } : { openWorldHint: true };
|
|
615
|
+
const inputShape = {};
|
|
616
|
+
if (hasId) inputShape.id = z.string().describe("Resource ID");
|
|
617
|
+
if (mcpHandler) tools.push({
|
|
618
|
+
name: prefix ? `${prefix}_${opName}_${resource.name}` : `${opName}_${resource.name}`,
|
|
619
|
+
description: toolDescription,
|
|
620
|
+
annotations: toolAnnotations,
|
|
621
|
+
inputSchema: inputShape,
|
|
622
|
+
handler: async (input, _ctx) => {
|
|
623
|
+
try {
|
|
624
|
+
return await mcpHandler(input);
|
|
625
|
+
} catch (err) {
|
|
626
|
+
return {
|
|
627
|
+
content: [{
|
|
628
|
+
type: "text",
|
|
629
|
+
text: `Error: ${err instanceof Error ? err.message : String(err)}`
|
|
630
|
+
}],
|
|
631
|
+
isError: true
|
|
632
|
+
};
|
|
632
633
|
}
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
}
|
|
634
|
+
}
|
|
635
|
+
});
|
|
636
|
+
else tools.push({
|
|
637
|
+
name: prefix ? `${prefix}_${opName}_${resource.name}` : `${opName}_${resource.name}`,
|
|
638
|
+
description: toolDescription,
|
|
639
|
+
annotations: toolAnnotations,
|
|
640
|
+
inputSchema: inputShape,
|
|
641
|
+
handler: createCustomRouteHandler(route, controller, hasId)
|
|
642
|
+
});
|
|
642
643
|
}
|
|
643
644
|
if (resource.actions) for (const [actionName, entry] of Object.entries(resource.actions)) {
|
|
644
645
|
const def = typeof entry === "function" ? { handler: entry } : entry;
|
|
@@ -757,11 +758,27 @@ function createHandler(op, controller, resourceName, permissions) {
|
|
|
757
758
|
}
|
|
758
759
|
};
|
|
759
760
|
}
|
|
760
|
-
function
|
|
761
|
+
function createCustomRouteHandler(route, controller, hasId) {
|
|
761
762
|
const ctrl = controller;
|
|
762
763
|
const handlerName = typeof route.handler === "string" ? route.handler : route.operation ?? slugifyRoute(route.method, route.path);
|
|
763
764
|
return async (input, ctx) => {
|
|
764
765
|
try {
|
|
766
|
+
if (typeof route.handler === "function") {
|
|
767
|
+
const reqCtx = buildRequestContext(input, ctx.session, hasId ? "update" : "create");
|
|
768
|
+
const fn = route.handler;
|
|
769
|
+
const out = await fn(reqCtx);
|
|
770
|
+
return toCallToolResult(out !== null && typeof out === "object" && "success" in out ? out : {
|
|
771
|
+
success: true,
|
|
772
|
+
data: out
|
|
773
|
+
});
|
|
774
|
+
}
|
|
775
|
+
if (!ctrl) return {
|
|
776
|
+
content: [{
|
|
777
|
+
type: "text",
|
|
778
|
+
text: `Handler "${handlerName}" has no controller available`
|
|
779
|
+
}],
|
|
780
|
+
isError: true
|
|
781
|
+
};
|
|
765
782
|
const method = ctrl[handlerName];
|
|
766
783
|
if (typeof method !== "function") return {
|
|
767
784
|
content: [{
|
|
@@ -85,7 +85,7 @@ function convertOpenApiSchemas(schemas, target = DEFAULT_OPENAPI_TARGET) {
|
|
|
85
85
|
*
|
|
86
86
|
* JSON Schema values pass through unchanged. Only Zod schemas are converted.
|
|
87
87
|
*
|
|
88
|
-
* Used for both
|
|
88
|
+
* Used for both custom routes and customSchemas (CRUD overrides).
|
|
89
89
|
*
|
|
90
90
|
* Defaults to `draft-7` so Fastify v5's bundled AJV 8 accepts the output.
|
|
91
91
|
* Pass `openapi-3.0` (or `openapi-3.1`) when generating OpenAPI documents.
|
package/dist/scope/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { i as elevationPlugin, n as ElevationOptions, r as _default, t as ElevationEvent } from "../elevation-C5SwtkAn.mjs";
|
|
1
2
|
import { _ as isAuthenticated, a as getClientId, b as isOrgInScope, c as getOrgRoles, d as getScopeContextMap, f as getServiceScopes, g as hasOrgAccess, h as getUserRoles, i as getAncestorOrgIds, l as getRequestScope, m as getUserId, n as PUBLIC_SCOPE, o as getOrgContext, p as getTeamId, r as RequestScope, s as getOrgId, t as AUTHENTICATED_SCOPE, u as getScopeContext, v as isElevated, x as isService, y as isMember } from "../types-BD85MlEK.mjs";
|
|
2
|
-
import { i as elevationPlugin, n as ElevationOptions, r as _default, t as ElevationEvent } from "../elevation-B6S5csVA.mjs";
|
|
3
3
|
import { FastifyReply, FastifyRequest } from "fastify";
|
|
4
4
|
|
|
5
5
|
//#region src/scope/rateLimitKey.d.ts
|
package/dist/scope/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { _ as isElevated, a as getOrgContext, b as isService, c as getRequestScope, d as getServiceScopes, f as getTeamId, g as isAuthenticated, h as hasOrgAccess, i as getClientId, l as getScopeContext, m as getUserRoles, n as PUBLIC_SCOPE, o as getOrgId, p as getUserId, r as getAncestorOrgIds, s as getOrgRoles, t as AUTHENTICATED_SCOPE, u as getScopeContextMap, v as isMember, y as isOrgInScope } from "../types-AOD8fxIw.mjs";
|
|
2
|
-
import { n as normalizeRoles } from "../types-
|
|
3
|
-
import { n as elevation_default, t as elevationPlugin } from "../elevation-
|
|
2
|
+
import { n as normalizeRoles } from "../types-DV9WDfeg.mjs";
|
|
3
|
+
import { n as elevation_default, t as elevationPlugin } from "../elevation-C7hgL_aI.mjs";
|
|
4
4
|
//#region src/scope/rateLimitKey.ts
|
|
5
5
|
function createTenantKeyGenerator(opts) {
|
|
6
6
|
if (opts?.strategy) return opts.strategy;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
|
|
2
2
|
import { n as PUBLIC_SCOPE, o as getOrgId } from "./types-AOD8fxIw.mjs";
|
|
3
|
-
import { t as arcLog } from "./logger-
|
|
3
|
+
import { t as arcLog } from "./logger-DLg8-Ueg.mjs";
|
|
4
4
|
import fp from "fastify-plugin";
|
|
5
5
|
//#region src/plugins/sse.ts
|
|
6
6
|
var sse_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
//#region src/adapters/store-helpers.ts
|
|
2
|
+
/**
|
|
3
|
+
* Classify an error thrown by `getOne` / `getById` / `update` as a
|
|
4
|
+
* "document not found" miss. Mongokit uses `status: 404`, Prisma uses
|
|
5
|
+
* `code: 'P2025'`, some kits throw `DocumentNotFoundError`. Kits that
|
|
6
|
+
* return `null` on miss never see this predicate fire — it only kicks in
|
|
7
|
+
* when a driver chose to throw.
|
|
8
|
+
*/
|
|
9
|
+
function isNotFoundError(err) {
|
|
10
|
+
if (!err || typeof err !== "object") return false;
|
|
11
|
+
const e = err;
|
|
12
|
+
if (e.status === 404 || e.statusCode === 404) return true;
|
|
13
|
+
if (e.code === "P2025") return true;
|
|
14
|
+
if (e.name === "DocumentNotFoundError") return true;
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Build a `safeGetOne(filter)` that papers over the throw-vs-null split
|
|
19
|
+
* in kit implementations. Real errors propagate; miss returns `null`.
|
|
20
|
+
* Throws if the repository lacks `getOne` — callers must check.
|
|
21
|
+
*/
|
|
22
|
+
function createSafeGetOne(repository) {
|
|
23
|
+
if (typeof repository.getOne !== "function") throw new Error("createSafeGetOne: repository.getOne is required");
|
|
24
|
+
const getOne = repository.getOne.bind(repository);
|
|
25
|
+
return async (filter) => {
|
|
26
|
+
try {
|
|
27
|
+
return await getOne(filter) ?? null;
|
|
28
|
+
} catch (err) {
|
|
29
|
+
if (isNotFoundError(err)) return null;
|
|
30
|
+
throw err;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Build a dup-key predicate for the given repository. Prefers the kit's
|
|
36
|
+
* own `isDuplicateKeyError` (it knows its driver — Mongo `11000`, Prisma
|
|
37
|
+
* `P2002`, Postgres `23505`, MySQL `1062`, etc.); falls back to a
|
|
38
|
+
* conservative Mongo check so mongokit ≤3.8 keeps working without changes.
|
|
39
|
+
*
|
|
40
|
+
* Non-mongo kits MUST implement the predicate to participate in
|
|
41
|
+
* idempotency/outbox dup-handling semantics.
|
|
42
|
+
*
|
|
43
|
+
* `name === "MongoServerError"` alone is deliberately NOT matched — that
|
|
44
|
+
* also fires on WriteConflict / NotWritablePrimary / transient failures,
|
|
45
|
+
* which must propagate rather than silently become 409s.
|
|
46
|
+
*/
|
|
47
|
+
function createIsDuplicateKeyError(repository) {
|
|
48
|
+
const repoPredicate = typeof repository.isDuplicateKeyError === "function" ? repository.isDuplicateKeyError.bind(repository) : null;
|
|
49
|
+
return (err) => {
|
|
50
|
+
if (repoPredicate) return repoPredicate(err);
|
|
51
|
+
if (!err || typeof err !== "object") return false;
|
|
52
|
+
const e = err;
|
|
53
|
+
return e.code === 11e3 || e.codeName === "DuplicateKey";
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//#endregion
|
|
57
|
+
export { createSafeGetOne as n, createIsDuplicateKeyError as t };
|
package/dist/testing/index.d.mts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { d as ResourceLike, r as CreateAppOptions } from "../types-
|
|
1
|
+
import { G as ResourceDefinition, dn as AnyRecord } from "../index-Cl0uoKd5.mjs";
|
|
2
|
+
import { d as ResourceLike, r as CreateAppOptions } from "../types-Co8k3NyS.mjs";
|
|
3
3
|
import { StorageContractSetup, StorageContractSetupResult, runStorageContract } from "./storageContract.mjs";
|
|
4
4
|
import Fastify, { FastifyInstance, FastifyServerOptions } from "fastify";
|
|
5
5
|
import { Connection } from "mongoose";
|
|
6
6
|
import { Mock } from "vitest";
|
|
7
|
+
import { StandardRepo } from "@classytic/repo-core/repository";
|
|
7
8
|
|
|
8
9
|
//#region src/testing/authHelpers.d.ts
|
|
9
10
|
interface BetterAuthTestHelpersOptions {
|
|
@@ -478,7 +479,7 @@ declare function createHttpTestHarness<T = unknown>(resource: ResourceDefinition
|
|
|
478
479
|
/**
|
|
479
480
|
* Extended repository interface for testing (includes optional preset methods)
|
|
480
481
|
*/
|
|
481
|
-
interface MockRepository<T> extends
|
|
482
|
+
interface MockRepository<T> extends StandardRepo<T> {
|
|
482
483
|
getBySlug?: Mock;
|
|
483
484
|
getDeleted?: Mock;
|
|
484
485
|
restore?: Mock;
|
|
@@ -519,8 +520,8 @@ declare function createMockReply(): unknown;
|
|
|
519
520
|
/**
|
|
520
521
|
* Create a mock controller for testing
|
|
521
522
|
*/
|
|
522
|
-
declare function createMockController(repository:
|
|
523
|
-
repository:
|
|
523
|
+
declare function createMockController(repository: StandardRepo<AnyRecord>): {
|
|
524
|
+
repository: StandardRepo<AnyRecord>;
|
|
524
525
|
list: Mock<(...args: any[]) => any>;
|
|
525
526
|
get: Mock<(...args: any[]) => any>;
|
|
526
527
|
create: Mock<(...args: any[]) => any>;
|
|
@@ -631,21 +632,12 @@ declare class TestHarness<T = unknown> {
|
|
|
631
632
|
private _createdIds;
|
|
632
633
|
constructor(resource: ResourceDefinition<unknown>, options: TestHarnessOptions<T>);
|
|
633
634
|
/**
|
|
634
|
-
* Run all baseline tests
|
|
635
|
+
* Run all baseline tests (schema, presets, field permissions, pipeline, events).
|
|
635
636
|
*
|
|
636
|
-
*
|
|
637
|
+
* For HTTP-level CRUD coverage (routes, auth, permissions), use
|
|
638
|
+
* {@link HttpTestHarness} instead.
|
|
637
639
|
*/
|
|
638
640
|
runAll(): void;
|
|
639
|
-
/**
|
|
640
|
-
* Run CRUD operation tests (model-level)
|
|
641
|
-
*
|
|
642
|
-
* Tests: create, read (list + getById), update, delete
|
|
643
|
-
*
|
|
644
|
-
* @deprecated Use `HttpTestHarness.runCrud()` for HTTP-level CRUD tests.
|
|
645
|
-
* This method tests Mongoose models directly and does not exercise
|
|
646
|
-
* HTTP routes, authentication, permissions, or the Arc pipeline.
|
|
647
|
-
*/
|
|
648
|
-
runCrud(): void;
|
|
649
641
|
/**
|
|
650
642
|
* Run validation tests
|
|
651
643
|
*
|
package/dist/testing/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as CRUD_OPERATIONS } from "../constants-
|
|
2
|
-
import { n as applyFieldWritePermissions, t as applyFieldReadPermissions } from "../fields-
|
|
1
|
+
import { t as CRUD_OPERATIONS } from "../constants-BhY1OHoH.mjs";
|
|
2
|
+
import { n as applyFieldWritePermissions, t as applyFieldReadPermissions } from "../fields-bxkeltzz.mjs";
|
|
3
3
|
import { runStorageContract } from "./storageContract.mjs";
|
|
4
4
|
import Fastify from "fastify";
|
|
5
5
|
import mongoose from "mongoose";
|
|
@@ -566,7 +566,10 @@ var HttpTestHarness = class {
|
|
|
566
566
|
this.resource = resource;
|
|
567
567
|
this.optionsOrGetter = optionsOrGetter;
|
|
568
568
|
if (typeof optionsOrGetter === "function") this.eagerBaseUrl = null;
|
|
569
|
-
else
|
|
569
|
+
else {
|
|
570
|
+
const apiPrefix = optionsOrGetter.apiPrefix ?? "/api";
|
|
571
|
+
this.eagerBaseUrl = `${apiPrefix}${resource.prefix}`;
|
|
572
|
+
}
|
|
570
573
|
const disabled = new Set(resource.disabledRoutes ?? []);
|
|
571
574
|
this.enabledRoutes = new Set(resource.disableDefaultRoutes ? [] : CRUD_OPERATIONS.filter((op) => !disabled.has(op)));
|
|
572
575
|
this.updateMethod = resource.updateMethod === "PUT" ? "PUT" : "PATCH";
|
|
@@ -877,12 +880,6 @@ function createHttpTestHarness(resource, optionsOrGetter) {
|
|
|
877
880
|
//#endregion
|
|
878
881
|
//#region src/testing/mocks.ts
|
|
879
882
|
/**
|
|
880
|
-
* Testing Utilities - Mock Factories
|
|
881
|
-
*
|
|
882
|
-
* Create mock repositories, controllers, and services for testing.
|
|
883
|
-
* Uses Vitest for mocking (compatible with Jest API).
|
|
884
|
-
*/
|
|
885
|
-
/**
|
|
886
883
|
* Create a mock repository for testing
|
|
887
884
|
*
|
|
888
885
|
* @example
|
|
@@ -896,6 +893,7 @@ function createHttpTestHarness(resource, optionsOrGetter) {
|
|
|
896
893
|
function createMockRepository(overrides = {}) {
|
|
897
894
|
return {
|
|
898
895
|
getAll: vi.fn().mockResolvedValue({
|
|
896
|
+
method: "offset",
|
|
899
897
|
docs: [],
|
|
900
898
|
total: 0,
|
|
901
899
|
page: 1,
|
|
@@ -1133,8 +1131,11 @@ function pickResource(value) {
|
|
|
1133
1131
|
* harness.runAll();
|
|
1134
1132
|
*
|
|
1135
1133
|
* // Or run specific test suites
|
|
1136
|
-
* harness.runCrud();
|
|
1137
1134
|
* harness.runPresets();
|
|
1135
|
+
* harness.runValidation();
|
|
1136
|
+
*
|
|
1137
|
+
* // For HTTP-level CRUD coverage (auth, permissions, routes), use
|
|
1138
|
+
* // `HttpTestHarness` from `@classytic/arc/testing`.
|
|
1138
1139
|
*/
|
|
1139
1140
|
var TestHarness = class {
|
|
1140
1141
|
resource;
|
|
@@ -1157,12 +1158,12 @@ var TestHarness = class {
|
|
|
1157
1158
|
this.Model = model;
|
|
1158
1159
|
}
|
|
1159
1160
|
/**
|
|
1160
|
-
* Run all baseline tests
|
|
1161
|
+
* Run all baseline tests (schema, presets, field permissions, pipeline, events).
|
|
1161
1162
|
*
|
|
1162
|
-
*
|
|
1163
|
+
* For HTTP-level CRUD coverage (routes, auth, permissions), use
|
|
1164
|
+
* {@link HttpTestHarness} instead.
|
|
1163
1165
|
*/
|
|
1164
1166
|
runAll() {
|
|
1165
|
-
this.runCrud();
|
|
1166
1167
|
this.runValidation();
|
|
1167
1168
|
this.runPresets();
|
|
1168
1169
|
this.runFieldPermissions();
|
|
@@ -1170,67 +1171,6 @@ var TestHarness = class {
|
|
|
1170
1171
|
this.runEvents();
|
|
1171
1172
|
}
|
|
1172
1173
|
/**
|
|
1173
|
-
* Run CRUD operation tests (model-level)
|
|
1174
|
-
*
|
|
1175
|
-
* Tests: create, read (list + getById), update, delete
|
|
1176
|
-
*
|
|
1177
|
-
* @deprecated Use `HttpTestHarness.runCrud()` for HTTP-level CRUD tests.
|
|
1178
|
-
* This method tests Mongoose models directly and does not exercise
|
|
1179
|
-
* HTTP routes, authentication, permissions, or the Arc pipeline.
|
|
1180
|
-
*/
|
|
1181
|
-
runCrud() {
|
|
1182
|
-
const { resource, fixtures, Model } = this;
|
|
1183
|
-
describe(`${resource.displayName} CRUD Operations`, () => {
|
|
1184
|
-
beforeAll(async () => {
|
|
1185
|
-
await mongoose.connect(this.mongoUri);
|
|
1186
|
-
if (this.setupFn) await this.setupFn();
|
|
1187
|
-
});
|
|
1188
|
-
afterAll(async () => {
|
|
1189
|
-
if (this._createdIds.length > 0) await Model.deleteMany({ _id: { $in: this._createdIds } });
|
|
1190
|
-
if (this.teardownFn) await this.teardownFn();
|
|
1191
|
-
await mongoose.disconnect();
|
|
1192
|
-
});
|
|
1193
|
-
describe("Create", () => {
|
|
1194
|
-
it("should create a new document with valid data", async () => {
|
|
1195
|
-
const doc = await Model.create(fixtures.valid);
|
|
1196
|
-
this._createdIds.push(doc._id);
|
|
1197
|
-
expect(doc).toBeDefined();
|
|
1198
|
-
expect(doc._id).toBeDefined();
|
|
1199
|
-
for (const [key, value] of Object.entries(fixtures.valid)) if (typeof value !== "object") expect(doc[key]).toEqual(value);
|
|
1200
|
-
});
|
|
1201
|
-
it("should have timestamps", async () => {
|
|
1202
|
-
const doc = await Model.findById(this._createdIds[0]);
|
|
1203
|
-
expect(doc).toBeDefined();
|
|
1204
|
-
expect(doc?.createdAt).toBeDefined();
|
|
1205
|
-
expect(doc?.updatedAt).toBeDefined();
|
|
1206
|
-
});
|
|
1207
|
-
});
|
|
1208
|
-
describe("Read", () => {
|
|
1209
|
-
it("should find document by ID", async () => {
|
|
1210
|
-
expect(await Model.findById(this._createdIds[0])).toBeDefined();
|
|
1211
|
-
});
|
|
1212
|
-
it("should list documents", async () => {
|
|
1213
|
-
const docs = await Model.find({});
|
|
1214
|
-
expect(Array.isArray(docs)).toBe(true);
|
|
1215
|
-
expect(docs.length).toBeGreaterThan(0);
|
|
1216
|
-
});
|
|
1217
|
-
});
|
|
1218
|
-
describe("Update", () => {
|
|
1219
|
-
it("should update document", async () => {
|
|
1220
|
-
const updateData = fixtures.update || { updatedAt: /* @__PURE__ */ new Date() };
|
|
1221
|
-
expect(await Model.findByIdAndUpdate(this._createdIds[0], updateData, { new: true })).toBeDefined();
|
|
1222
|
-
});
|
|
1223
|
-
});
|
|
1224
|
-
describe("Delete", () => {
|
|
1225
|
-
it("should delete document", async () => {
|
|
1226
|
-
const toDelete = await Model.create(fixtures.valid);
|
|
1227
|
-
await Model.findByIdAndDelete(toDelete._id);
|
|
1228
|
-
expect(await Model.findById(toDelete._id)).toBeNull();
|
|
1229
|
-
});
|
|
1230
|
-
});
|
|
1231
|
-
});
|
|
1232
|
-
}
|
|
1233
|
-
/**
|
|
1234
1174
|
* Run validation tests
|
|
1235
1175
|
*
|
|
1236
1176
|
* Tests schema validation, required fields, etc.
|
|
@@ -1371,7 +1311,7 @@ var TestHarness = class {
|
|
|
1371
1311
|
expect(result.otherField).toBe("visible");
|
|
1372
1312
|
});
|
|
1373
1313
|
it(`should strip hidden field '${field}' from writes`, () => {
|
|
1374
|
-
const result = applyFieldWritePermissions({
|
|
1314
|
+
const { body: result } = applyFieldWritePermissions({
|
|
1375
1315
|
[field]: "attempt",
|
|
1376
1316
|
name: "test"
|
|
1377
1317
|
}, fieldPerms, []);
|
|
@@ -1392,7 +1332,7 @@ var TestHarness = class {
|
|
|
1392
1332
|
break;
|
|
1393
1333
|
case "writableBy":
|
|
1394
1334
|
it(`should strip field '${field}' from writes by non-privileged users`, () => {
|
|
1395
|
-
const result = applyFieldWritePermissions({
|
|
1335
|
+
const { body: result } = applyFieldWritePermissions({
|
|
1396
1336
|
[field]: "new-value",
|
|
1397
1337
|
name: "test"
|
|
1398
1338
|
}, fieldPerms, ["viewer"]);
|
|
@@ -1402,7 +1342,8 @@ var TestHarness = class {
|
|
|
1402
1342
|
if (perm.roles && perm.roles.length > 0) {
|
|
1403
1343
|
const writeRole = perm.roles[0];
|
|
1404
1344
|
it(`should allow writing field '${field}' by roles: ${[...perm.roles].join(", ")}`, () => {
|
|
1405
|
-
|
|
1345
|
+
const { body: result } = applyFieldWritePermissions({ [field]: "new-value" }, fieldPerms, [writeRole]);
|
|
1346
|
+
expect(result[field]).toBe("new-value");
|
|
1406
1347
|
});
|
|
1407
1348
|
}
|
|
1408
1349
|
break;
|
|
@@ -1654,10 +1595,11 @@ function runFieldPermissionTests(displayName, fieldPerms) {
|
|
|
1654
1595
|
}, fieldPerms, [])[field]).toBeUndefined();
|
|
1655
1596
|
});
|
|
1656
1597
|
it(`should strip hidden field '${field}' from writes`, () => {
|
|
1657
|
-
|
|
1598
|
+
const { body: result } = applyFieldWritePermissions({
|
|
1658
1599
|
[field]: "attempt",
|
|
1659
1600
|
name: "test"
|
|
1660
|
-
}, fieldPerms, [])
|
|
1601
|
+
}, fieldPerms, []);
|
|
1602
|
+
expect(result[field]).toBeUndefined();
|
|
1661
1603
|
});
|
|
1662
1604
|
break;
|
|
1663
1605
|
case "visibleTo":
|
|
@@ -1673,15 +1615,17 @@ function runFieldPermissionTests(displayName, fieldPerms) {
|
|
|
1673
1615
|
break;
|
|
1674
1616
|
case "writableBy":
|
|
1675
1617
|
it(`should strip field '${field}' from writes by non-privileged users`, () => {
|
|
1676
|
-
|
|
1618
|
+
const { body: result } = applyFieldWritePermissions({
|
|
1677
1619
|
[field]: "v",
|
|
1678
1620
|
name: "test"
|
|
1679
|
-
}, fieldPerms, ["_no_role_"])
|
|
1621
|
+
}, fieldPerms, ["_no_role_"]);
|
|
1622
|
+
expect(result[field]).toBeUndefined();
|
|
1680
1623
|
});
|
|
1681
1624
|
if (perm.roles && perm.roles.length > 0) {
|
|
1682
1625
|
const writeRole = perm.roles[0];
|
|
1683
1626
|
it(`should allow writing field '${field}' by roles: ${[...perm.roles].join(", ")}`, () => {
|
|
1684
|
-
|
|
1627
|
+
const { body: result } = applyFieldWritePermissions({ [field]: "v" }, fieldPerms, [writeRole]);
|
|
1628
|
+
expect(result[field]).toBe("v");
|
|
1685
1629
|
});
|
|
1686
1630
|
}
|
|
1687
1631
|
break;
|
|
@@ -1797,7 +1741,7 @@ function runEventTests(resourceName, displayName, events) {
|
|
|
1797
1741
|
* ```
|
|
1798
1742
|
*/
|
|
1799
1743
|
async function createTestApp(options = {}) {
|
|
1800
|
-
const { createApp } = await import("../createApp-
|
|
1744
|
+
const { createApp } = await import("../createApp-BuvPma24.mjs").then((n) => n.r);
|
|
1801
1745
|
const { useInMemoryDb = true, mongoUri: providedMongoUri, ...appOptions } = options;
|
|
1802
1746
|
const defaultAuth = {
|
|
1803
1747
|
type: "jwt",
|
package/dist/types/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { n as ElevationOptions, t as ElevationEvent } from "../elevation-C5SwtkAn.mjs";
|
|
1
2
|
import { _ as isAuthenticated, c as getOrgRoles, g as hasOrgAccess, n as PUBLIC_SCOPE, p as getTeamId, r as RequestScope, s as getOrgId, t as AUTHENTICATED_SCOPE, v as isElevated, y as isMember } from "../types-BD85MlEK.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
export { AUTHENTICATED_SCOPE, ActionDefinition, ActionEntry, ActionHandlerFn, ActionsMap, AdditionalRoute, AnyRecord, ApiResponse, ArcDecorator, ArcInternalMetadata, ArcRequest, AuthHelpers, AuthPluginOptions, Authenticator, AuthenticatorContext, BaseControllerOptions, BulkWriteOperation, BulkWriteResult, ConfigError, ControllerHandler, ControllerLike, ControllerQueryOptions, CrudController, CrudRepository, CrudRouteKey, CrudRouterOptions, CrudSchemas, DeleteManyResult, DeleteOptions, DeleteResult, ElevationEvent, ElevationOptions, EventDefinition, EventsDecorator, FastifyHandler, FastifyRequestExtras, FastifyWithAuth, FastifyWithDecorators, FieldRule, GracefulShutdownOptions, HealthCheck, HealthOptions, IController, IControllerResponse, IRequestContext, InferAdapterDoc, InferDoc, InferDocType, InferResourceDoc, IntrospectionData, IntrospectionPluginOptions, JWTPayload, JwtContext, KeysetPaginatedResult, LookupOption, MiddlewareConfig, MiddlewareHandler, ObjectId, OffsetPaginatedResult, OpenApiSchemas, OwnershipCheck, PUBLIC_SCOPE, PaginatedResult, PaginationParams, PaginationResult, ParsedQuery, PermissionCheck, PermissionContext, PermissionResult, PopulateOption, PresetFunction, PresetHook, PresetResult, QueryOptions, QueryParserInterface, RateLimitConfig, RegistryEntry, RegistryStats, RepositorySession, RequestContext, RequestIdOptions, RequestScope, RequestWithExtras, ResourceCacheConfig, ResourceConfig, ResourceHookContext, ResourceHooks, ResourceMetadata, ResourcePermissions, RouteDefinition, RouteHandler, RouteHandlerMethod, RouteMcpConfig, RouteSchemaOptions, ServiceContext, TokenPair, TypedController, TypedRepository, TypedResourceConfig, UpdateManyResult, UserBase, UserLike, UserOrganization, ValidateOptions, ValidationResult, WriteOptions, envelope, getOrgId, getOrgRoles, getTeamId, getUserId, hasOrgAccess, isAuthenticated, isElevated, isMember };
|
|
3
|
+
import { c as PermissionCheck, d as UserBase, l as PermissionContext, u as PermissionResult } from "../fields-Lo1VUDpt.mjs";
|
|
4
|
+
import { $ as CrudSchemas, A as AuthHelpers, B as FastifyWithDecorators, Bt as ArcInternalMetadata, C as ResourceMetadata, Ct as RouteHandler, D as HealthOptions, E as HealthCheck, F as TokenPair, Gt as PopulateOption, H as RequestWithExtras, Ht as LookupOption, I as ArcDecorator, J as ActionEntry, Jt as ServiceContext, Kt as QueryParserInterface, L as EventsDecorator, M as Authenticator, N as AuthenticatorContext, O as IntrospectionPluginOptions, P as JwtContext, Q as CrudRouteKey, R as FastifyRequestExtras, S as RegistryStats, St as IRequestContext, T as GracefulShutdownOptions, Ut as OwnershipCheck, V as MiddlewareHandler, Vt as ControllerQueryOptions, Wt as ParsedQuery, X as ActionsMap, Y as ActionHandlerFn, Z as CrudController, _ as ConfigError, _n as UserOrganization, _t as ControllerHandler, at as PresetHook, b as IntrospectionData, bt as IController, ct as ResourceCacheConfig, d as InferAdapterDoc, dn as AnyRecord, dt as ResourceHooks, et as EventDefinition, f as InferDocType, fn as ApiResponse, ft as ResourcePermissions, g as TypedResourceConfig, gn as UserLike, gt as RouteSchemaOptions, h as TypedRepository, hn as ObjectId, ht as RouteMethod, it as PresetFunction, j as AuthPluginOptions, k as RequestIdOptions, lt as ResourceConfig, m as TypedController, mn as JWTPayload, mt as RouteMcpConfig, nt as MiddlewareConfig, ot as PresetResult, p as InferResourceDoc, pn as ArcRequest, pt as RouteDefinition, q as ActionDefinition, qt as RequestContext, r as BaseControllerOptions, rt as OpenApiSchemas, st as RateLimitConfig, t as RouteHandlerMethod, tt as FieldRule, u as PaginationResult, ut as ResourceHookContext, v as ValidateOptions, vn as envelope, vt as ControllerLike, w as CrudRouterOptions, x as RegistryEntry, xt as IControllerResponse, y as ValidationResult, yn as getUserId, yt as FastifyHandler, z as FastifyWithAuth } from "../index-Cl0uoKd5.mjs";
|
|
5
|
+
export { AUTHENTICATED_SCOPE, ActionDefinition, ActionEntry, ActionHandlerFn, ActionsMap, AnyRecord, ApiResponse, ArcDecorator, ArcInternalMetadata, ArcRequest, AuthHelpers, AuthPluginOptions, Authenticator, AuthenticatorContext, BaseControllerOptions, ConfigError, ControllerHandler, ControllerLike, ControllerQueryOptions, CrudController, CrudRouteKey, CrudRouterOptions, CrudSchemas, ElevationEvent, ElevationOptions, EventDefinition, EventsDecorator, FastifyHandler, FastifyRequestExtras, FastifyWithAuth, FastifyWithDecorators, FieldRule, GracefulShutdownOptions, HealthCheck, HealthOptions, IController, IControllerResponse, IRequestContext, InferAdapterDoc, InferDocType, InferResourceDoc, IntrospectionData, IntrospectionPluginOptions, JWTPayload, JwtContext, LookupOption, MiddlewareConfig, MiddlewareHandler, ObjectId, OpenApiSchemas, OwnershipCheck, PUBLIC_SCOPE, PaginationResult, ParsedQuery, PermissionCheck, PermissionContext, PermissionResult, PopulateOption, PresetFunction, PresetHook, PresetResult, QueryParserInterface, RateLimitConfig, RegistryEntry, RegistryStats, RequestContext, RequestIdOptions, RequestScope, RequestWithExtras, ResourceCacheConfig, ResourceConfig, ResourceHookContext, ResourceHooks, ResourceMetadata, ResourcePermissions, RouteDefinition, RouteHandler, RouteHandlerMethod, RouteMcpConfig, RouteMethod, RouteSchemaOptions, ServiceContext, TokenPair, TypedController, TypedRepository, TypedResourceConfig, UserBase, UserLike, UserOrganization, ValidateOptions, ValidationResult, envelope, getOrgId, getOrgRoles, getTeamId, getUserId, hasOrgAccess, isAuthenticated, isElevated, isMember };
|
package/dist/types/index.mjs
CHANGED
|
@@ -1,33 +1,3 @@
|
|
|
1
1
|
import { _ as isElevated, f as getTeamId, g as isAuthenticated, h as hasOrgAccess, n as PUBLIC_SCOPE, o as getOrgId, s as getOrgRoles, t as AUTHENTICATED_SCOPE, v as isMember } from "../types-AOD8fxIw.mjs";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Response envelope helper — wraps data in Arc's standard `{ success, data }` format.
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* ```typescript
|
|
8
|
-
* import { envelope } from '@classytic/arc';
|
|
9
|
-
*
|
|
10
|
-
* handler: async (req, reply) => {
|
|
11
|
-
* const data = await getResults();
|
|
12
|
-
* return envelope(data);
|
|
13
|
-
* // → { success: true, data }
|
|
14
|
-
* }
|
|
15
|
-
* ```
|
|
16
|
-
*/
|
|
17
|
-
function envelope(data, meta) {
|
|
18
|
-
return {
|
|
19
|
-
success: true,
|
|
20
|
-
data,
|
|
21
|
-
...meta
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Extract user ID from a user object (supports both id and _id)
|
|
26
|
-
*/
|
|
27
|
-
function getUserId(user) {
|
|
28
|
-
if (!user) return void 0;
|
|
29
|
-
const id = user.id ?? user._id;
|
|
30
|
-
return id ? String(id) : void 0;
|
|
31
|
-
}
|
|
32
|
-
//#endregion
|
|
2
|
+
import { n as getUserId, t as envelope } from "../types-Csi3FLfq.mjs";
|
|
33
3
|
export { AUTHENTICATED_SCOPE, PUBLIC_SCOPE, envelope, getOrgId, getOrgRoles, getTeamId, getUserId, hasOrgAccess, isAuthenticated, isElevated, isMember };
|
package/dist/types/storage.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as StorageReadResult, i as StorageReadRange, n as StorageContext, o as StorageUploadInput, r as StorageFile, t as Storage } from "../storage-
|
|
1
|
+
import { a as StorageReadResult, i as StorageReadRange, n as StorageContext, o as StorageUploadInput, r as StorageFile, t as Storage } from "../storage-CVk_SEn2.mjs";
|
|
2
2
|
export { Storage, StorageContext, StorageFile, StorageReadRange, StorageReadResult, StorageUploadInput };
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { r as
|
|
6
|
-
import {
|
|
7
|
-
import { t as EventPluginOptions } from "./eventPlugin-
|
|
8
|
-
import {
|
|
9
|
-
import { r as IdempotencyStore } from "./interface-
|
|
1
|
+
import { n as ElevationOptions } from "./elevation-C5SwtkAn.mjs";
|
|
2
|
+
import { M as Authenticator } from "./index-Cl0uoKd5.mjs";
|
|
3
|
+
import { o as EventTransport } from "./EventTransport-CUw5NNWe.mjs";
|
|
4
|
+
import { t as ExternalOpenApiPaths } from "./externalPaths-BQ8QijNH.mjs";
|
|
5
|
+
import { r as CacheStore } from "./interface-D218ikEo.mjs";
|
|
6
|
+
import { r as QueryCachePluginOptions } from "./queryCachePlugin-BKbWjgDG.mjs";
|
|
7
|
+
import { t as EventPluginOptions } from "./eventPlugin-CxWgpd6K.mjs";
|
|
8
|
+
import { a as VersioningOptions, g as CachingOptions, p as SSEOptions, t as ErrorHandlerOptions, u as MetricsOptions } from "./errorHandler-DRQ3EqfL.mjs";
|
|
9
|
+
import { r as IdempotencyStore } from "./interface-CSbZdv_3.mjs";
|
|
10
10
|
import { FastifyInstance, FastifyPluginAsync, FastifyReply, FastifyRequest, FastifyServerOptions } from "fastify";
|
|
11
11
|
|
|
12
12
|
//#region src/factory/loadResources.d.ts
|
|
@@ -409,6 +409,8 @@ interface CreateAppOptions {
|
|
|
409
409
|
debug?: boolean | string;
|
|
410
410
|
/** Trust proxy headers (X-Forwarded-For, etc.) */
|
|
411
411
|
trustProxy?: boolean;
|
|
412
|
+
/** Fastify plugin/onReady timeout in ms (default: 10_000). Raise for slow boot work (index materialisation, WAL replay, external warm-up). */
|
|
413
|
+
pluginTimeout?: number;
|
|
412
414
|
/**
|
|
413
415
|
* Auth configuration
|
|
414
416
|
*
|