@classytic/arc 2.15.3 → 2.16.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.
Files changed (159) hide show
  1. package/README.md +1 -0
  2. package/bin/arc.js +12 -0
  3. package/dist/{BaseController-dx3m2J8V.mjs → BaseController-DlCCTIxJ.mjs} +61 -19
  4. package/dist/{HookSystem-Iiebom92.mjs → HookSystem-Cmf7-Etp.mjs} +8 -4
  5. package/dist/{QueryCache-D41bfdBB.d.mts → QueryCache-SvmT_9ti.d.mts} +1 -1
  6. package/dist/{ResourceRegistry-CTERg_2x.mjs → ResourceRegistry-f48hFk3m.mjs} +52 -9
  7. package/dist/audit/index.d.mts +1 -1
  8. package/dist/audit/index.mjs +4 -2
  9. package/dist/auth/index.d.mts +4 -4
  10. package/dist/auth/index.mjs +4 -4
  11. package/dist/auth/redis-session.d.mts +1 -1
  12. package/dist/{betterAuthOpenApi--M_i87dQ.mjs → betterAuthOpenApi-ClWxaceA.mjs} +10 -6
  13. package/dist/buildHandler-BZX6zzDM.mjs +300 -0
  14. package/dist/cache/index.d.mts +3 -3
  15. package/dist/cache/index.mjs +3 -3
  16. package/dist/{caching-SM8gghN6.mjs → caching-TeHE8G-v.mjs} +1 -1
  17. package/dist/cli/commands/describe.d.mts +35 -1
  18. package/dist/cli/commands/describe.mjs +52 -12
  19. package/dist/cli/commands/docs.d.mts +1 -4
  20. package/dist/cli/commands/docs.mjs +4 -16
  21. package/dist/cli/commands/generate.d.mts +2 -20
  22. package/dist/cli/commands/generate.mjs +1 -546
  23. package/dist/cli/commands/init.d.mts +2 -40
  24. package/dist/cli/commands/init.mjs +1 -3036
  25. package/dist/cli/commands/introspect.mjs +53 -64
  26. package/dist/cli/index.d.mts +2 -2
  27. package/dist/cli/index.mjs +2 -2
  28. package/dist/{constants-Cxde4rpC.mjs → constants-TrJVIJl0.mjs} +7 -0
  29. package/dist/core/index.d.mts +3 -3
  30. package/dist/core/index.mjs +5 -5
  31. package/dist/{core-CvmOqEms.mjs → core-DBJ_j6rX.mjs} +222 -44
  32. package/dist/createActionRouter-DUpN3Dd1.mjs +288 -0
  33. package/dist/{createAggregationRouter-B0bPDf5b.mjs → createAggregationRouter-Dq-TUCuY.mjs} +3 -2
  34. package/dist/{createApp-PFegs47-.mjs → createApp-DNccuhyI.mjs} +16 -14
  35. package/dist/{defineEvent-D5h7EvAx.mjs → defineEvent-DRwY0fYm.mjs} +1 -1
  36. package/dist/docs/index.d.mts +2 -2
  37. package/dist/docs/index.mjs +1 -1
  38. package/dist/{errorHandler-Bk-AGhkU.mjs → errorHandler-DpoXQHZ9.mjs} +17 -14
  39. package/dist/errors-C1lX_jlm.d.mts +91 -0
  40. package/dist/{eventPlugin-CaKTYkYM.mjs → eventPlugin-C2cGqtRO.mjs} +1 -1
  41. package/dist/{eventPlugin-qXpqTebY.d.mts → eventPlugin-CtHC_av1.d.mts} +1 -1
  42. package/dist/events/index.d.mts +3 -3
  43. package/dist/events/index.mjs +5 -5
  44. package/dist/events/transports/redis-stream-entry.d.mts +1 -1
  45. package/dist/events/transports/redis.d.mts +1 -1
  46. package/dist/factory/index.d.mts +1 -1
  47. package/dist/factory/index.mjs +2 -2
  48. package/dist/{fields-COhcH3fk.d.mts → fields-Anj0xdih.d.mts} +1 -1
  49. package/dist/generate-BWFwgcCM.d.mts +38 -0
  50. package/dist/generate-CYac-OLv.mjs +654 -0
  51. package/dist/hooks/index.d.mts +1 -1
  52. package/dist/hooks/index.mjs +1 -1
  53. package/dist/idempotency/index.d.mts +2 -2
  54. package/dist/idempotency/index.mjs +1 -1
  55. package/dist/idempotency/redis.d.mts +1 -1
  56. package/dist/{index-BTqLEvhu.d.mts → index-3oIimXQn.d.mts} +12 -12
  57. package/dist/{index-BstGxcc3.d.mts → index-B-ulKx5P.d.mts} +55 -4
  58. package/dist/{index-BswOSJCE.d.mts → index-CkW0flkU.d.mts} +355 -16
  59. package/dist/index.d.mts +6 -6
  60. package/dist/index.mjs +7 -8
  61. package/dist/init-Dv71MsJr.d.mts +71 -0
  62. package/dist/init-HDvoO9L5.mjs +3098 -0
  63. package/dist/integrations/event-gateway.d.mts +2 -2
  64. package/dist/integrations/event-gateway.mjs +1 -1
  65. package/dist/integrations/index.d.mts +2 -2
  66. package/dist/integrations/jobs.mjs +3 -3
  67. package/dist/integrations/mcp/index.d.mts +239 -7
  68. package/dist/integrations/mcp/index.mjs +2 -528
  69. package/dist/integrations/mcp/testing.d.mts +2 -2
  70. package/dist/integrations/mcp/testing.mjs +6 -10
  71. package/dist/integrations/streamline.d.mts +71 -2
  72. package/dist/integrations/streamline.mjs +81 -8
  73. package/dist/integrations/websocket-redis.d.mts +1 -1
  74. package/dist/integrations/websocket.d.mts +1 -1
  75. package/dist/integrations/websocket.mjs +1 -0
  76. package/dist/loadResourcesFromEntry-BLMEI2Xa.mjs +51 -0
  77. package/dist/{resourceToTools-tFYUNmM0.mjs → mcpPlugin-7vGV51ED.mjs} +1021 -318
  78. package/dist/{memory-UBydS5ku.mjs → memory-QOLe11D5.mjs} +2 -0
  79. package/dist/middleware/index.d.mts +1 -1
  80. package/dist/middleware/index.mjs +1 -1
  81. package/dist/{openapi-BHXhoX8O.mjs → openapi-34T9yNwd.mjs} +47 -36
  82. package/dist/permissions/index.d.mts +2 -2
  83. package/dist/permissions/index.mjs +1 -1
  84. package/dist/{permissions-ohQyv50e.mjs → permissions-CTxMrreC.mjs} +2 -2
  85. package/dist/{pipe-Zr0KXjQe.mjs → pipe-DiCyvyPN.mjs} +1 -0
  86. package/dist/pipeline/index.d.mts +1 -1
  87. package/dist/pipeline/index.mjs +1 -1
  88. package/dist/plugins/index.d.mts +5 -5
  89. package/dist/plugins/index.mjs +10 -10
  90. package/dist/plugins/response-cache.mjs +5 -5
  91. package/dist/plugins/tracing-entry.d.mts +1 -1
  92. package/dist/plugins/tracing-entry.mjs +1 -1
  93. package/dist/{pluralize-DQgqgifU.mjs → pluralize-B9M8xvy-.mjs} +2 -1
  94. package/dist/presets/filesUpload.d.mts +4 -4
  95. package/dist/presets/filesUpload.mjs +2 -2
  96. package/dist/presets/index.d.mts +1 -1
  97. package/dist/presets/index.mjs +1 -1
  98. package/dist/presets/multiTenant.d.mts +1 -1
  99. package/dist/presets/multiTenant.mjs +4 -3
  100. package/dist/presets/search.d.mts +2 -2
  101. package/dist/presets/search.mjs +1 -1
  102. package/dist/{presets-BbkjdPeH.mjs → presets-C9BE6WaZ.mjs} +2 -2
  103. package/dist/{queryCachePlugin-m1XsgAIJ.mjs → queryCachePlugin-B4XMSSe7.mjs} +2 -2
  104. package/dist/{queryCachePlugin-CqMdLI2-.d.mts → queryCachePlugin-Biqzfbi5.d.mts} +2 -2
  105. package/dist/{redis-DiMkdHEl.d.mts → redis-Cyzrz6SX.d.mts} +1 -1
  106. package/dist/{redis-stream-D6HzR1Z_.d.mts → redis-stream-DT-YjzrB.d.mts} +1 -1
  107. package/dist/registry/index.d.mts +319 -2
  108. package/dist/registry/index.mjs +3 -3
  109. package/dist/registry-BBE23CDj.mjs +576 -0
  110. package/dist/{routerShared-DrOa-26E.mjs → routerShared-CZV5aabX.mjs} +3 -3
  111. package/dist/scope/index.d.mts +3 -3
  112. package/dist/scope/index.mjs +3 -3
  113. package/dist/{sse-Bz-5ZeTt.mjs → sse-BY6sTy4P.mjs} +1 -1
  114. package/dist/testing/index.d.mts +2 -2
  115. package/dist/testing/index.mjs +16 -7
  116. package/dist/testing/storageContract.d.mts +1 -1
  117. package/dist/types/index.d.mts +5 -5
  118. package/dist/types/storage.d.mts +1 -1
  119. package/dist/{types-C_s5moIu.mjs → types-Bi0r0vjG.mjs} +53 -1
  120. package/dist/{types-BQsjgQzS.d.mts → types-BsJMEQ4D.d.mts} +106 -12
  121. package/dist/{types-DrBaUwyV.d.mts → types-D-fYtKjb.d.mts} +33 -10
  122. package/dist/{types-CTYvcwHe.d.mts → types-DVfpSfx2.d.mts} +42 -1
  123. package/dist/utils/index.d.mts +1286 -2
  124. package/dist/utils/index.mjs +1 -1
  125. package/dist/{utils-_h9B3c57.mjs → utils-DC5ycPfr.mjs} +89 -40
  126. package/dist/{buildHandler-CcFOpJLh.mjs → validate-By96rH0r.mjs} +8 -299
  127. package/dist/{versioning-hmkPcDlX.d.mts → versioning-ZwX9tmbS.d.mts} +1 -1
  128. package/package.json +22 -29
  129. package/skills/arc/SKILL.md +299 -689
  130. package/skills/arc/references/auth.md +19 -7
  131. package/skills/arc-code-review/SKILL.md +1 -1
  132. package/skills/arc-code-review/references/arc-cheatsheet.md +100 -322
  133. package/dist/createActionRouter-S3MLVYot.mjs +0 -220
  134. package/dist/index-bRjYu21O.d.mts +0 -1320
  135. package/dist/org/index.d.mts +0 -66
  136. package/dist/org/index.mjs +0 -486
  137. package/dist/org/types.d.mts +0 -82
  138. package/dist/org/types.mjs +0 -1
  139. package/dist/registry-I-ogLgL9.mjs +0 -46
  140. /package/dist/{EventTransport-CT_52aWU.d.mts → EventTransport-C-2oAHtw.d.mts} +0 -0
  141. /package/dist/{EventTransport-DLWoUMHy.mjs → EventTransport-Hxvv5QQz.mjs} +0 -0
  142. /package/dist/{actionPermissions-CyUkQu6O.mjs → actionPermissions-Bjmvn7Eb.mjs} +0 -0
  143. /package/dist/{elevation-BXOWoGCF.d.mts → elevation-0YBpa663.d.mts} +0 -0
  144. /package/dist/{elevation-DgoeTyfX.mjs → elevation-Dci0AYLT.mjs} +0 -0
  145. /package/dist/{errorHandler-DFr45ZG4.d.mts → errorHandler-mHuyWzZE.d.mts} +0 -0
  146. /package/dist/{externalPaths-BD5nw6St.d.mts → externalPaths-DFg-2KTp.d.mts} +0 -0
  147. /package/dist/{interface-beEtJyWM.d.mts → interface-CH0OQudo.d.mts} +0 -0
  148. /package/dist/{interface-DfLGcus7.d.mts → interface-NwJ_qPlY.d.mts} +0 -0
  149. /package/dist/{keys-CGcCbNyu.mjs → keys-DopsCuyQ.mjs} +0 -0
  150. /package/dist/{loadResources-DBMQg_Aj.mjs → loadResources-ChQEj8ih.mjs} +0 -0
  151. /package/dist/{metrics-Qnvwc-LQ.mjs → metrics-TuOmguhi.mjs} +0 -0
  152. /package/dist/{replyHelpers-CK-FNO8E.mjs → replyHelpers-C-gD32oF.mjs} +0 -0
  153. /package/dist/{schemaIR-lYhC2gE5.mjs → schemaIR-Ctc89DSn.mjs} +0 -0
  154. /package/dist/{sessionManager-C4Le_UB3.d.mts → sessionManager-BqFegc0W.d.mts} +0 -0
  155. /package/dist/{storage-Dfzt4VTl.d.mts → storage-D2KZJAmn.d.mts} +0 -0
  156. /package/dist/{store-helpers-BkIN9-vu.mjs → store-helpers-B0sunfZZ.mjs} +0 -0
  157. /package/dist/{tracing-QJVprktp.d.mts → tracing-Dm8n7Cnn.d.mts} +0 -0
  158. /package/dist/{versioning-BUrT5aP4.mjs → versioning-B6mimogM.mjs} +0 -0
  159. /package/dist/{websocket-ChC2rqe1.d.mts → websocket-BkjeGZRn.d.mts} +0 -0
