@classytic/arc 2.11.0 → 2.11.2

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 (40) hide show
  1. package/README.md +146 -670
  2. package/dist/adapters/index.d.mts +2 -2
  3. package/dist/audit/index.d.mts +1 -1
  4. package/dist/auth/index.d.mts +1 -1
  5. package/dist/core/index.d.mts +2 -2
  6. package/dist/{createApp-DvNYEhpb.mjs → createApp-P1d6rjPy.mjs} +1 -1
  7. package/dist/docs/index.d.mts +1 -1
  8. package/dist/events/index.d.mts +1 -1
  9. package/dist/factory/index.d.mts +2 -2
  10. package/dist/factory/index.mjs +2 -2
  11. package/dist/hooks/index.d.mts +1 -1
  12. package/dist/idempotency/index.d.mts +1 -1
  13. package/dist/{index-Cm0vUrr_.d.mts → index-6u4_Gg6G.d.mts} +49 -8
  14. package/dist/{index-DAushRTt.d.mts → index-BbMrcvGp.d.mts} +1 -1
  15. package/dist/{index-t8pLpPFW.d.mts → index-BdXnTPRj.d.mts} +1 -1
  16. package/dist/{index-DsJ1MNfC.d.mts → index-DdQ3O9Pg.d.mts} +1 -1
  17. package/dist/index.d.mts +4 -4
  18. package/dist/index.mjs +1 -1
  19. package/dist/integrations/index.d.mts +1 -1
  20. package/dist/integrations/mcp/index.d.mts +2 -2
  21. package/dist/integrations/mcp/testing.d.mts +1 -1
  22. package/dist/{loadResources-YNwKHvRA.mjs → loadResources-CPpkyKfM.mjs} +29 -7
  23. package/dist/middleware/index.d.mts +1 -1
  24. package/dist/org/index.d.mts +1 -1
  25. package/dist/pipeline/index.d.mts +1 -1
  26. package/dist/plugins/index.d.mts +1 -1
  27. package/dist/plugins/tracing-entry.mjs +1 -1
  28. package/dist/presets/filesUpload.d.mts +1 -1
  29. package/dist/presets/index.d.mts +1 -1
  30. package/dist/presets/multiTenant.d.mts +1 -1
  31. package/dist/presets/search.d.mts +1 -1
  32. package/dist/registry/index.d.mts +1 -1
  33. package/dist/testing/index.d.mts +2 -2
  34. package/dist/testing/index.mjs +1 -1
  35. package/dist/types/index.d.mts +1 -1
  36. package/dist/{types-D9NqiYIw.d.mts → types-9beEMe25.d.mts} +1 -1
  37. package/dist/{types-CgikqKAj.d.mts → types-BH7dEGvU.d.mts} +74 -10
  38. package/dist/utils/index.d.mts +1 -1
  39. package/package.json +3 -1
  40. package/skills/arc/SKILL.md +3 -3
@@ -1,3 +1,3 @@
1
- import { An as RelationMetadata, En as AdapterFactory, Mn as SchemaMetadata, Nn as ValidationResult, On as DataAdapter, jn as RepositoryLike, kn as FieldMetadata } from "../index-Cm0vUrr_.mjs";
2
- import { a as PrismaQueryParserOptions, c as MongooseAdapterOptions, d as DrizzleAdapterOptions, f as createDrizzleAdapter, i as PrismaQueryParser, l as createMongooseAdapter, n as PrismaAdapterOptions, o as createPrismaAdapter, r as PrismaQueryOptions, s as MongooseAdapter, t as PrismaAdapter, u as DrizzleAdapter } from "../index-DAushRTt.mjs";
1
+ import { An as RelationMetadata, En as AdapterFactory, Mn as SchemaMetadata, Nn as ValidationResult, On as DataAdapter, jn as RepositoryLike, kn as FieldMetadata } from "../index-6u4_Gg6G.mjs";
2
+ import { a as PrismaQueryParserOptions, c as MongooseAdapterOptions, d as DrizzleAdapterOptions, f as createDrizzleAdapter, i as PrismaQueryParser, l as createMongooseAdapter, n as PrismaAdapterOptions, o as createPrismaAdapter, r as PrismaQueryOptions, s as MongooseAdapter, t as PrismaAdapter, u as DrizzleAdapter } from "../index-BbMrcvGp.mjs";
3
3
  export { AdapterFactory, DataAdapter, DrizzleAdapter, DrizzleAdapterOptions, FieldMetadata, MongooseAdapter, MongooseAdapterOptions, PrismaAdapter, PrismaAdapterOptions, PrismaQueryOptions, PrismaQueryParser, PrismaQueryParserOptions, RelationMetadata, RepositoryLike, SchemaMetadata, ValidationResult, createDrizzleAdapter, createMongooseAdapter, createPrismaAdapter };
@@ -1,4 +1,4 @@
1
- import { jn as RepositoryLike } from "../index-Cm0vUrr_.mjs";
1
+ import { jn as RepositoryLike } from "../index-6u4_Gg6G.mjs";
2
2
  import { d as UserBase } from "../fields-C8Y0XLAu.mjs";
3
3
  import { FastifyPluginAsync } from "fastify";
4
4
 
@@ -1,4 +1,4 @@
1
- import { Ot as AuthHelpers, kt as AuthPluginOptions } from "../index-Cm0vUrr_.mjs";
1
+ import { Ot as AuthHelpers, kt as AuthPluginOptions } from "../index-6u4_Gg6G.mjs";
2
2
  import { c as PermissionCheck } from "../fields-C8Y0XLAu.mjs";
3
3
  import { t as ExternalOpenApiPaths } from "../externalPaths-Bapitwvd.mjs";
4
4
  import { a as SessionManagerOptions, c as createSessionManager, i as SessionData, n as MemorySessionStoreOptions, o as SessionManagerResult, r as SessionCookieOptions, s as SessionStore, t as MemorySessionStore } from "../sessionManager-D-oNWHz3.mjs";
@@ -1,3 +1,3 @@
1
- import { B as ResourceDefinition, Gt as TreeMixin, Ht as SoftDeleteExt, Jt as BulkExt, Kt as SlugExt, Ut as SoftDeleteMixin, V as defineResource, Vt as BaseController, Wt as TreeExt, Yt as BulkMixin, an as QueryResolverConfig, cn as AccessControl, in as QueryResolver, ln as AccessControlConfig, nn as BaseCrudController, on as BodySanitizer, qt as SlugMixin, rn as ListResult, sn as BodySanitizerConfig, tn as BaseControllerOptions } from "../index-Cm0vUrr_.mjs";
2
- import { C as MAX_REGEX_LENGTH, D as RESERVED_QUERY_PARAMS, E as MutationOperation, O as SYSTEM_FIELDS, S as MAX_FILTER_DEPTH, T as MUTATION_OPERATIONS, _ as DEFAULT_UPDATE_METHOD, a as getControllerScope, b as HookOperation, c as createCrudRouter, d as CrudOperation, f as DEFAULT_ID_FIELD, g as DEFAULT_TENANT_FIELD, h as DEFAULT_SORT, i as getControllerContext, l as createPermissionMiddleware, m as DEFAULT_MAX_LIMIT, n as createFastifyHandler, o as sendControllerResponse, p as DEFAULT_LIMIT, r as createRequestContext, s as defineResourceVariants, t as createCrudHandlers, u as CRUD_OPERATIONS, v as HOOK_OPERATIONS, w as MAX_SEARCH_LENGTH, x as HookPhase, y as HOOK_PHASES } from "../index-t8pLpPFW.mjs";
1
+ import { B as ResourceDefinition, Gt as TreeMixin, Ht as SoftDeleteExt, Jt as BulkExt, Kt as SlugExt, Ut as SoftDeleteMixin, V as defineResource, Vt as BaseController, Wt as TreeExt, Yt as BulkMixin, an as QueryResolverConfig, cn as AccessControl, in as QueryResolver, ln as AccessControlConfig, nn as BaseCrudController, on as BodySanitizer, qt as SlugMixin, rn as ListResult, sn as BodySanitizerConfig, tn as BaseControllerOptions } from "../index-6u4_Gg6G.mjs";
2
+ import { C as MAX_REGEX_LENGTH, D as RESERVED_QUERY_PARAMS, E as MutationOperation, O as SYSTEM_FIELDS, S as MAX_FILTER_DEPTH, T as MUTATION_OPERATIONS, _ as DEFAULT_UPDATE_METHOD, a as getControllerScope, b as HookOperation, c as createCrudRouter, d as CrudOperation, f as DEFAULT_ID_FIELD, g as DEFAULT_TENANT_FIELD, h as DEFAULT_SORT, i as getControllerContext, l as createPermissionMiddleware, m as DEFAULT_MAX_LIMIT, n as createFastifyHandler, o as sendControllerResponse, p as DEFAULT_LIMIT, r as createRequestContext, s as defineResourceVariants, t as createCrudHandlers, u as CRUD_OPERATIONS, v as HOOK_OPERATIONS, w as MAX_SEARCH_LENGTH, x as HookPhase, y as HOOK_PHASES } from "../index-BdXnTPRj.mjs";
3
3
  export { AccessControl, AccessControlConfig, BaseController, BaseControllerOptions, BaseCrudController, BodySanitizer, BodySanitizerConfig, BulkExt, BulkMixin, CRUD_OPERATIONS, CrudOperation, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, HOOK_OPERATIONS, HOOK_PHASES, HookOperation, HookPhase, ListResult, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, MutationOperation, QueryResolver, QueryResolverConfig, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, SlugExt, SlugMixin, SoftDeleteExt, SoftDeleteMixin, TreeExt, TreeMixin, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineResource, defineResourceVariants, getControllerContext, getControllerScope, sendControllerResponse };
