@classytic/arc 2.11.0 → 2.11.1

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 (39) hide show
  1. package/dist/adapters/index.d.mts +2 -2
  2. package/dist/audit/index.d.mts +1 -1
  3. package/dist/auth/index.d.mts +1 -1
  4. package/dist/core/index.d.mts +2 -2
  5. package/dist/{createApp-DvNYEhpb.mjs → createApp-P1d6rjPy.mjs} +1 -1
  6. package/dist/docs/index.d.mts +1 -1
  7. package/dist/events/index.d.mts +1 -1
  8. package/dist/factory/index.d.mts +2 -2
  9. package/dist/factory/index.mjs +2 -2
  10. package/dist/hooks/index.d.mts +1 -1
  11. package/dist/idempotency/index.d.mts +1 -1
  12. package/dist/{index-Cm0vUrr_.d.mts → index-C_bgx9o4.d.mts} +15 -8
  13. package/dist/{index-DAushRTt.d.mts → index-CvM1e09j.d.mts} +1 -1
  14. package/dist/{index-t8pLpPFW.d.mts → index-pUczGjO0.d.mts} +1 -1
  15. package/dist/{index-DsJ1MNfC.d.mts → index-smCAoA5W.d.mts} +1 -1
  16. package/dist/index.d.mts +4 -4
  17. package/dist/index.mjs +1 -1
  18. package/dist/integrations/index.d.mts +1 -1
  19. package/dist/integrations/mcp/index.d.mts +2 -2
  20. package/dist/integrations/mcp/testing.d.mts +1 -1
  21. package/dist/{loadResources-YNwKHvRA.mjs → loadResources-CPpkyKfM.mjs} +29 -7
  22. package/dist/middleware/index.d.mts +1 -1
  23. package/dist/org/index.d.mts +1 -1
  24. package/dist/pipeline/index.d.mts +1 -1
  25. package/dist/plugins/index.d.mts +1 -1
  26. package/dist/plugins/tracing-entry.mjs +1 -1
  27. package/dist/presets/filesUpload.d.mts +1 -1
  28. package/dist/presets/index.d.mts +1 -1
  29. package/dist/presets/multiTenant.d.mts +1 -1
  30. package/dist/presets/search.d.mts +1 -1
  31. package/dist/registry/index.d.mts +1 -1
  32. package/dist/testing/index.d.mts +2 -2
  33. package/dist/testing/index.mjs +1 -1
  34. package/dist/types/index.d.mts +1 -1
  35. package/dist/{types-CgikqKAj.d.mts → types-BdA4uMBV.d.mts} +74 -10
  36. package/dist/{types-D9NqiYIw.d.mts → types-Bh_gEJBi.d.mts} +1 -1
  37. package/dist/utils/index.d.mts +1 -1
  38. package/package.json +1 -1
  39. 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-C_bgx9o4.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-CvM1e09j.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-C_bgx9o4.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-C_bgx9o4.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-C_bgx9o4.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-pUczGjO0.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-C_bgx9o4.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-C_bgx9o4.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-BdA4uMBV.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-C_bgx9o4.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-C_bgx9o4.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";
@@ -1942,10 +1942,13 @@ interface ActionDefinition {
1942
1942
  readonly permissions?: PermissionCheck;
1943
1943
  /**
1944
1944
  * 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.
1945
+ *
1946
+ * Typed `unknown` (not `Record<string, unknown>`) so Zod class instances
1947
+ * — `ZodObject<...>` carries no string index signature — assign without
1948
+ * a cast. Same convention as `RouteDefinition.schema.body` / `customSchemas`.
1949
+ * Runtime feature-detects via `convertRouteSchema` / `toJsonSchema`.
1947
1950
  */
1948
- readonly schema?: Record<string, unknown>;
1951
+ readonly schema?: unknown;
1949
1952
  /** Description for OpenAPI docs and MCP tool */
1950
1953
  readonly description?: string;
1951
1954
  /**
@@ -2060,8 +2063,12 @@ interface EventDefinition {
2060
2063
  name: string;
2061
2064
  /** Optional handler — events are published via `fastify.events.publish()`. */
2062
2065
  handler?: (data: unknown) => Promise<void> | void;
2063
- /** JSON schema for event payload */
2064
- schema?: Record<string, unknown>;
2066
+ /**
2067
+ * JSON Schema or Zod v4 schema for event payload. Typed `unknown` so Zod
2068
+ * class instances assign without a cast (same convention as
2069
+ * `ActionDefinition.schema` and `RouteDefinition.schema`).
2070
+ */
2071
+ schema?: unknown;
2065
2072
  description?: string;
2066
2073
  }