@@ -1,4 +1,4 @@
1
- import { t as CRUD_OPERATIONS } from "../constants-Cxde4rpC.mjs";
1
+ import { t as CRUD_OPERATIONS } from "../constants-TrJVIJl0.mjs";
2
2
  import { runStorageContract } from "./storageContract.mjs";
3
3
  import Fastify from "fastify";
4
4
  import { afterAll, describe, expect, it, vi } from "vitest";
@@ -415,7 +415,10 @@ async function setupBetterAuthTestApp(input) {
415
415
  user: u
416
416
  };
417
417
  }
418
- const creatorRec = signedUp[creators[0].key];
418
+ const creator = creators[0];
419
+ if (!creator) throw new Error("[arc-testing] setupBetterAuthTestApp: no `isCreator: true` user supplied");
420
+ const creatorRec = signedUp[creator.key];
421
+ if (!creatorRec) throw new Error(`[arc-testing] setupBetterAuthTestApp: creator '${creator.key}' missing from signed-up roster`);
419
422
  const orgRes = await helpers.createOrg(app, creatorRec.token, org);
420
423
  if (orgRes.statusCode >= 400 || !orgRes.orgId) throw new Error(`[arc-testing] setupBetterAuthTestApp: createOrg failed. statusCode=${orgRes.statusCode}, orgId=${orgRes.orgId ? "ok" : "missing"}, body=${JSON.stringify(orgRes.body).slice(0, 300)}`);