@@ -448,7 +448,7 @@ async function registerResources(fastify, config) {
448
448
  let discoveryPath;
449
449
  let discoveryYieldedZero = false;
450
450
  if (resolvedResources === void 0 && config.resourceDir) {
451
- const { loadResources } = await import("./loadResources-YNwKHvRA.mjs").then((n) => n.n);
451
+ const { loadResources } = await import("./loadResources-CPpkyKfM.mjs").then((n) => n.n);
452
452
  const { resolve, dirname } = await import("node:path");
453
453
  const { fileURLToPath } = await import("node:url");
454
454
  const rawDir = config.resourceDir;
@@ -1,4 +1,4 @@
1
- import { p as RegistryEntry } from "../index-Cm0vUrr_.mjs";
1
+ import { p as RegistryEntry } from "../index-6u4_Gg6G.mjs";
2
2
  import { t as ExternalOpenApiPaths } from "../externalPaths-Bapitwvd.mjs";
3
3
  import { FastifyPluginAsync } from "fastify";
4
4
 
@@ -1,4 +1,4 @@
1
- import { jn as RepositoryLike } from "../index-Cm0vUrr_.mjs";
1
+ import { jn as RepositoryLike } from "../index-6u4_Gg6G.mjs";
2
2
  import { a as EventMeta, c as MemoryEventTransportOptions, d as createEvent, i as EventLogger, l as PublishManyResult, n as DomainEvent, o as EventTransport, r as EventHandler, s as MemoryEventTransport, t as DeadLetteredEvent, u as createChildEvent } from "../EventTransport-CfVEGaEl.mjs";
3
3
  import { a as withRetry, c as EventDefinitionOutput, d as EventSchema, f as ValidationResult, i as createDeadLetterPublisher, l as EventRegistry, m as defineEvent, n as eventPlugin, o as CustomValidator, p as createEventRegistry, r as RetryOptions, s as EventDefinitionInput, t as EventPluginOptions, u as EventRegistryOptions } from "../eventPlugin-CUNjYYRY.mjs";
4
4
  import { RedisEventTransportOptions, RedisLike } from "./transports/redis.mjs";
@@ -1,4 +1,4 @@
1
- import { a as CustomPluginAuthOption, c as RawBodyOptions, d as ResourceLike, f as loadResources, i as CustomAuthenticatorOption, l as UnderPressureOptions, n as BetterAuthOption, o as JwtAuthOption, r as CreateAppOptions, s as MultipartOptions, t as AuthOption, u as LoadResourcesOptions } from "../types-CgikqKAj.mjs";
1
+ import { a as CustomPluginAuthOption, c as RawBodyOptions, d as ResourceLike, f as ResourceModule, i as CustomAuthenticatorOption, l as UnderPressureOptions, n as BetterAuthOption, o as JwtAuthOption, p as loadResources, r as CreateAppOptions, s as MultipartOptions, t as AuthOption, u as LoadResourcesOptions } from "../types-BH7dEGvU.mjs";
2
2
  import { FastifyInstance } from "fastify";
3
3
 
4
4
  //#region src/factory/createApp.d.ts
@@ -95,4 +95,4 @@ declare const edgePreset: Partial<CreateAppOptions>;
95
95
  */
96
96
  declare function getPreset(name: "production" | "development" | "testing" | "edge"): Partial<CreateAppOptions>;
97
97
  //#endregion
98
- export { ArcFactory, type AuthOption, type BetterAuthOption, type CreateAppOptions, type CustomAuthenticatorOption, type CustomPluginAuthOption, type FetchHandlerOptions, type JwtAuthOption, type LoadResourcesOptions, type MultipartOptions, type RawBodyOptions, type ResourceLike, type UnderPressureOptions, createApp, developmentPreset, edgePreset, getPreset, loadResources, productionPreset, testingPreset, toFetchHandler };
98
+ export { ArcFactory, type AuthOption, type BetterAuthOption, type CreateAppOptions, type CustomAuthenticatorOption, type CustomPluginAuthOption, type FetchHandlerOptions, type JwtAuthOption, type LoadResourcesOptions, type MultipartOptions, type RawBodyOptions, type ResourceLike, type ResourceModule, type UnderPressureOptions, createApp, developmentPreset, edgePreset, getPreset, loadResources, productionPreset, testingPreset, toFetchHandler };
@@ -1,5 +1,5 @@
1
- import { a as edgePreset, c as testingPreset, i as developmentPreset, n as createApp, o as getPreset, s as productionPreset, t as ArcFactory } from "../createApp-DvNYEhpb.mjs";
2
- import { t as loadResources } from "../loadResources-YNwKHvRA.mjs";
1
+ import { a as edgePreset, c as testingPreset, i as developmentPreset, n as createApp, o as getPreset, s as productionPreset, t as ArcFactory } from "../createApp-P1d6rjPy.mjs";
2
+ import { t as loadResources } from "../loadResources-CPpkyKfM.mjs";
3
3
  //#region src/factory/edge.ts
4
4
  /**
5
5
  * Convert a Fastify app into a Web Standards fetch handler.
@@ -1,2 +1,2 @@
1
- import { Cn as beforeUpdate, Sn as beforeDelete, Tn as defineHook, _n as HookSystemOptions, bn as afterUpdate, dn as HookContext, fn as HookHandler, gn as HookSystem, hn as HookRegistration, mn as HookPhase, pn as HookOperation, un as DefineHookOptions, vn as afterCreate, wn as createHookSystem, xn as beforeCreate, yn as afterDelete } from "../index-Cm0vUrr_.mjs";
1
+ import { Cn as beforeUpdate, Sn as beforeDelete, Tn as defineHook, _n as HookSystemOptions, bn as afterUpdate, dn as HookContext, fn as HookHandler, gn as HookSystem, hn as HookRegistration, mn as HookPhase, pn as HookOperation, un as DefineHookOptions, vn as afterCreate, wn as createHookSystem, xn as beforeCreate, yn as afterDelete } from "../index-6u4_Gg6G.mjs";
2
2
  export { type DefineHookOptions, type HookContext, type HookHandler, type HookOperation, type HookPhase, type HookRegistration, HookSystem, type HookSystemOptions, afterCreate, afterDelete, afterUpdate, beforeCreate, beforeDelete, beforeUpdate, createHookSystem, defineHook };
@@ -1,4 +1,4 @@
1
- import { jn as RepositoryLike } from "../index-Cm0vUrr_.mjs";
1
+ import { jn as RepositoryLike } from "../index-6u4_Gg6G.mjs";
2
2
  import { i as createIdempotencyResult, n as IdempotencyResult, r as IdempotencyStore, t as IdempotencyLock } from "../interface-CkkWm5uR.mjs";
3
3
  import { i as RedisIdempotencyStoreOptions, n as RedisClient } from "../redis-Cm1gnRDf.mjs";
4
4
  import { FastifyPluginAsync } from "fastify";
@@ -1776,6 +1776,40 @@ interface RouteSchemaOptions extends SchemaBuilderOptions {
1776
1776
  * post-kit by `mergeFieldRuleConstraints`.
1777
1777
  */
1778
1778
  fieldRules?: Record<string, ArcFieldRule>;
1779
+ /**
1780
+ * Query-time security whitelists + the kit's `filterableFields`.
1781
+ *
1782
+ * Extends repo-core's `SchemaBuilderOptions['query']` with arc-specific
1783
+ * runtime features that `QueryResolver` reads at request time:
1784
+ *
1785
+ * - **`allowedPopulate`** — populate-path whitelist consumed by
1786
+ * `QueryResolver.sanitizePopulate` / `sanitizeAdvancedPopulate`.
1787
+ * When set, only paths in the list pass through; everything else is
1788
+ * stripped silently. Shrinks the auto-wired `?populate=` attack surface.
1789
+ *
1790
+ * - **`allowedLookups`** — lookup-collection whitelist consumed by
1791
+ * `QueryResolver.sanitizeLookups`. When set, only the listed
1792
+ * collections may be `$lookup`'d into the pipeline.
1793
+ *
1794
+ * Both are pre-2.11.2 runtime features — the type was missing them, so
1795
+ * hosts wrote `as Record<string, unknown>` at every call site. Arc's own
1796
+ * `QueryResolver` had to cast its own input via `as AnyRecord` for the
1797
+ * same reason. Adding the type dropped both casts.
1798
+ */
1799
+ query?: SchemaBuilderOptions["query"] & {
1800
+ /**
1801
+ * Populate-path whitelist. When set, `QueryResolver.sanitizePopulate`
1802
+ * strips any `?populate=<path>` not in this list. Omit to allow all
1803
+ * paths the kit recognizes.
1804
+ */
1805
+ allowedPopulate?: string[];
1806
+ /**
1807
+ * Lookup-collection whitelist for `QueryResolver.sanitizeLookups`.
1808
+ * When set, only the listed collections may be `$lookup`'d. Omit to
1809
+ * disable the whitelist (kit-level rules still apply).
1810
+ */
1811
+ allowedLookups?: string[];
1812
+ };
1779
1813
  }
1780
1814
  interface FieldRule$1 {
1781
1815
  field: string;
@@ -1942,10 +1976,13 @@ interface ActionDefinition {
1942
1976
  readonly permissions?: PermissionCheck;
1943
1977
  /**
1944
1978
  * JSON Schema or Zod v4 schema for action-specific body fields.
1945
- * Per-field values are typed `unknown` so Zod class instances assign
1946
- * without casts.
1979
+ *
1980
+ * Typed `unknown` (not `Record<string, unknown>`) so Zod class instances
1981
+ * — `ZodObject<...>` carries no string index signature — assign without
1982
+ * a cast. Same convention as `RouteDefinition.schema.body` / `customSchemas`.
1983
+ * Runtime feature-detects via `convertRouteSchema` / `toJsonSchema`.
1947
1984
  */
1948
- readonly schema?: Record<string, unknown>;
1985
+ readonly schema?: unknown;
1949
1986
  /** Description for OpenAPI docs and MCP tool */
1950
1987
  readonly description?: string;
1951
1988
  /**
@@ -2060,8 +2097,12 @@ interface EventDefinition {
2060
2097
  name: string;
2061
2098
  /** Optional handler — events are published via `fastify.events.publish()`. */
2062
2099
  handler?: (data: unknown) => Promise<void> | void;
2063
- /** JSON schema for event payload */
2064
- schema?: Record<string, unknown>;
2100
+ /**
2101
+ * JSON Schema or Zod v4 schema for event payload. Typed `unknown` so Zod
2102
+ * class instances assign without a cast (same convention as
2103
+ * `ActionDefinition.schema` and `RouteDefinition.schema`).
2104
+ */
2105
+ schema?: unknown;
2065
2106
  description?: string;
2066
2107
  }
2067
2108
  /** Resource-level permissions — only `PermissionCheck` functions allowed. */
@@ -2361,7 +2402,7 @@ declare class ResourceDefinition<TDoc = AnyRecord> {
2361
2402
  getEvents(): Array<{
2362
2403
  name: string;
2363
2404
  module: string;
2364
- schema?: AnyRecord;
2405
+ schema?: unknown;
2365
2406
  description?: string;
2366
2407
  }>;
2367
2408
  /**
@@ -2762,7 +2803,7 @@ interface ResourceMetadata {
2762
2803
  description?: string;
2763
2804
  permissions?: PermissionCheck;
2764
2805
  raw?: boolean;
2765
- schema?: Record<string, unknown>;
2806
+ schema?: unknown;
2766
2807
  }>;
2767
2808
  routes: Array<{
2768
2809
  method: string;
@@ -2814,7 +2855,7 @@ interface RegistryEntry extends ResourceMetadata {
2814
2855
  actions?: Array<{
2815
2856
  readonly name: string;
2816
2857
  readonly description?: string; /** Raw per-action schema (JSON Schema, Zod v4, or legacy field map) */
2817
- readonly schema?: Record<string, unknown>; /** Per-action permission check (if different from resource-level `actionPermissions`) */
2858
+ readonly schema?: unknown; /** Per-action permission check (if different from resource-level `actionPermissions`) */
2818
2859
  readonly permissions?: PermissionCheck; /** MCP tool generation flag — `false` to skip, object for overrides */
2819
2860
  readonly mcp?: boolean | {
2820
2861
  readonly description?: string;
@@ -1,4 +1,4 @@
1
- import { $ as OpenApiSchemas, Dn as AdapterSchemaContext, Mn as SchemaMetadata, Nn as ValidationResult, On as DataAdapter, S as QueryParserInterface, b as ParsedQuery, ft as RouteSchemaOptions, jn as RepositoryLike } from "./index-Cm0vUrr_.mjs";
1
+ import { $ as OpenApiSchemas, Dn as AdapterSchemaContext, Mn as SchemaMetadata, Nn as ValidationResult, On as DataAdapter, S as QueryParserInterface, b as ParsedQuery, ft as RouteSchemaOptions, jn as RepositoryLike } from "./index-6u4_Gg6G.mjs";
2
2
  import { StandardRepo } from "@classytic/repo-core/repository";
3
3
  import { Model } from "mongoose";
4
4
 
@@ -1,4 +1,4 @@
1
- import { B as ResourceDefinition, C as RequestContext, F as FastifyWithDecorators, Pt as AnyRecord, T as CrudRouterOptions, _t as IControllerResponse, at as ResourceConfig, gt as IController, q as CrudController, vt as IRequestContext } from "./index-Cm0vUrr_.mjs";
1
+ import { B as ResourceDefinition, C as RequestContext, F as FastifyWithDecorators, Pt as AnyRecord, T as CrudRouterOptions, _t as IControllerResponse, at as ResourceConfig, gt as IController, q as CrudController, vt as IRequestContext } from "./index-6u4_Gg6G.mjs";
2
2
  import { r as RequestScope } from "./types-tgR4Pt8F.mjs";
3
3
  import { c as PermissionCheck } from "./fields-C8Y0XLAu.mjs";
4
4
  import { FastifyReply, FastifyRequest, RouteHandlerMethod } from "fastify";
@@ -1,4 +1,4 @@
1
- import { $ as OpenApiSchemas, Pt as AnyRecord, S as QueryParserInterface, at as ResourceConfig, b as ParsedQuery, zt as UserLike } from "./index-Cm0vUrr_.mjs";
1
+ import { $ as OpenApiSchemas, Pt as AnyRecord, S as QueryParserInterface, at as ResourceConfig, b as ParsedQuery, zt as UserLike } from "./index-6u4_Gg6G.mjs";
2
2
  import { n as ErrorMapper } from "./errorHandler-Co3lnVmJ.mjs";
3
3
  import { FastifyInstance, FastifyReply, FastifyRequest, RouteHandlerMethod } from "fastify";
4
4
 
package/dist/index.d.mts CHANGED
@@ -1,9 +1,9 @@
1
- import { $t as ArcListResult, A as RequestIdOptions, An as RelationMetadata, B as ResourceDefinition, Bt as UserOrganization, C as RequestContext, D as HealthCheck, E as GracefulShutdownOptions, F as FastifyWithDecorators, Ft as ApiResponse, Gt as TreeMixin, Ht as SoftDeleteExt, It as ArcRequest, J as CrudRouteKey, Jt as BulkExt, Kt as SlugExt, L as RequestWithExtras, Lt as JWTPayload, Mn as SchemaMetadata, N as FastifyRequestExtras, Nn as ValidationResult, O as HealthOptions, On as DataAdapter, P as FastifyWithAuth, Pt as AnyRecord, Q as MiddlewareConfig, Qt as ArcGetResult, S as QueryParserInterface, T as CrudRouterOptions, Ut as SoftDeleteMixin, V as defineResource, Vt as BaseController, Wt as TreeExt, X as EventDefinition, Xt as ArcCreateResult, Y as CrudSchemas, Yt as BulkMixin, Z as FieldRule, Zt as ArcDeleteResult, _t as IControllerResponse, a as InferAdapterDoc, at as ResourceConfig, c as TypedController, d as PaginationResult, en as ArcUpdateResult, et as PresetFunction, f as IntrospectionData, ft as RouteSchemaOptions, g as ArcInternalMetadata, gt as IController, h as ResourceMetadata, i as ValidationResult$1, jn as RepositoryLike, k as IntrospectionPluginOptions, kn as FieldMetadata, kt as AuthPluginOptions, l as TypedRepository, m as RegistryStats, mt as ControllerLike, n as ConfigError, nn as BaseCrudController, nt as PresetResult, o as InferDocType, p as RegistryEntry, q as CrudController, qt as SlugMixin, r as ValidateOptions, rn as ListResult, rt as RateLimitConfig, s as InferResourceDoc, t as RouteHandlerMethod, tn as BaseControllerOptions, u as TypedResourceConfig, vt as IRequestContext, w as ServiceContext, y as OwnershipCheck, yt as RouteHandler } from "./index-Cm0vUrr_.mjs";
1
+ import { $t as ArcListResult, A as RequestIdOptions, An as RelationMetadata, B as ResourceDefinition, Bt as UserOrganization, C as RequestContext, D as HealthCheck, E as GracefulShutdownOptions, F as FastifyWithDecorators, Ft as ApiResponse, Gt as TreeMixin, Ht as SoftDeleteExt, It as ArcRequest, J as CrudRouteKey, Jt as BulkExt, Kt as SlugExt, L as RequestWithExtras, Lt as JWTPayload, Mn as SchemaMetadata, N as FastifyRequestExtras, Nn as ValidationResult, O as HealthOptions, On as DataAdapter, P as FastifyWithAuth, Pt as AnyRecord, Q as MiddlewareConfig, Qt as ArcGetResult, S as QueryParserInterface, T as CrudRouterOptions, Ut as SoftDeleteMixin, V as defineResource, Vt as BaseController, Wt as TreeExt, X as EventDefinition, Xt as ArcCreateResult, Y as CrudSchemas, Yt as BulkMixin, Z as FieldRule, Zt as ArcDeleteResult, _t as IControllerResponse, a as InferAdapterDoc, at as ResourceConfig, c as TypedController, d as PaginationResult, en as ArcUpdateResult, et as PresetFunction, f as IntrospectionData, ft as RouteSchemaOptions, g as ArcInternalMetadata, gt as IController, h as ResourceMetadata, i as ValidationResult$1, jn as RepositoryLike, k as IntrospectionPluginOptions, kn as FieldMetadata, kt as AuthPluginOptions, l as TypedRepository, m as RegistryStats, mt as ControllerLike, n as ConfigError, nn as BaseCrudController, nt as PresetResult, o as InferDocType, p as RegistryEntry, q as CrudController, qt as SlugMixin, r as ValidateOptions, rn as ListResult, rt as RateLimitConfig, s as InferResourceDoc, t as RouteHandlerMethod, tn as BaseControllerOptions, u as TypedResourceConfig, vt as IRequestContext, w as ServiceContext, y as OwnershipCheck, yt as RouteHandler } from "./index-6u4_Gg6G.mjs";
2
2
  import { a as applyFieldWritePermissions, c as PermissionCheck, d as UserBase, i as applyFieldReadPermissions, l as PermissionContext, n as FieldPermissionMap, o as fields, t as FieldPermission, u as PermissionResult } from "./fields-C8Y0XLAu.mjs";
3
- import { l as createMongooseAdapter, o as createPrismaAdapter, s as MongooseAdapter, t as PrismaAdapter } from "./index-DAushRTt.mjs";
4
- import { C as MAX_REGEX_LENGTH, D as RESERVED_QUERY_PARAMS, E as MutationOperation, O as SYSTEM_FIELDS, S as MAX_FILTER_DEPTH, T as MUTATION_OPERATIONS, _ as DEFAULT_UPDATE_METHOD, a as getControllerScope, b as HookOperation, d as CrudOperation, f as DEFAULT_ID_FIELD, g as DEFAULT_TENANT_FIELD, h as DEFAULT_SORT, m as DEFAULT_MAX_LIMIT, p as DEFAULT_LIMIT, s as defineResourceVariants, u as CRUD_OPERATIONS, v as HOOK_OPERATIONS, w as MAX_SEARCH_LENGTH, x as HookPhase, y as HOOK_PHASES } from "./index-t8pLpPFW.mjs";
3
+ import { l as createMongooseAdapter, o as createPrismaAdapter, s as MongooseAdapter, t as PrismaAdapter } from "./index-BbMrcvGp.mjs";
4
+ import { C as MAX_REGEX_LENGTH, D as RESERVED_QUERY_PARAMS, E as MutationOperation, O as SYSTEM_FIELDS, S as MAX_FILTER_DEPTH, T as MUTATION_OPERATIONS, _ as DEFAULT_UPDATE_METHOD, a as getControllerScope, b as HookOperation, d as CrudOperation, f as DEFAULT_ID_FIELD, g as DEFAULT_TENANT_FIELD, h as DEFAULT_SORT, m as DEFAULT_MAX_LIMIT, p as DEFAULT_LIMIT, s as defineResourceVariants, u as CRUD_OPERATIONS, v as HOOK_OPERATIONS, w as MAX_SEARCH_LENGTH, x as HookPhase, y as HOOK_PHASES } from "./index-BdXnTPRj.mjs";
5
5
  import { A as requireRoles, C as allOf, E as denyAll, M as when, O as requireAuth, S as createOrgPermissions, T as anyOf, a as presets_d_exports, c as readOnly, d as requireOrgRole, f as requireScopeContext, i as ownerWithAdminBypass, k as requireOwnership, l as requireOrgInScope, m as requireTeamMembership, n as authenticated, o as publicRead, p as requireServiceScope, r as fullPublic, s as publicReadAdminWrite, t as adminOnly, u as requireOrgMembership, v as DynamicPermissionMatrix, w as allowPublic, x as createDynamicPermissionMatrix, y as DynamicPermissionMatrixConfig } from "./index-BYCqHCVu.mjs";
6
- import { ft as UnauthorizedError, j as envelope, mt as createDomainError, ot as ForbiddenError, pt as ValidationError, rt as ArcError, st as NotFoundError, t as getUserId } from "./index-DsJ1MNfC.mjs";
6
+ import { ft as UnauthorizedError, j as envelope, mt as createDomainError, ot as ForbiddenError, pt as ValidationError, rt as ArcError, st as NotFoundError, t as getUserId } from "./index-DdQ3O9Pg.mjs";
7
7
 
8
8
  //#region src/index.d.ts
9
9
  declare const version: string;
package/dist/index.mjs CHANGED
@@ -7,6 +7,6 @@ import { d as createDomainError, i as NotFoundError, l as UnauthorizedError, r a
7
7
  import { _ as getControllerScope } from "./routerShared-DeESFp4a.mjs";
8
8
  import { n as ResourceDefinition, r as defineResource, t as defineResourceVariants } from "./core-DXdSSFW-.mjs";
9
9
  //#region src/index.ts
10
- const version = "2.11.0";
10
+ const version = "2.11.2";
11
11
  //#endregion
12
12
  export { ArcError, BaseController, BaseCrudController, BulkMixin, CRUD_OPERATIONS, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, ForbiddenError, HOOK_OPERATIONS, HOOK_PHASES, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, MongooseAdapter, NotFoundError, PrismaAdapter, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, SlugMixin, SoftDeleteMixin, TreeMixin, UnauthorizedError, ValidationError, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, authenticated, createDomainError, createDynamicPermissionMatrix, createMongooseAdapter, createOrgPermissions, createPrismaAdapter, defineResource, defineResourceVariants, denyAll, envelope, fields, fullPublic, getControllerScope, getUserId, ownerWithAdminBypass, presets_exports as permissions, publicRead, publicReadAdminWrite, readOnly, requireAuth, requireOrgInScope, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireScopeContext, requireServiceScope, requireTeamMembership, version, when };
@@ -1,7 +1,7 @@
1
1
  import { a as WebSocketMessage, i as WebSocketClient, o as WebSocketPluginOptions } from "../websocket-CyJ1VIFI.mjs";
2
2
  import { EventGatewayOptions } from "./event-gateway.mjs";
3
3
  import { JobDefinition, JobDispatchOptions, JobDispatcher, JobMeta, JobsPluginOptions, QueueStats } from "./jobs.mjs";
4
- import { c as McpResourceConfig, f as ToolAnnotations, i as CrudOperation, l as PromptDefinition, m as ToolDefinition, n as CallToolResult, o as McpAuthResult, p as ToolContext, r as CreateMcpServerConfig, s as McpPluginOptions, t as BetterAuthHandler } from "../types-D9NqiYIw.mjs";
4
+ import { c as McpResourceConfig, f as ToolAnnotations, i as CrudOperation, l as PromptDefinition, m as ToolDefinition, n as CallToolResult, o as McpAuthResult, p as ToolContext, r as CreateMcpServerConfig, s as McpPluginOptions, t as BetterAuthHandler } from "../types-9beEMe25.mjs";
5
5
  import { StreamlinePluginOptions, WorkflowLike, WorkflowRunLike } from "./streamline.mjs";
6
6
  import { WebhookDeliveryRecord, WebhookManager, WebhookPluginOptions, WebhookStore, WebhookSubscription } from "./webhooks.mjs";
7
7
  export { type BetterAuthHandler, type CallToolResult, type CreateMcpServerConfig, type CrudOperation, type EventGatewayOptions, type JobDefinition, type JobDispatchOptions, type JobDispatcher, type JobMeta, type JobsPluginOptions, type McpAuthResult, type McpPluginOptions, type McpResourceConfig, type PromptDefinition, type QueueStats, type StreamlinePluginOptions, type ToolAnnotations, type ToolContext, type ToolDefinition, type WebSocketClient, type WebSocketMessage, type WebSocketPluginOptions, type WebhookDeliveryRecord, type WebhookManager, type WebhookPluginOptions, type WebhookStore, type WebhookSubscription, type WorkflowLike, type WorkflowRunLike };
@@ -1,5 +1,5 @@
1
- import { B as ResourceDefinition } from "../../index-Cm0vUrr_.mjs";
2
- import { a as McpAuthResolver, c as McpResourceConfig, d as SessionEntry, f as ToolAnnotations, i as CrudOperation, l as PromptDefinition, m as ToolDefinition, n as CallToolResult, o as McpAuthResult, p as ToolContext, r as CreateMcpServerConfig, s as McpPluginOptions, t as BetterAuthHandler, u as PromptResult } from "../../types-D9NqiYIw.mjs";
1
+ import { B as ResourceDefinition } from "../../index-6u4_Gg6G.mjs";
2
+ import { a as McpAuthResolver, c as McpResourceConfig, d as SessionEntry, f as ToolAnnotations, i as CrudOperation, l as PromptDefinition, m as ToolDefinition, n as CallToolResult, o as McpAuthResult, p as ToolContext, r as CreateMcpServerConfig, s as McpPluginOptions, t as BetterAuthHandler, u as PromptResult } from "../../types-9beEMe25.mjs";
3
3
  import { FastifyPluginAsync } from "fastify";
4
4
  import { z } from "zod";
5
5
 
@@ -1,4 +1,4 @@
1
- import { o as McpAuthResult, s as McpPluginOptions } from "../../types-D9NqiYIw.mjs";
1
+ import { o as McpAuthResult, s as McpPluginOptions } from "../../types-9beEMe25.mjs";
2
2
 
3
3
  //#region src/integrations/mcp/testing.d.ts
4
4
  interface TestMcpClientOptions {
@@ -1,4 +1,5 @@
1
1
  import { t as __exportAll } from "./chunk-BpYLSNr0.mjs";
2
+ import { arcLog } from "./logger/index.mjs";
2
3
  import { readdir } from "node:fs/promises";
3
4
  import { dirname, join, resolve } from "node:path";
4
5
  import { fileURLToPath, pathToFileURL } from "node:url";
@@ -58,7 +59,7 @@ var loadResources_exports = /* @__PURE__ */ __exportAll({ loadResources: () => l
58
59
  * ```
59
60
  */
60
61
  async function loadResources(dir, options = {}) {
61
- const { suffix = ".resource", recursive = true, exclude, include, silent = false } = options;
62
+ const { suffix = ".resource", recursive = true, exclude, include } = options;
62
63
  const absDir = resolve(dir.startsWith("file://") ? dirname(fileURLToPath(dir)) : dir);
63
64
  const files = await collectFiles(absDir, new RegExp(`${escapeRegex(suffix)}\\.(ts|js|mts|mjs)$`), recursive);
64
65
  files.sort();
@@ -99,13 +100,30 @@ async function loadResources(dir, options = {}) {
99
100
  return null;
100
101
  }));
101
102
  const resources = [];
103
+ const factoryFailed = [];
102
104
  for (const result of results) {
103
105
  if (!result) continue;
104
- let resource = result.mod.default ?? result.mod.resource;
105
- if (!resource || typeof resource.toPlugin !== "function") {
106
- for (const value of Object.values(result.mod)) if (value && typeof value === "object" && typeof value.toPlugin === "function") {
107
- resource = value;
108
- break;
106
+ let resource;
107
+ const rawDefault = result.mod.default;
108
+ if (typeof rawDefault === "function" && !("toPlugin" in rawDefault)) try {
109
+ const built = await rawDefault(options.context);
110
+ if (built && typeof built === "object" && typeof built.toPlugin === "function") resource = built;
111
+ else {
112
+ factoryFailed.push(`${result.file}: factory returned non-resource value`);
113
+ continue;
114
+ }
115
+ } catch (err) {
116
+ const msg = err instanceof Error ? err.message : String(err);
117
+ factoryFailed.push(`${result.file}: factory threw: ${msg}`);
118
+ continue;
119
+ }
120
+ else {
121
+ resource = rawDefault ?? result.mod.resource;
122
+ if (!resource || typeof resource.toPlugin !== "function") {
123
+ for (const value of Object.values(result.mod)) if (value && typeof value === "object" && typeof value.toPlugin === "function") {
124
+ resource = value;
125
+ break;
126
+ }
109
127
  }
110
128
  }
111
129
  if (!resource || typeof resource.toPlugin !== "function") {
@@ -119,12 +137,16 @@ async function loadResources(dir, options = {}) {
119
137
  }
120
138
  resources.push(resource);
121
139
  }
122
- const log = silent ? void 0 : options?.logger;
140
+ const log = options?.logger ?? arcLog("loadResources");
123
141
  if (log) {
124
142
  if (failed.length) {
125
143
  log.warn(`[arc] loadResources: ${failed.length} file(s) failed to import:`);
126
144
  for (const f of failed) log.warn(` - ${f}`);
127
145
  }
146
+ if (factoryFailed.length) {
147
+ log.warn(`[arc] loadResources: ${factoryFailed.length} factory export(s) failed (function default that returned non-resource or threw):`);
148
+ for (const f of factoryFailed) log.warn(` - ${f}`);
149
+ }
128
150
  if (skipped.length) {
129
151
  log.warn(`[arc] loadResources: ${skipped.length} file(s) skipped (no default export with toPlugin):`);
130
152
  for (const f of skipped) log.warn(` - ${f}`);
@@ -1,4 +1,4 @@
1
- import { I as MiddlewareHandler, L as RequestWithExtras, Q as MiddlewareConfig } from "../index-Cm0vUrr_.mjs";
1
+ import { I as MiddlewareHandler, L as RequestWithExtras, Q as MiddlewareConfig } from "../index-6u4_Gg6G.mjs";
2
2
  import { RouteHandlerMethod } from "fastify";
3
3
 
4
4
  //#region src/middleware/middleware.d.ts
@@ -1,4 +1,4 @@
1
- import { yt as RouteHandler } from "../index-Cm0vUrr_.mjs";
1
+ import { yt as RouteHandler } from "../index-6u4_Gg6G.mjs";
2
2
  import { d as UserBase } from "../fields-C8Y0XLAu.mjs";
3
3
  import { InvitationAdapter, InvitationDoc, MemberDoc, OrgAdapter, OrgDoc, OrgPermissionStatement, OrgRole, OrganizationPluginOptions } from "./types.mjs";
4
4
  import { FastifyPluginAsync, RouteHandlerMethod } from "fastify";
@@ -1,4 +1,4 @@
1
- import { Ct as OperationFilter, Dt as Transform, Et as PipelineStep, St as NextFunction, Tt as PipelineContext, _t as IControllerResponse, bt as Guard, wt as PipelineConfig, xt as Interceptor } from "../index-Cm0vUrr_.mjs";
1
+ import { Ct as OperationFilter, Dt as Transform, Et as PipelineStep, St as NextFunction, Tt as PipelineContext, _t as IControllerResponse, bt as Guard, wt as PipelineConfig, xt as Interceptor } from "../index-6u4_Gg6G.mjs";
2
2
 
3
3
  //#region src/pipeline/guard.d.ts
4
4
  interface GuardOptions {
@@ -1,4 +1,4 @@
1
- import { Pt as AnyRecord, Q as MiddlewareConfig, ft as RouteSchemaOptions, gn as HookSystem, lt as RouteDefinition, tt as PresetHook, z as ResourceRegistry } from "../index-Cm0vUrr_.mjs";
1
+ import { Pt as AnyRecord, Q as MiddlewareConfig, ft as RouteSchemaOptions, gn as HookSystem, lt as RouteDefinition, tt as PresetHook, z as ResourceRegistry } from "../index-6u4_Gg6G.mjs";
2
2
  import { t as ExternalOpenApiPaths } from "../externalPaths-Bapitwvd.mjs";
3
3
  import { a as MetricsCollector, c as metricsPlugin, d as ssePlugin, f as CachingOptions, h as cachingPlugin, i as MetricEntry, l as SSEOptions, m as _default$1, n as _default$7, o as MetricsOptions, p as CachingRule, r as versioningPlugin, s as _default$4, t as VersioningOptions, u as _default$6 } from "../versioning-M9lNLhO8.mjs";
4
4
  import { i as errorHandlerPlugin, n as ErrorMapper, r as defaultIsDuplicateKeyError, t as ErrorHandlerOptions } from "../errorHandler-Co3lnVmJ.mjs";
@@ -58,7 +58,7 @@ try {
58
58
  function createTracerProvider(options) {
59
59
  if (!isAvailable || !NodeTracerProvider || !BatchSpanProcessor || !OTLPTraceExporter) return null;
60
60
  const { serviceName = "@classytic/arc", serviceVersion, exporterUrl = "http://localhost:4318/v1/traces" } = options;
61
- const resolvedVersion = serviceVersion ?? "2.11.0";
61
+ const resolvedVersion = serviceVersion ?? "2.11.2";
62
62
  const exporter = new OTLPTraceExporter({ url: exporterUrl });
63
63
  const provider = new NodeTracerProvider({ resource: { attributes: {
64
64
  "service.name": serviceName,
@@ -1,4 +1,4 @@
1
- import { nt as PresetResult } from "../index-Cm0vUrr_.mjs";
1
+ import { nt as PresetResult } from "../index-6u4_Gg6G.mjs";
2
2
  import { r as RequestScope } from "../types-tgR4Pt8F.mjs";
3
3
  import { c as PermissionCheck } from "../fields-C8Y0XLAu.mjs";
4
4
  import { a as StorageReadResult, i as StorageReadRange, n as StorageContext, o as StorageUploadInput, r as StorageFile, t as Storage } from "../storage-BwGQXUpd.mjs";
@@ -1,4 +1,4 @@
1
- import { Pt as AnyRecord, _t as IControllerResponse, at as ResourceConfig, d as PaginationResult, nt as PresetResult, vt as IRequestContext } from "../index-Cm0vUrr_.mjs";
1
+ import { Pt as AnyRecord, _t as IControllerResponse, at as ResourceConfig, d as PaginationResult, nt as PresetResult, vt as IRequestContext } from "../index-6u4_Gg6G.mjs";
2
2
  import { FilesUploadPresetOptions, FilesUploadPresetPermissions, FilesUploadPresetRoutes, filesUploadPreset } from "./filesUpload.mjs";
3
3
  import { MultiTenantOptions, TenantFieldSpec, multiTenantPreset } from "./multiTenant.mjs";
4
4
  import { SearchHandler, SearchPresetOptions, SearchRouteConfig, searchPreset } from "./search.mjs";
@@ -1,4 +1,4 @@
1
- import { J as CrudRouteKey, nt as PresetResult } from "../index-Cm0vUrr_.mjs";
1
+ import { J as CrudRouteKey, nt as PresetResult } from "../index-6u4_Gg6G.mjs";
2
2
 
3
3
  //#region src/presets/multiTenant.d.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { lt as RouteDefinition, nt as PresetResult, pt as ControllerHandler, ut as RouteMcpConfig } from "../index-Cm0vUrr_.mjs";
1
+ import { lt as RouteDefinition, nt as PresetResult, pt as ControllerHandler, ut as RouteMcpConfig } from "../index-6u4_Gg6G.mjs";
2
2
  import { c as PermissionCheck } from "../fields-C8Y0XLAu.mjs";
3
3
 
4
4
  //#region src/presets/search.d.ts
@@ -1,4 +1,4 @@
1
- import { R as RegisterOptions, k as IntrospectionPluginOptions, z as ResourceRegistry } from "../index-Cm0vUrr_.mjs";
1
+ import { R as RegisterOptions, k as IntrospectionPluginOptions, z as ResourceRegistry } from "../index-6u4_Gg6G.mjs";
2
2
  import { FastifyPluginAsync } from "fastify";
3
3
 
4
4
  //#region src/registry/introspectionPlugin.d.ts
@@ -1,5 +1,5 @@
1
- import { B as ResourceDefinition, Pt as AnyRecord } from "../index-Cm0vUrr_.mjs";
2
- import { d as ResourceLike, r as CreateAppOptions } from "../types-CgikqKAj.mjs";
1
+ import { B as ResourceDefinition, Pt as AnyRecord } from "../index-6u4_Gg6G.mjs";
2
+ import { d as ResourceLike, r as CreateAppOptions } from "../types-BH7dEGvU.mjs";
3
3
  import { StorageContractSetup, StorageContractSetupResult, runStorageContract } from "./storageContract.mjs";
4
4
  import { FastifyInstance, FastifyServerOptions } from "fastify";
5
5
  import { Mock } from "vitest";
@@ -1081,7 +1081,7 @@ function pickDefaultAuth(authMode, callerAuth) {
1081
1081
  };
1082
1082
  }
1083
1083
  async function createTestApp(options = {}) {
1084
- const { createApp } = await import("../createApp-DvNYEhpb.mjs").then((n) => n.r);
1084
+ const { createApp } = await import("../createApp-P1d6rjPy.mjs").then((n) => n.r);
1085
1085
  const { resources = [], db = "in-memory", connectMongoose = false, authMode = "jwt", defaultOrgId, plugins, auth: callerAuth, ...appOptions } = options;
1086
1086
  let dbHandle;
1087
1087
  let dbUri;
@@ -1,4 +1,4 @@
1
- import { $ as OpenApiSchemas, A as RequestIdOptions, At as Authenticator, Bt as UserOrganization, C as RequestContext, D as HealthCheck, E as GracefulShutdownOptions, F as FastifyWithDecorators, Ft as ApiResponse, G as ActionsMap, H as ActionDefinition, I as MiddlewareHandler, It as ArcRequest, J as CrudRouteKey, K as ArcFieldRule, L as RequestWithExtras, Lt as JWTPayload, M as EventsDecorator, Mt as JwtContext, N as FastifyRequestExtras, Nt as TokenPair, O as HealthOptions, Ot as AuthHelpers, P as FastifyWithAuth, Pt as AnyRecord, Q as MiddlewareConfig, Rt as ObjectId, S as QueryParserInterface, T as CrudRouterOptions, U as ActionEntry, W as ActionHandlerFn, X as EventDefinition, Y as CrudSchemas, 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, jt as AuthenticatorContext, k as IntrospectionPluginOptions, kt as AuthPluginOptions, l as TypedRepository, lt as RouteDefinition, m as RegistryStats, mt as ControllerLike, n as ConfigError, nt as PresetResult, o as InferDocType, ot as ResourceHookContext, p as RegistryEntry, pt as ControllerHandler, q as CrudController, r as ValidateOptions, rt as RateLimitConfig, s as InferResourceDoc, st as ResourceHooks, t as RouteHandlerMethod, tn as BaseControllerOptions, 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 UserLike } from "../index-Cm0vUrr_.mjs";
1
+ import { $ as OpenApiSchemas, A as RequestIdOptions, At as Authenticator, Bt as UserOrganization, C as RequestContext, D as HealthCheck, E as GracefulShutdownOptions, F as FastifyWithDecorators, Ft as ApiResponse, G as ActionsMap, H as ActionDefinition, I as MiddlewareHandler, It as ArcRequest, J as CrudRouteKey, K as ArcFieldRule, L as RequestWithExtras, Lt as JWTPayload, M as EventsDecorator, Mt as JwtContext, N as FastifyRequestExtras, Nt as TokenPair, O as HealthOptions, Ot as AuthHelpers, P as FastifyWithAuth, Pt as AnyRecord, Q as MiddlewareConfig, Rt as ObjectId, S as QueryParserInterface, T as CrudRouterOptions, U as ActionEntry, W as ActionHandlerFn, X as EventDefinition, Y as CrudSchemas, 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, jt as AuthenticatorContext, k as IntrospectionPluginOptions, kt as AuthPluginOptions, l as TypedRepository, lt as RouteDefinition, m as RegistryStats, mt as ControllerLike, n as ConfigError, nt as PresetResult, o as InferDocType, ot as ResourceHookContext, p as RegistryEntry, pt as ControllerHandler, q as CrudController, r as ValidateOptions, rt as RateLimitConfig, s as InferResourceDoc, st as ResourceHooks, t as RouteHandlerMethod, tn as BaseControllerOptions, 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 UserLike } from "../index-6u4_Gg6G.mjs";
2
2
  import { r as RequestScope } from "../types-tgR4Pt8F.mjs";
3
3
  import { c as PermissionCheck, d as UserBase, l as PermissionContext, u as PermissionResult } from "../fields-C8Y0XLAu.mjs";
4
4
  import { n as ElevationOptions, t as ElevationEvent } from "../elevation-s5ykdNHr.mjs";
@@ -1,4 +1,4 @@
1
- import { B as ResourceDefinition } from "./index-Cm0vUrr_.mjs";
1
+ import { B as ResourceDefinition } from "./index-6u4_Gg6G.mjs";
2
2
  import { z } from "zod";
3
3
 
4
4
  //#region src/integrations/mcp/types.d.ts
@@ -1,4 +1,4 @@
1
- import { At as Authenticator } from "./index-Cm0vUrr_.mjs";
1
+ import { At as Authenticator } from "./index-6u4_Gg6G.mjs";
2
2
  import { r as CacheStore } from "./interface-Da0r7Lna.mjs";
3
3
  import { n as ElevationOptions } from "./elevation-s5ykdNHr.mjs";
4
4
  import { o as EventTransport } from "./EventTransport-CfVEGaEl.mjs";
@@ -74,11 +74,63 @@ interface ResourceLike {
74
74
  /** Applied preset names */
75
75
  _appliedPresets?: string[];
76
76
  }
77
- interface LoadResourcesOptions {
77
+ /**
78
+ * Resource module — what a `.resource.ts` file's default (or named) export
79
+ * may resolve to.
80
+ *
81
+ * Two shapes accepted:
82
+ * 1. **Plain `ResourceLike`** — the result of `defineResource({...})`.
83
+ * Used as-is; no engine wiring needed.
84
+ * 2. **Factory `(ctx: TContext) => ResourceLike | Promise<ResourceLike>`**
85
+ * — a function arc calls with the `context` from `LoadResourcesOptions`.
86
+ * Eliminates the parallel `createXResource(engine)` factory files +
87
+ * `exclude: [...]` bookkeeping that engine-bound resources used to need.
88
+ *
89
+ * Detection is by `typeof === 'function'`: `ResourceDefinition` instances
90
+ * (returned by `defineResource()`) are class instances (`typeof === 'object'`),
91
+ * so the two shapes are unambiguous in practice.
92
+ */
93
+ type ResourceModule<TContext = unknown> = ResourceLike | ((ctx: TContext) => ResourceLike | Promise<ResourceLike>);
94
+ interface LoadResourcesOptions<TContext = unknown> {
78
95
  /** File pattern suffix (default: '.resource'). Matches `*.resource.{ts,js,mts,mjs}`. */
79
96
  suffix?: string;
80
97
  /** Recurse into subdirectories (default: true) */
81
98
  recursive?: boolean;
99
+ /**
100
+ * Context passed to factory-style default exports. Resources whose default
101
+ * export is a function `(ctx) => ResourceLike` are called with this value;
102
+ * plain `ResourceLike` exports are returned unchanged.
103
+ *
104
+ * Use this to thread engine handles into engine-bound resources without
105
+ * creating parallel factory files outside `loadResources`'s sweep:
106
+ *
107
+ * ```ts
108
+ * // category.resource.ts
109
+ * import type { AppContext } from '#core/app/context.js';
110
+ * export default (ctx: AppContext) =>
111
+ * defineResource({
112
+ * name: 'category',
113
+ * adapter: createMongooseAdapter(
114
+ * ctx.catalog.models.Category,
115
+ * ctx.catalog.repositories.category,
116
+ * ),
117
+ * });
118
+ *
119
+ * // create-arc-app-options.ts
120
+ * resources: async () => {
121
+ * const [catalog, flow] = await Promise.all([
122
+ * ensureCatalogEngine(),
123
+ * ensureFlowEngine(),
124
+ * ]);
125
+ * return loadResources(import.meta.url, { context: { catalog, flow } });
126
+ * }
127
+ * ```
128
+ *
129
+ * Backwards compatible — pre-2.11.1 callers omit `context`, plain exports
130
+ * keep working unchanged. Factories that need a context but receive
131
+ * `undefined` should narrow defensively.
132
+ */
133
+ context?: TContext;
82
134
  /**
83
135
  * Resource names to exclude. Matched against the resource's `.name` property
84
136
  * after import, so you use the resource name (not the filename).
@@ -101,14 +153,26 @@ interface LoadResourcesOptions {
101
153
  */
102
154
  include?: string[];
103
155
  /**
104
- * Suppress warning logs for skipped/failed files.
105
- * Useful when your resources directory contains factory files or helpers
106
- * that don't export a resource (e.g., `account.resource.ts` exporting a factory).
156
+ * Optional logger override for diagnostics. When omitted, warnings flow
157
+ * through arc's standard logger (`arcLog('loadResources')`) same path
158
+ * as every other arc-internal warning, controlled by `ARC_SUPPRESS_WARNINGS=1`
159
+ * and routable via `configureArcLogger({ writer })`.
107
160
  *
108
- * @default false
161
+ * Pass any object with `warn(msg)` to override (e.g. `fastify.log` —
162
+ * which is what `registerResources` passes automatically when arc's
163
+ * factory triggers auto-discovery via `resourceDir`).
164
+ *
165
+ * Pre-2.11.1 had a `silent: boolean` flag and "silent by default" semantics;
166
+ * both removed. Migration:
167
+ *
168
+ * ```ts
169
+ * // Pre-2.11.1 // 2.11.1+
170
+ * loadResources(url, { silent: true }); // ARC_SUPPRESS_WARNINGS=1 (env)
171
+ * // OR configureArcLogger({ writer })
172
+ * loadResources(url, { silent: !isDev }); // ARC_SUPPRESS_WARNINGS=1 in prod
173
+ * loadResources(url, { logger: pinoAdapter }); // unchanged — still works
174
+ * ```
109
175
  */
110
- silent?: boolean;
111
- /** Optional logger for diagnostics. No output when omitted (silent by default). */
112
176
  logger?: {
113
177
  warn: (msg: string) => void;
114
178
  };
@@ -137,7 +201,7 @@ interface LoadResourcesOptions {
137
201
  * await loadResources('./src/resources');
138
202
  * ```
139
203
  */
140
- declare function loadResources(dir: string, options?: LoadResourcesOptions): Promise<ResourceLike[]>;
204
+ declare function loadResources<TContext = unknown>(dir: string, options?: LoadResourcesOptions<TContext>): Promise<ResourceLike[]>;
141
205
  //#endregion
142
206
  //#region src/factory/types.d.ts
143
207
  type CorsOptions = Record<string, unknown> & {
@@ -870,4 +934,4 @@ interface RawBodyOptions {
870
934
  runFirst?: boolean;
871
935
  }
872
936
  //#endregion
873
- export { CustomPluginAuthOption as a, RawBodyOptions as c, ResourceLike as d, loadResources as f, CustomAuthenticatorOption as i, UnderPressureOptions as l, BetterAuthOption as n, JwtAuthOption as o, CreateAppOptions as r, MultipartOptions as s, AuthOption as t, LoadResourcesOptions as u };
937
+ export { CustomPluginAuthOption as a, RawBodyOptions as c, ResourceLike as d, ResourceModule as f, CustomAuthenticatorOption as i, UnderPressureOptions as l, BetterAuthOption as n, JwtAuthOption as o, loadResources as p, CreateAppOptions as r, MultipartOptions as s, AuthOption as t, LoadResourcesOptions as u };
@@ -1,2 +1,2 @@
1
- import { $ as ValidationResult, A as handleRaw, B as CompensationStep, C as queryParams, D as ArcQueryParser, E as wrapResponse, F as defineErrorMapper, G as CircuitBreakerOptions, H as withCompensation, I as CompensationDefinition, J as CircuitState, K as CircuitBreakerRegistry, L as CompensationError, M as Guard, N as GuardConfig, O as ArcQueryParserOptions, P as defineGuard, Q as ValidateOptions, R as CompensationHooks, S as paginationSchema, T as successResponseSchema, U as CircuitBreaker, V as defineCompensation, W as CircuitBreakerError, X as createCircuitBreakerRegistry, Y as createCircuitBreaker, Z as ConfigError, _ as getDefaultCrudSchemas, a as TransitionConfig, at as ErrorDetails, b as listResponse, c as JsonSchemaTarget, ct as OrgAccessDeniedError, d as isJsonSchema, dt as ServiceUnavailableError, et as assertValidConfig, f as isZodSchema, ft as UnauthorizedError, g as errorResponseSchema, gt as isArcError, h as deleteResponse, ht as createError, i as StateMachine, it as ConflictError, j as envelope, k as createQueryParser, l as convertOpenApiSchemas, lt as OrgRequiredError, m as JsonSchema, mt as createDomainError, n as EventsDecorator, nt as validateResourceConfig, o as createStateMachine, ot as ForbiddenError, p as toJsonSchema, pt as ValidationError, q as CircuitBreakerStats, r as hasEvents, rt as ArcError, s as simpleEqualityMatcher, st as NotFoundError, t as getUserId, tt as formatValidationErrors, u as convertRouteSchema, ut as RateLimitError, v as getListQueryParams, w as responses, x as mutationResponse, y as itemResponse, z as CompensationResult } from "../index-DsJ1MNfC.mjs";
1
+ import { $ as ValidationResult, A as handleRaw, B as CompensationStep, C as queryParams, D as ArcQueryParser, E as wrapResponse, F as defineErrorMapper, G as CircuitBreakerOptions, H as withCompensation, I as CompensationDefinition, J as CircuitState, K as CircuitBreakerRegistry, L as CompensationError, M as Guard, N as GuardConfig, O as ArcQueryParserOptions, P as defineGuard, Q as ValidateOptions, R as CompensationHooks, S as paginationSchema, T as successResponseSchema, U as CircuitBreaker, V as defineCompensation, W as CircuitBreakerError, X as createCircuitBreakerRegistry, Y as createCircuitBreaker, Z as ConfigError, _ as getDefaultCrudSchemas, a as TransitionConfig, at as ErrorDetails, b as listResponse, c as JsonSchemaTarget, ct as OrgAccessDeniedError, d as isJsonSchema, dt as ServiceUnavailableError, et as assertValidConfig, f as isZodSchema, ft as UnauthorizedError, g as errorResponseSchema, gt as isArcError, h as deleteResponse, ht as createError, i as StateMachine, it as ConflictError, j as envelope, k as createQueryParser, l as convertOpenApiSchemas, lt as OrgRequiredError, m as JsonSchema, mt as createDomainError, n as EventsDecorator, nt as validateResourceConfig, o as createStateMachine, ot as ForbiddenError, p as toJsonSchema, pt as ValidationError, q as CircuitBreakerStats, r as hasEvents, rt as ArcError, s as simpleEqualityMatcher, st as NotFoundError, t as getUserId, tt as formatValidationErrors, u as convertRouteSchema, ut as RateLimitError, v as getListQueryParams, w as responses, x as mutationResponse, y as itemResponse, z as CompensationResult } from "../index-DdQ3O9Pg.mjs";
2
2
  export { ArcError, ArcQueryParser, ArcQueryParserOptions, CircuitBreaker, CircuitBreakerError, CircuitBreakerOptions, CircuitBreakerRegistry, CircuitBreakerStats, CircuitState, CompensationDefinition, CompensationError, CompensationHooks, CompensationResult, CompensationStep, ConfigError, ConflictError, ErrorDetails, EventsDecorator, ForbiddenError, Guard, GuardConfig, JsonSchema, JsonSchemaTarget, NotFoundError, OrgAccessDeniedError, OrgRequiredError, RateLimitError, ServiceUnavailableError, StateMachine, TransitionConfig, UnauthorizedError, ValidateOptions, ValidationError, ValidationResult, assertValidConfig, convertOpenApiSchemas, convertRouteSchema, createCircuitBreaker, createCircuitBreakerRegistry, createDomainError, createError, createQueryParser, createStateMachine, defineCompensation, defineErrorMapper, defineGuard, deleteResponse, envelope, errorResponseSchema, formatValidationErrors, getDefaultCrudSchemas, getListQueryParams, getUserId, handleRaw, hasEvents, isArcError, isJsonSchema, isZodSchema, itemResponse, listResponse, mutationResponse, paginationSchema, queryParams, responses, simpleEqualityMatcher, successResponseSchema, toJsonSchema, validateResourceConfig, withCompensation, wrapResponse };