2067
2074
  /** Resource-level permissions — only `PermissionCheck` functions allowed. */
@@ -2361,7 +2368,7 @@ declare class ResourceDefinition<TDoc = AnyRecord> {
2361
2368
  getEvents(): Array<{
2362
2369
  name: string;
2363
2370
  module: string;
2364
- schema?: AnyRecord;
2371
+ schema?: unknown;
2365
2372
  description?: string;
2366
2373
  }>;
2367
2374
  /**
@@ -2762,7 +2769,7 @@ interface ResourceMetadata {
2762
2769
  description?: string;
2763
2770
  permissions?: PermissionCheck;
2764
2771
  raw?: boolean;
2765
- schema?: Record<string, unknown>;
2772
+ schema?: unknown;
2766
2773
  }>;
2767
2774
  routes: Array<{
2768
2775
  method: string;
@@ -2814,7 +2821,7 @@ interface RegistryEntry extends ResourceMetadata {
2814
2821
  actions?: Array<{
2815
2822
  readonly name: string;
2816
2823
  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`) */
2824
+ readonly schema?: unknown; /** Per-action permission check (if different from resource-level `actionPermissions`) */
2818
2825
  readonly permissions?: PermissionCheck; /** MCP tool generation flag — `false` to skip, object for overrides */
2819
2826
  readonly mcp?: boolean | {
2820
2827
  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-C_bgx9o4.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-C_bgx9o4.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-C_bgx9o4.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-C_bgx9o4.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-CvM1e09j.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-pUczGjO0.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-smCAoA5W.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.1";
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-Bh_gEJBi.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-C_bgx9o4.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-Bh_gEJBi.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-Bh_gEJBi.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-C_bgx9o4.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-C_bgx9o4.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-C_bgx9o4.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-C_bgx9o4.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.1";
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-C_bgx9o4.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-C_bgx9o4.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-C_bgx9o4.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-C_bgx9o4.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-C_bgx9o4.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-C_bgx9o4.mjs";
2
+ import { d as ResourceLike, r as CreateAppOptions } from "../types-BdA4uMBV.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-C_bgx9o4.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 { At as Authenticator } from "./index-Cm0vUrr_.mjs";
1
+ import { At as Authenticator } from "./index-C_bgx9o4.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,4 +1,4 @@
1
- import { B as ResourceDefinition } from "./index-Cm0vUrr_.mjs";
1
+ import { B as ResourceDefinition } from "./index-C_bgx9o4.mjs";
2
2
  import { z } from "zod";
3
3
 
4
4
  //#region src/integrations/mcp/types.d.ts
@@ -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-smCAoA5W.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 };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classytic/arc",
3
- "version": "2.11.0",
3
+ "version": "2.11.1",
4
4
  "description": "Resource-oriented backend framework for Fastify — clean, minimal, powerful, tree-shakable",
5
5
  "type": "module",
6
6
  "exports": {
@@ -8,11 +8,11 @@ description: |
8
8
  Triggers: arc, fastify resource, defineResource, createApp, BaseController, arc preset,
9
9
  arc auth, arc events, arc jobs, arc websocket, arc mcp, arc plugin, arc testing, arc cli,
10
10
  arc permissions, arc hooks, arc pipeline, arc factory, arc cache, arc QueryCache.
11
- version: 2.11.0
11
+ version: 2.11.1
12
12
  license: MIT
13
13
  metadata:
14
14
  author: Classytic
15
- version: "2.11.0"
15
+ version: "2.11.1"
16
16
  tags:
17
17
  - fastify
18
18
  - rest-api
@@ -1079,7 +1079,7 @@ const app = await createApp({
1079
1079
 
1080
1080
  `loadResources()` discovers files matching `*.resource.{ts,js,mts,mjs}`, recursively. Pass `import.meta.url` for dev/prod parity (resolves to `src/` in dev, `dist/` in prod automatically). Discovers `default` export, `export const resource`, OR any named export with `toPlugin()` (e.g., `export const userResource`).
1081
1081
 
1082
- Options: `exclude`, `include`, `suffix`, `recursive`, `silent`.
1082
+ Options: `exclude`, `include`, `suffix`, `recursive`, `context`, `logger`. Silent by default — pass `logger: { warn(msg) {...} }` to receive skip / factory-failure diagnostics.
1083
1083
 
1084
1084
  **Per-resource opt-out of `resourcePrefix`** — for webhooks, admin routes:
1085
1085
  ```typescript