421
424
  const orgId = orgRes.orgId;
@@ -423,6 +426,7 @@ async function setupBetterAuthTestApp(input) {
423
426
  if (u.isCreator === true) continue;
424
427
  if (!addMember) continue;
425
428
  const rec = signedUp[u.key];
429
+ if (!rec) continue;
426
430
  const res = await addMember({
427
431
  app,
428
432
  creatorToken: creatorRec.token,
@@ -486,6 +490,7 @@ function createTestFixtures() {
486
490
  async clear() {
487
491
  for (let i = tracked.length - 1; i >= 0; i--) {
488
492
  const entry = tracked[i];
493
+ if (!entry) continue;
489
494
  if (entry.destroy) await entry.destroy(entry.record).catch(() => {});
490
495
  }
491
496
  tracked.length = 0;
@@ -541,7 +546,9 @@ var HttpTestHarness = class {
541
546
  this.runValidation();
542
547
  }
543
548
  runCrud() {
544
- const { resource, enabledRoutes, updateMethods } = this;
549
+ const resource = this.resource;
550
+ const enabledRoutes = this.enabledRoutes;
551
+ const updateMethods = this.updateMethods;
545
552
  let createdId = null;
546
553
  describe(`${resource.displayName} HTTP CRUD`, () => {
547
554
  afterAll(async () => {
@@ -663,7 +670,9 @@ var HttpTestHarness = class {
663
670
  });
664
671
  }
665
672
  runPermissions() {
666
- const { resource, enabledRoutes, updateMethods } = this;
673
+ const resource = this.resource;
674
+ const enabledRoutes = this.enabledRoutes;
675
+ const updateMethods = this.updateMethods;
667
676
  const protectedOps = {
668
677
  list: opRequiresAuth(resource, "list"),
669
678
  get: opRequiresAuth(resource, "get"),
@@ -737,8 +746,8 @@ var HttpTestHarness = class {
737
746
  });
738
747
  }
739
748
  runValidation() {
740
- const { resource, enabledRoutes } = this;
741
- if (!enabledRoutes.has("create")) return;
749
+ const resource = this.resource;
750
+ if (!this.enabledRoutes.has("create")) return;
742
751
  describe(`${resource.displayName} HTTP Validation`, () => {
743
752
  it("POST with invalid payload should be rejected", async () => {
744
753
  const { app, fixtures } = this.getOptions();
@@ -1070,7 +1079,7 @@ function pickDefaultAuth(authMode, callerAuth) {
1070
1079
  };
1071
1080
  }
1072
1081
  async function createTestApp(options = {}) {
1073
- const { createApp } = await import("../createApp-PFegs47-.mjs").then((n) => n.r);
1082
+ const { createApp } = await import("../createApp-DNccuhyI.mjs").then((n) => n.r);
1074
1083
  const { resources = [], db = "in-memory", connectMongoose = false, authMode = "jwt", defaultOrgId, plugins, auth: callerAuth, ...appOptions } = options;
1075
1084
  let dbHandle;
1076
1085
  let dbUri;
@@ -1,4 +1,4 @@
1
- import { t as Storage } from "../storage-Dfzt4VTl.mjs";
1
+ import { t as Storage } from "../storage-D2KZJAmn.mjs";
2
2
 
3
3
  //#region src/testing/storageContract.d.ts
4
4
  interface StorageContractSetupResult {
@@ -1,5 +1,5 @@
1
- import { $ as OpenApiSchemas, A as RequestIdOptions, Bt as Authenticator, C as RequestContext, D as HealthCheck, E as GracefulShutdownOptions, F as FastifyWithDecorators, G as ActionsMap, Gt as ApiResponse, H as ActionDefinition, Ht as JwtContext, I as MiddlewareHandler, J as CrudRouteKey, Jt as ObjectId, K as ArcFieldRule, Kt as ArcRequest, L as RequestWithExtras, M as EventsDecorator, N as FastifyRequestExtras, O as HealthOptions, P as FastifyWithAuth, Q as MiddlewareConfig, Rt as AuthHelpers, S as QueryParserInterface, T as CrudRouterOptions, U as ActionEntry, Ut as TokenPair, Vt as AuthenticatorContext, W as ActionHandlerFn, Wt as AnyRecord, X as EventDefinition, Xt as UserOrganization, Y as CrudSchemas, Yt as UserLike, Z as FieldRule, _ as ControllerQueryOptions, _t as IControllerResponse, a as InferAdapterDoc, at as ResourceConfig, b as ParsedQuery, c as TypedController, ct as ResourcePermissions, d as PaginationResult, dt as RouteMethod, et as PresetFunction, f as IntrospectionData, ft as RouteSchemaOptions, g as ArcInternalMetadata, gt as IController, h as ResourceMetadata, ht as FastifyHandler, i as ValidationResult, it as ResourceCacheConfig, j as ArcDecorator, k as IntrospectionPluginOptions, l as TypedRepository, lt as RouteDefinition, m as RegistryStats, mt as ControllerLike, n as ConfigError, nt as PresetResult, o as InferDocType, on as BaseControllerOptions, ot as ResourceHookContext, p as RegistryEntry, pt as ControllerHandler, q as CrudController, qt as JWTPayload, r as ValidateOptions, rt as RateLimitConfig, s as InferResourceDoc, st as ResourceHooks, t as RouteHandlerMethod, tt as PresetHook, u as TypedResourceConfig, ut as RouteMcpConfig, v as LookupOption, vt as IRequestContext, w as ServiceContext, x as PopulateOption, y as OwnershipCheck, yt as RouteHandler, zt as AuthPluginOptions } from "../index-BswOSJCE.mjs";
2
- import { i as RequestScope } from "../types-CTYvcwHe.mjs";
3
- import { c as PermissionCheck, d as UserBase, l as PermissionContext, u as PermissionResult } from "../fields-COhcH3fk.mjs";
4
- import { n as ElevationOptions, t as ElevationEvent } from "../elevation-BXOWoGCF.mjs";
5
- export { ActionDefinition, ActionEntry, ActionHandlerFn, ActionsMap, AnyRecord, ApiResponse, ArcDecorator, ArcFieldRule, 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, 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 };
1
+ import { $ as OnTenantDeleteConfig, A as RequestIdOptions, Bt as AuthHelpers, C as RequestContext, D as HealthCheck, E as GracefulShutdownOptions, F as FastifyWithDecorators, G as ActionsMap, Gt as TokenPair, H as ActionDefinition, Ht as Authenticator, I as MiddlewareHandler, J as CrudRouteKey, Jt as ArcRequest, K as ArcFieldRule, Kt as AnyRecord, L as RequestWithExtras, M as EventsDecorator, N as FastifyRequestExtras, O as HealthOptions, P as FastifyWithAuth, Q as MiddlewareConfig, Qt as UserOrganization, S as QueryParserInterface, T as CrudRouterOptions, U as ActionEntry, Ut as AuthenticatorContext, Vt as AuthPluginOptions, W as ActionHandlerFn, Wt as JwtContext, X as EventDefinition, Xt as ObjectId, Y as CrudSchemas, Yt as JWTPayload, Z as FieldRule, Zt as UserLike, _ as ControllerQueryOptions, _t as FastifyHandler, a as InferAdapterDoc, at as ResolvedTenantPurge, b as ParsedQuery, bt as IRequestContext, c as TypedController, cn as BaseControllerOptions, ct as ResourceHookContext, d as PaginationResult, dt as RouteDefinition, et as OpenApiSchemas, f as IntrospectionData, ft as RouteMcpConfig, g as ArcInternalMetadata, gt as ControllerLike, h as ResourceMetadata, ht as ControllerHandler, i as ValidationResult, it as RateLimitConfig, j as ArcDecorator, k as IntrospectionPluginOptions, l as TypedRepository, lt as ResourceHooks, m as RegistryStats, mt as RouteSchemaOptions, n as ConfigError, nt as PresetHook, o as InferDocType, ot as ResourceCacheConfig, p as RegistryEntry, pt as RouteMethod, q as CrudController, qt as ApiResponse, r as ValidateOptions, rt as PresetResult, s as InferResourceDoc, st as ResourceConfig, t as RouteHandlerMethod, tt as PresetFunction, u as TypedResourceConfig, ut as ResourcePermissions, v as LookupOption, vt as IController, w as ServiceContext, x as PopulateOption, xt as RouteHandler, y as OwnershipCheck, yt as IControllerResponse } from "../index-CkW0flkU.mjs";
2
+ import { i as RequestScope } from "../types-DVfpSfx2.mjs";
3
+ import { c as PermissionCheck, d as UserBase, l as PermissionContext, u as PermissionResult } from "../fields-Anj0xdih.mjs";
4
+ import { n as ElevationOptions, t as ElevationEvent } from "../elevation-0YBpa663.mjs";
5
+ export { ActionDefinition, ActionEntry, ActionHandlerFn, ActionsMap, AnyRecord, ApiResponse, ArcDecorator, ArcFieldRule, 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, OnTenantDeleteConfig, OpenApiSchemas, OwnershipCheck, PaginationResult, ParsedQuery, PermissionCheck, PermissionContext, PermissionResult, PopulateOption, PresetFunction, PresetHook, PresetResult, QueryParserInterface, RateLimitConfig, RegistryEntry, RegistryStats, RequestContext, RequestIdOptions, RequestScope, RequestWithExtras, ResolvedTenantPurge, ResourceCacheConfig, ResourceConfig, ResourceHookContext, ResourceHooks, ResourceMetadata, ResourcePermissions, RouteDefinition, RouteHandler, RouteHandlerMethod, RouteMcpConfig, RouteMethod, RouteSchemaOptions, ServiceContext, TokenPair, TypedController, TypedRepository, TypedResourceConfig, UserBase, UserLike, UserOrganization, ValidateOptions, ValidationResult };
@@ -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-Dfzt4VTl.mjs";
1
+ import { a as StorageReadResult, i as StorageReadRange, n as StorageContext, o as StorageUploadInput, r as StorageFile, t as Storage } from "../storage-D2KZJAmn.mjs";
2
2
  export { Storage, StorageContext, StorageFile, StorageReadRange, StorageReadResult, StorageUploadInput };
@@ -47,6 +47,58 @@ function getOrgId(scope) {
47
47
  if (scope.kind === "elevated") return scope.organizationId;
48
48
  }
49
49
  /**
50
+ * Resolve the tenant (organization) id from an incoming Fastify request,
51
+ * walking the canonical sources in order: `request.scope` → `x-organization-id`
52
+ * header. Returns `{ organizationId, source }` so callers can log or branch
53
+ * on which path won.
54
+ *
55
+ * Use in custom handlers that bypass arc's auto-CRUD path (worker routes,
56
+ * batch importers, cross-engine subscribers) and therefore don't get the
57
+ * tenant injected by `BaseCrudController`. Bridges arc's HTTP shape to
58
+ * the mongokit/kit-side tenant context (e.g. `createTenantContext().run`).
59
+ *
60
+ * Header fallback is intentional: matches `resolveOrgFromHeader` semantics
61
+ * for hosts that select an org via header instead of session/scope. Don't
62
+ * reach for this when `getOrgId(scope)` alone is enough — for standard
63
+ * authenticated routes the scope is already authoritative.
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * import { getTenantFromRequest } from '@classytic/arc/scope';
68
+ * import { tenantContext } from './lib/mongokit.js';
69
+ *
70
+ * fastify.post('/statements/batch', async (req, reply) => {
71
+ * const { organizationId } = getTenantFromRequest(req);
72
+ * if (!organizationId) {
73
+ * return reply.code(400).send({ error: 'organizationId required' });
74
+ * }
75
+ * await tenantContext.run({ tenantId: organizationId }, async () => {
76
+ * await statementRepository.create(req.body);
77
+ * });
78
+ * });
79
+ * ```
80
+ */
81
+ function getTenantFromRequest(req, options = {}) {
82
+ if (req.scope) {
83
+ const id = getOrgId(req.scope);
84
+ if (id) return {
85
+ organizationId: id,
86
+ source: "scope"
87
+ };
88
+ }
89
+ const headerName = (options.header ?? "x-organization-id").toLowerCase();
90
+ const raw = req.headers[headerName];
91
+ const headerValue = Array.isArray(raw) ? raw[0] : raw;
92
+ if (typeof headerValue === "string" && headerValue.length > 0) return {
93
+ organizationId: headerValue,
94
+ source: "header"
95
+ };
96
+ return {
97
+ organizationId: void 0,
98
+ source: "none"
99
+ };
100
+ }
101
+ /**
50
102
  * Get stable client identity from a service scope.
51
103
  *
52
104
  * Returns the `clientId` for machine-to-machine auth (API keys, service accounts),
@@ -342,4 +394,4 @@ const PUBLIC_SCOPE = Object.freeze({ kind: "public" });
342
394
  /** Default authenticated scope — used when user is logged in but no org */
343
395
  const AUTHENTICATED_SCOPE = Object.freeze({ kind: "authenticated" });
344
396
  //#endregion
345
- export { requireClientId as C, requireUserId as E, isService as S, requireTeamId as T, hasOrgAccess as _, getDPoPJkt as a, isMember as b, getOrgId as c, getScopeContext as d, getScopeContextMap as f, getUserRoles as g, getUserId as h, getClientId as i, getOrgRoles as l, getTeamId as m, PUBLIC_SCOPE as n, getMandate as o, getServiceScopes as p, getAncestorOrgIds as r, getOrgContext as s, AUTHENTICATED_SCOPE as t, getRequestScope as u, isAuthenticated as v, requireOrgId as w, isOrgInScope as x, isElevated as y };
397
+ export { isService as C, requireUserId as D, requireTeamId as E, isOrgInScope as S, requireOrgId as T, getUserRoles as _, getDPoPJkt as a, isElevated as b, getOrgId as c, getScopeContext as d, getScopeContextMap as f, getUserId as g, getTenantFromRequest as h, getClientId as i, getOrgRoles as l, getTeamId as m, PUBLIC_SCOPE as n, getMandate as o, getServiceScopes as p, getAncestorOrgIds as r, getOrgContext as s, AUTHENTICATED_SCOPE as t, getRequestScope as u, hasOrgAccess as v, requireClientId as w, isMember as x, isAuthenticated as y };
@@ -1,4 +1,4 @@
1
- import { V as ResourceDefinition } from "./index-BswOSJCE.mjs";
1
+ import { V as ResourceDefinition } from "./index-CkW0flkU.mjs";
2
2
  import { z } from "zod";
3
3
 
4
4
  //#region src/integrations/mcp/types.d.ts
@@ -13,10 +13,30 @@ interface ToolAnnotations {
13
13
  /** Tool interacts with external systems beyond this server */
14
14
  openWorldHint?: boolean;
15
15
  }
16
- /** Context passed to tool handlers at invocation time */
17
- interface ToolContext {
18
- /** Session identity — null in no-auth mode */
19
- session: McpAuthResult | null;
16
+ /**
17
+ * Context passed to tool handlers at invocation time.
18
+ *
19
+ * The `TSession` parameter widens `session` to a host-specific shape — pass
20
+ * an interface that extends `McpAuthResult` (or omits it entirely for fully
21
+ * custom auth resolvers) to drop the `as any` casts at call sites:
22
+ *
23
+ * ```ts
24
+ * interface MySession extends McpAuthResult {
25
+ * userId: string; // required, not optional
26
+ * organizationId: string;
27
+ * tenantPlan: 'free' | 'pro';
28
+ * }
29
+ *
30
+ * defineTool<MySession>('upgrade', {
31
+ * handler: async (_input, ctx) => {
32
+ * ctx.session?.tenantPlan; // typed, no cast
33
+ * },
34
+ * });
35
+ * ```
36
+ */
37
+ interface ToolContext<TSession = McpAuthResult> {
38
+ /** Session identity — `null` in no-auth mode */
39
+ session: TSession | null;
20
40
  /** Log to MCP client (best-effort, non-blocking) */
21
41
  log: (level: "info" | "warning" | "error" | "debug", message: string) => Promise<void>;
22
42
  /** Raw MCP SDK extra context (for advanced use) */
@@ -59,8 +79,11 @@ interface CallToolResult {
59
79
  *
60
80
  * `inputSchema` is a flat Zod shape `{ name: z.string(), age: z.number() }` —
61
81
  * the SDK wraps it in z.object() internally. Do NOT pass z.object() here.
82
+ *
83
+ * The `TSession` parameter lets hosts widen the session shape on the
84
+ * handler — same generic the `defineTool()` builder accepts.
62
85
  */
63
- interface ToolDefinition {
86
+ interface ToolDefinition<TSession = McpAuthResult> {
64
87
  name: string;
65
88
  description: string;
66
89
  title?: string;
@@ -69,7 +92,7 @@ interface ToolDefinition {
69
92
  /** Flat Zod shape for structured output validation */
70
93
  outputSchema?: Record<string, z.ZodTypeAny>;
71
94
  annotations?: ToolAnnotations;
72
- handler: (input: Record<string, unknown>, ctx: ToolContext) => Promise<CallToolResult>;
95
+ handler: (input: Record<string, unknown>, ctx: ToolContext<TSession>) => Promise<CallToolResult>;
73
96
  }
74
97
  /** Output of definePrompt() — plain data, not yet registered */
75
98
  interface PromptDefinition {
@@ -93,12 +116,57 @@ interface PromptResult {
93
116
  };
94
117
  }>;
95
118
  }
119
+ /**
120
+ * Metadata threaded into a function-form description override so authors
121
+ * can produce a context-aware description without re-deriving filter /
122
+ * sort / operator lists from the resource definition by hand.
123
+ *
124
+ * Equivalent to the inputs `defaultCrudDescription()` consumes — the
125
+ * default description is also passed (`defaultDescription`) so authors
126
+ * can prepend or append to it without duplicating Arc's auto-derived
127
+ * filterable-fields blurb.
128
+ */
129
+ interface CrudDescriptionMeta {
130
+ readonly operation: CrudOperation;
131
+ /** Resource display name (e.g. `Posts`) — Arc derives this from `defineResource`. */
132
+ readonly displayName: string;
133
+ readonly softDelete: boolean;
134
+ /** Pre-rendered default description Arc would have used. */
135
+ readonly defaultDescription: string;
136
+ readonly filterableFields?: readonly string[];
137
+ readonly allowedOperators?: readonly string[];
138
+ readonly sortableFields?: readonly string[];
139
+ }
140
+ /**
141
+ * Override shape for a single CRUD tool description.
142
+ *
143
+ * - `string` — replace the default outright.
144
+ * - Function — receives the auto-rendered default plus the same metadata
145
+ * `defaultCrudDescription()` consumes, returns a final string. Use this
146
+ * to append context (`'Note: prefer isActive: true'`) without losing
147
+ * Arc's auto-derived filterable-fields blurb.
148
+ */
149
+ type CrudDescriptionOverride = string | ((meta: CrudDescriptionMeta) => string);
96
150
  /** Per-resource MCP configuration overrides */
97
151
  interface McpResourceConfig {
98
152
  /** Which CRUD operations to expose (default: all enabled on the resource) */
99
153
  operations?: CrudOperation[];
100
- /** Override tool descriptions per operation */
101
- descriptions?: Partial<Record<CrudOperation, string>>;
154
+ /**
155
+ * Override tool descriptions per operation.
156
+ *
157
+ * Each entry is either a plain replacement string OR a function
158
+ * `(meta) => string` that receives the auto-rendered default plus the
159
+ * filterable / sortable metadata Arc would have used. Use the function
160
+ * form to extend the default without losing the auto-derived blurb:
161
+ *
162
+ * ```ts
163
+ * descriptions: {
164
+ * list: ({ defaultDescription }) =>
165
+ * `${defaultDescription} Sort by createdAt desc for newest first.`,
166
+ * }
167
+ * ```
168
+ */
169
+ descriptions?: Partial<Record<CrudOperation, CrudDescriptionOverride>>;
102
170
  /** Fields to hide from MCP tool schemas (beyond schemaOptions.hiddenFields) */
103
171
  hideFields?: string[];
104
172
  /** Per-operation tool name overrides: `{ get: 'get_job_by_id' }` */
@@ -168,9 +236,35 @@ interface McpPluginOptions {
168
236
  serverVersion?: string;
169
237
  /** Instructions for the LLM — guidance on tool usage, constraints */
170
238
  instructions?: string;
171
- /** Resources to exclude by name (ignored if `include` is set) */
239
+ /**
240
+ * Resources to exclude by name (ignored if `expose`/`include` is set).
241
+ *
242
+ * Drift-prone for LLM-facing surfaces: a new `defineResource()` is exposed
243
+ * by default and you have to remember to add it here. Prefer `expose` when
244
+ * the principle of least authority matters.
245
+ */
172
246
  exclude?: string[];
173
- /** Resources to include by name — only these get MCP tools. Takes priority over `exclude`. */
247
+ /**
248
+ * Default-deny allowlist — only resources whose names appear here are
249
+ * surfaced to MCP. New `defineResource()` calls are auto-denied (the
250
+ * inverse of `exclude`), matching the principle-of-least-authority that
251
+ * LLM-driven tool surfaces want.
252
+ *
253
+ * Mutually exclusive with `include` (a deprecated alias) — passing both
254
+ * throws at registration. Mutually exclusive with `exclude`: the deny
255
+ * default would render the exclude list redundant; passing both throws
256
+ * with a hint to drop `exclude`.
257
+ *
258
+ * @example
259
+ * ```ts
260
+ * await app.register(mcpPlugin, { resources, expose: ['post'] });
261
+ * ```
262
+ */
263
+ expose?: string[];
264
+ /**
265
+ * @deprecated Use `expose` — same default-deny semantics with a clearer
266
+ * verb. Kept for backwards compatibility with pre-2.15.5 hosts.
267
+ */
174
268
  include?: string[];
175
269
  /** Tool name prefix: 'crm' → 'crm_list_products' */
176
270
  toolNamePrefix?: string;
@@ -288,4 +382,4 @@ interface CreateMcpServerConfig {
288
382
  /** CRUD operation type */
289
383
  type CrudOperation = "list" | "get" | "create" | "update" | "delete";
290
384
  //#endregion
291
- export { McpAuthResolver as a, McpResourceConfig as c, SessionEntry as d, ToolAnnotations as f, CrudOperation as i, PromptDefinition as l, ToolDefinition as m, CallToolResult as n, McpAuthResult as o, ToolContext as p, CreateMcpServerConfig as r, McpPluginOptions as s, BetterAuthHandler as t, PromptResult as u };
385
+ export { CrudDescriptionOverride as a, McpAuthResult as c, PromptDefinition as d, PromptResult as f, ToolDefinition as g, ToolContext as h, CrudDescriptionMeta as i, McpPluginOptions as l, ToolAnnotations as m, CallToolResult as n, CrudOperation as o, SessionEntry as p, CreateMcpServerConfig as r, McpAuthResolver as s, BetterAuthHandler as t, McpResourceConfig as u };
@@ -1,13 +1,13 @@
1
- import { r as CacheStore } from "./interface-beEtJyWM.mjs";
2
- import { Bt as Authenticator } from "./index-BswOSJCE.mjs";
3
- import { n as ElevationOptions } from "./elevation-BXOWoGCF.mjs";
4
- import { a as EventTransport } from "./EventTransport-CT_52aWU.mjs";
5
- import { t as ExternalOpenApiPaths } from "./externalPaths-BD5nw6St.mjs";
6
- import { r as QueryCachePluginOptions } from "./queryCachePlugin-CqMdLI2-.mjs";
7
- import { t as EventPluginOptions } from "./eventPlugin-qXpqTebY.mjs";
8
- import { _ as HealthOptions, f as CachingOptions, l as SSEOptions, o as MetricsOptions, t as VersioningOptions } from "./versioning-hmkPcDlX.mjs";
9
- import { t as ErrorHandlerOptions } from "./errorHandler-DFr45ZG4.mjs";
10
- import { r as IdempotencyStore } from "./interface-DfLGcus7.mjs";
1
+ import { r as CacheStore } from "./interface-CH0OQudo.mjs";
2
+ import { Ht as Authenticator } from "./index-CkW0flkU.mjs";
3
+ import { n as ElevationOptions } from "./elevation-0YBpa663.mjs";
4
+ import { a as EventTransport } from "./EventTransport-C-2oAHtw.mjs";
5
+ import { t as ExternalOpenApiPaths } from "./externalPaths-DFg-2KTp.mjs";
6
+ import { r as QueryCachePluginOptions } from "./queryCachePlugin-Biqzfbi5.mjs";
7
+ import { t as EventPluginOptions } from "./eventPlugin-CtHC_av1.mjs";
8
+ import { _ as HealthOptions, f as CachingOptions, l as SSEOptions, o as MetricsOptions, t as VersioningOptions } from "./versioning-ZwX9tmbS.mjs";
9
+ import { t as ErrorHandlerOptions } from "./errorHandler-mHuyWzZE.mjs";
10
+ import { r as IdempotencyStore } from "./interface-NwJ_qPlY.mjs";
11
11
  import { FastifyInstance, FastifyPluginAsync, FastifyReply, FastifyRequest, FastifyServerOptions } from "fastify";
12
12
 
13
13
  //#region src/factory/loadResources.d.ts
@@ -498,6 +498,29 @@ interface CreateAppOptions {
498
498
  * separately by `multipart.limits.fileSize`. (2.15.1)
499
499
  */
500
500
  bodyLimit?: number;
501
+ /**
502
+ * Maximum length of a single URL path parameter (in characters).
503
+ *
504
+ * 2.16 — Fastify's default is `100`, which silently 404s modern signed-
505
+ * token URLs: HMAC tracking tokens (~250 chars), JWT-in-URL, OAuth state
506
+ * parameters, password-reset / magic-link tokens, etc. Arc's default
507
+ * is **400** to match the everything-is-a-signed-token reality of
508
+ * production apps; hosts that need longer params can raise it further
509
+ * (`1024` for very long JWTs).
510
+ *
511
+ * Pass-through to Fastify's `maxParamLength` constructor option — see
512
+ * https://fastify.dev/docs/latest/Reference/Server/#maxparamlength.
513
+ *
514
+ * @example
515
+ * ```ts
516
+ * // App expects long HMAC tokens in the URL path
517
+ * createApp({ preset: 'production', maxParamLength: 1024 });
518
+ *
519
+ * // Constrain tighter than arc's default for audit reasons
520
+ * createApp({ preset: 'production', maxParamLength: 256 });
521
+ * ```
522
+ */
523
+ maxParamLength?: number;
501
524
  /**
502
525
  * Auth configuration
503
526
  *
@@ -229,6 +229,47 @@ declare function hasOrgAccess(scope: RequestScope): boolean;
229
229
  declare function isAuthenticated(scope: RequestScope): boolean;
230
230
  /** Get organizationId from scope (member, service, or elevated — undefined otherwise) */
231
231
  declare function getOrgId(scope: RequestScope): string | undefined;
232
+ /**
233
+ * Resolve the tenant (organization) id from an incoming Fastify request,
234
+ * walking the canonical sources in order: `request.scope` → `x-organization-id`
235
+ * header. Returns `{ organizationId, source }` so callers can log or branch
236
+ * on which path won.
237
+ *
238
+ * Use in custom handlers that bypass arc's auto-CRUD path (worker routes,
239
+ * batch importers, cross-engine subscribers) and therefore don't get the
240
+ * tenant injected by `BaseCrudController`. Bridges arc's HTTP shape to
241
+ * the mongokit/kit-side tenant context (e.g. `createTenantContext().run`).
242
+ *
243
+ * Header fallback is intentional: matches `resolveOrgFromHeader` semantics
244
+ * for hosts that select an org via header instead of session/scope. Don't
245
+ * reach for this when `getOrgId(scope)` alone is enough — for standard
246
+ * authenticated routes the scope is already authoritative.
247
+ *
248
+ * @example
249
+ * ```typescript
250
+ * import { getTenantFromRequest } from '@classytic/arc/scope';
251
+ * import { tenantContext } from './lib/mongokit.js';
252
+ *
253
+ * fastify.post('/statements/batch', async (req, reply) => {
254
+ * const { organizationId } = getTenantFromRequest(req);
255
+ * if (!organizationId) {
256
+ * return reply.code(400).send({ error: 'organizationId required' });
257
+ * }
258
+ * await tenantContext.run({ tenantId: organizationId }, async () => {
259
+ * await statementRepository.create(req.body);
260
+ * });
261
+ * });
262
+ * ```
263
+ */
264
+ declare function getTenantFromRequest(req: {
265
+ scope?: RequestScope;
266
+ headers: Record<string, string | string[] | undefined>;
267
+ }, options?: {
268
+ header?: string;
269
+ }): {
270
+ organizationId: string | undefined;
271
+ source: "scope" | "header" | "none";
272
+ };
232
273
  /**
233
274
  * Get stable client identity from a service scope.
234
275
  *
@@ -477,4 +518,4 @@ declare const PUBLIC_SCOPE: Readonly<RequestScope>;
477
518
  /** Default authenticated scope — used when user is logged in but no org */
478
519
  declare const AUTHENTICATED_SCOPE: Readonly<RequestScope>;
479
520
  //#endregion
480
- export { isOrgInScope as C, requireTeamId as D, requireOrgId as E, requireUserId as O, isMember as S, requireClientId as T, getUserId as _, getAncestorOrgIds as a, isAuthenticated as b, getMandate as c, getOrgRoles as d, getRequestScope as f, getTeamId as g, getServiceScopes as h, RequestScope as i, getOrgContext as l, getScopeContextMap as m, Mandate as n, getClientId as o, getScopeContext as p, PUBLIC_SCOPE as r, getDPoPJkt as s, AUTHENTICATED_SCOPE as t, getOrgId as u, getUserRoles as v, isService as w, isElevated as x, hasOrgAccess as y };
521
+ export { isMember as C, requireOrgId as D, requireClientId as E, requireTeamId as O, isElevated as S, isService as T, getTenantFromRequest as _, getAncestorOrgIds as a, hasOrgAccess as b, getMandate as c, getOrgRoles as d, getRequestScope as f, getTeamId as g, getServiceScopes as h, RequestScope as i, requireUserId as k, getOrgContext as l, getScopeContextMap as m, Mandate as n, getClientId as o, getScopeContext as p, PUBLIC_SCOPE as r, getDPoPJkt as s, AUTHENTICATED_SCOPE as t, getOrgId as u, getUserId as v, isOrgInScope as w, isAuthenticated as x, getUserRoles as y };