@classytic/arc 2.6.1 → 2.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +48 -2
  2. package/dist/{BaseController-AbbRx3e0.mjs → BaseController-DzRtluEF.mjs} +88 -8
  3. package/dist/{ResourceRegistry-DeCIFlix.mjs → ResourceRegistry-C6ngvOnn.mjs} +1 -0
  4. package/dist/adapters/index.d.mts +2 -2
  5. package/dist/adapters/index.mjs +1 -1
  6. package/dist/{adapters-CTn28N4y.mjs → adapters-gM-WYjNe.mjs} +6 -4
  7. package/dist/audit/index.d.mts +31 -5
  8. package/dist/audit/index.mjs +21 -3
  9. package/dist/auth/index.d.mts +1 -1
  10. package/dist/cli/commands/docs.mjs +1 -1
  11. package/dist/cli/commands/introspect.mjs +1 -1
  12. package/dist/core/index.d.mts +2 -2
  13. package/dist/core/index.mjs +2 -2
  14. package/dist/{createApp-Bol7DLUf.mjs → createApp-D2w0LdYJ.mjs} +27 -11
  15. package/dist/{defineResource-bVKHjQzE.mjs → defineResource-wWMBB4GP.mjs} +48 -30
  16. package/dist/docs/index.d.mts +1 -1
  17. package/dist/dynamic/index.d.mts +1 -1
  18. package/dist/dynamic/index.mjs +1 -1
  19. package/dist/factory/index.d.mts +1 -1
  20. package/dist/factory/index.mjs +31 -15
  21. package/dist/hooks/index.d.mts +1 -1
  22. package/dist/{index-BIsZ_su5.d.mts → index-CHeJa4Zd.d.mts} +3 -3
  23. package/dist/{index-Cb3gtbg7.d.mts → index-gz6iuzCp.d.mts} +1 -1
  24. package/dist/index.d.mts +3 -3
  25. package/dist/index.mjs +4 -4
  26. package/dist/integrations/index.d.mts +1 -1
  27. package/dist/integrations/mcp/index.d.mts +2 -2
  28. package/dist/integrations/mcp/index.mjs +1 -1
  29. package/dist/integrations/mcp/testing.d.mts +1 -1
  30. package/dist/integrations/mcp/testing.mjs +1 -1
  31. package/dist/{interface-DDW43OmS.d.mts → interface-DYH8AXGe.d.mts} +89 -4
  32. package/dist/org/index.d.mts +1 -1
  33. package/dist/plugins/index.d.mts +1 -1
  34. package/dist/plugins/index.mjs +1 -1
  35. package/dist/plugins/tracing-entry.mjs +1 -1
  36. package/dist/presets/index.d.mts +1 -1
  37. package/dist/presets/multiTenant.d.mts +1 -1
  38. package/dist/registry/index.d.mts +1 -1
  39. package/dist/registry/index.mjs +1 -1
  40. package/dist/{resourceToTools-DH3c3e-T.mjs → resourceToTools-nCJWnG1r.mjs} +250 -13
  41. package/dist/testing/index.d.mts +26 -3
  42. package/dist/testing/index.mjs +46 -2
  43. package/dist/types/index.d.mts +1 -1
  44. package/dist/{types-D5rjsS_i.d.mts → types-B4_TDdPe.d.mts} +1 -1
  45. package/dist/{types-D5hJ-k_3.d.mts → types-By-5mIfn.d.mts} +7 -1
  46. package/dist/utils/index.d.mts +1 -1
  47. package/package.json +18 -18
  48. package/skills/arc/SKILL.md +80 -8
@@ -1,4 +1,4 @@
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-Bol7DLUf.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-D2w0LdYJ.mjs";
2
2
  import { readdir } from "node:fs/promises";
3
3
  import { dirname, join, resolve } from "node:path";
4
4
  import { fileURLToPath, pathToFileURL } from "node:url";
@@ -110,32 +110,48 @@ async function loadResources(dir, options = {}) {
110
110
  const excludeSet = exclude ? new Set(exclude) : null;
111
111
  const skipped = [];
112
112
  const failed = [];
113
+ const isWindowsPath = (p) => /^[a-z]:[\\/]/i.test(p);
113
114
  const results = await Promise.all(files.map(async (file) => {
115
+ let mod;
116
+ let primaryError;
114
117
  try {
115
- let mod;
116
- try {
117
- mod = await import(pathToFileURL(file).href);
118
- } catch (_importErr) {
119
- mod = await import(file);
120
- }
118
+ mod = await import(pathToFileURL(file).href);
121
119
  return {
122
120
  file,
123
121
  mod
124
122
  };
125
123
  } catch (err) {
126
- const code = err.code;
127
- const msg = err instanceof Error ? err.message : String(err);
128
- if (code === "ERR_MODULE_NOT_FOUND" && msg.includes(".js")) failed.push(`${file}: ${msg}\n Hint: This file uses .js extension imports (TypeScript ESM convention).
129
- In production, ensure your build compiles .ts→.js before loadResources() runs.
130
- In tests, use vitest/tsx which resolves .js→.ts automatically.`);
131
- else failed.push(`${file}: ${msg}`);
132
- return null;
124
+ primaryError = err;
133
125
  }
126
+ if (!isWindowsPath(file)) try {
127
+ mod = await import(file);
128
+ return {
129
+ file,
130
+ mod
131
+ };
132
+ } catch {}
133
+ const err = primaryError;
134
+ const code = err.code;
135
+ const msg = err instanceof Error ? err.message : String(err);
136
+ if (code === "ERR_MODULE_NOT_FOUND" && msg.includes(".js")) failed.push(`${file}: ${msg}\n Hint: This file uses .js extension imports (TypeScript ESM convention).
137
+ • Production: ensure your build compiles .ts→.js before loadResources() runs.
138
+ • Node.js: use tsx, ts-node/esm, or a build step.
139
+ • Vitest: nested .js→.ts resolution may fail through dynamic imports.
140
+ Workaround: use import.meta.glob to preload resources statically.
141
+ See: https://github.com/classytic/arc/blob/main/docs/production-ops/factory.mdx#vitest-limitation`);
142
+ else failed.push(`${file}: ${msg}`);
143
+ return null;
134
144
  }));
135
145
  const resources = [];
136
146
  for (const result of results) {
137
147
  if (!result) continue;
138
- const resource = result.mod.default ?? result.mod.resource;
148
+ let resource = result.mod.default ?? result.mod.resource;
149
+ if (!resource || typeof resource.toPlugin !== "function") {
150
+ for (const value of Object.values(result.mod)) if (value && typeof value === "object" && typeof value.toPlugin === "function") {
151
+ resource = value;
152
+ break;
153
+ }
154
+ }
139
155
  if (!resource || typeof resource.toPlugin !== "function") {
140
156
  skipped.push(result.file);
141
157
  continue;
@@ -1,2 +1,2 @@
1
- import { an as HookPhase, cn as HookSystemOptions, dn as afterUpdate, fn as beforeCreate, gn as defineHook, hn as createHookSystem, in as HookOperation, ln as afterCreate, mn as beforeUpdate, nn as HookContext, on as HookRegistration, pn as beforeDelete, rn as HookHandler, sn as HookSystem, tn as DefineHookOptions, un as afterDelete } from "../interface-DDW43OmS.mjs";
1
+ import { _n as defineHook, an as HookOperation, cn as HookSystem, dn as afterDelete, fn as afterUpdate, gn as createHookSystem, hn as beforeUpdate, in as HookHandler, ln as HookSystemOptions, mn as beforeDelete, nn as DefineHookOptions, on as HookPhase, pn as beforeCreate, rn as HookContext, sn as HookRegistration, un as afterCreate } from "../interface-DYH8AXGe.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 { Ht as CrudRepository, K as ParsedQuery, W as OpenApiSchemas, Z as QueryParserInterface, a as RepositoryLike, dt as RouteSchemaOptions, n as DataAdapter, o as SchemaMetadata, s as ValidationResult } from "./interface-DDW43OmS.mjs";
1
+ import { G as OpenApiSchemas, Q as QueryParserInterface, Ut as CrudRepository, c as ValidationResult, ft as RouteSchemaOptions, n as AdapterSchemaContext, o as RepositoryLike, q as ParsedQuery, r as DataAdapter, s as SchemaMetadata } from "./interface-DYH8AXGe.mjs";
2
2
  import { Model } from "mongoose";
3
3
 
4
4
  //#region src/adapters/mongoose.d.ts
@@ -29,7 +29,7 @@ interface MongooseAdapterOptions<TDoc = unknown> {
29
29
  * });
30
30
  * ```
31
31
  */
32
- schemaGenerator?: (model: Model<TDoc>, options?: RouteSchemaOptions) => OpenApiSchemas | Record<string, unknown>;
32
+ schemaGenerator?: (model: Model<TDoc>, options?: RouteSchemaOptions, context?: AdapterSchemaContext) => OpenApiSchemas | Record<string, unknown>;
33
33
  }
34
34
  /**
35
35
  * Mongoose data adapter with proper type safety
@@ -53,7 +53,7 @@ declare class MongooseAdapter<TDoc = unknown> implements DataAdapter<TDoc> {
53
53
  * If a `schemaGenerator` plugin was provided (e.g. MongoKit's buildCrudSchemasFromModel),
54
54
  * it is used instead of the built-in basic conversion.
55
55
  */
56
- generateSchemas(schemaOptions?: RouteSchemaOptions): OpenApiSchemas | Record<string, unknown> | null;
56
+ generateSchemas(schemaOptions?: RouteSchemaOptions, context?: AdapterSchemaContext): OpenApiSchemas | Record<string, unknown> | null;
57
57
  /**
58
58
  * Extract relation metadata
59
59
  */
@@ -1,5 +1,5 @@
1
1
  import { s as RequestScope } from "./elevation-C_taLQrM.mjs";
2
- import { Ft as IControllerResponse, It as IRequestContext, O as FastifyWithDecorators, Pt as IController, S as CrudRouterOptions, b as CrudController, rt as RequestWithExtras, tt as RequestContext } from "./interface-DDW43OmS.mjs";
2
+ import { C as CrudRouterOptions, Ft as IController, It as IControllerResponse, Lt as IRequestContext, it as RequestWithExtras, k as FastifyWithDecorators, nt as RequestContext, x as CrudController } from "./interface-DYH8AXGe.mjs";
3
3
  import { t as PermissionCheck } from "./types-BNUccdcf.mjs";
4
4
  import { FastifyInstance, FastifyReply, FastifyRequest, RouteHandlerMethod } from "fastify";
5
5
 
package/dist/index.d.mts CHANGED
@@ -1,8 +1,8 @@
1
- import { $ as RegistryEntry, $t as PipelineStep, A as GracefulShutdownOptions, Bt as ResourceDefinition, C as CrudSchemas, Ct as BaseController, D as FastifyWithAuth, E as FastifyRequestExtras, F as InferResourceDoc, Ft as IControllerResponse, G as OwnershipCheck, H as MiddlewareHandler, Ht as CrudRepository, I as IntrospectionData, It as IRequestContext, J as PresetFunction, Jt as Interceptor, Kt as QueryOptions, L as IntrospectionPluginOptions, Lt as RouteHandler, M as HealthOptions, Mt as ControllerLike, N as InferAdapterDoc, O as FastifyWithDecorators, P as InferDocType, Pt as IController, Q as RateLimitConfig, Qt as PipelineContext, R as JWTPayload, S as CrudRouterOptions, V as MiddlewareConfig, Vt as defineResource, Wt as PaginatedResult, X as PresetResult, Xt as OperationFilter, Yt as NextFunction, Zt as PipelineConfig, a as RepositoryLike, at as ResourceConfig, b as CrudController, bt as ValidationResult$1, c as AdditionalRoute, ct as ResourceMetadata, dt as RouteSchemaOptions, en as Transform, et as RegistryStats, f as ArcInternalMetadata, ft as ServiceContext, gt as TypedResourceConfig, h as AuthPluginOptions, ht as TypedRepository, i as RelationMetadata, j as HealthCheck, k as FieldRule, l as AnyRecord, mt as TypedController, n as DataAdapter, nt as RequestIdOptions, o as SchemaMetadata, p as ArcRequest, qt as Guard, r as FieldMetadata, rt as RequestWithExtras, s as ValidationResult, tt as RequestContext, u as ApiResponse, ut as RouteHandlerMethod, v as ConfigError, vt as UserOrganization, w as EventDefinition, wt as BaseControllerOptions, x as CrudRouteKey, xt as envelope, yt as ValidateOptions } from "./interface-DDW43OmS.mjs";
1
+ import { $ as RateLimitConfig, $t as PipelineContext, A as FieldRule, C as CrudRouterOptions, D as FastifyRequestExtras, F as InferDocType, Ft as IController, Gt as PaginatedResult, H as MiddlewareConfig, Ht as defineResource, I as InferResourceDoc, It as IControllerResponse, Jt as Guard, K as OwnershipCheck, L as IntrospectionData, Lt as IRequestContext, M as HealthCheck, N as HealthOptions, Nt as ControllerLike, O as FastifyWithAuth, P as InferAdapterDoc, Qt as PipelineConfig, R as IntrospectionPluginOptions, Rt as RouteHandler, S as CrudRouteKey, St as envelope, T as EventDefinition, Tt as BaseControllerOptions, U as MiddlewareHandler, Ut as CrudRepository, Vt as ResourceDefinition, Xt as NextFunction, Y as PresetFunction, Yt as Interceptor, Z as PresetResult, Zt as OperationFilter, _t as TypedResourceConfig, a as RelationMetadata, bt as ValidateOptions, c as ValidationResult, d as ApiResponse, dt as RouteHandlerMethod, en as PipelineStep, et as RegistryEntry, ft as RouteSchemaOptions, g as AuthPluginOptions, gt as TypedRepository, ht as TypedController, i as FieldMetadata, it as RequestWithExtras, j as GracefulShutdownOptions, k as FastifyWithDecorators, l as AdditionalRoute, lt as ResourceMetadata, m as ArcRequest, nt as RequestContext, o as RepositoryLike, ot as ResourceConfig, p as ArcInternalMetadata, pt as ServiceContext, qt as QueryOptions, r as DataAdapter, rt as RequestIdOptions, s as SchemaMetadata, tn as Transform, tt as RegistryStats, u as AnyRecord, w as CrudSchemas, wt as BaseController, x as CrudController, xt as ValidationResult$1, y as ConfigError, yt as UserOrganization, z as JWTPayload } from "./interface-DYH8AXGe.mjs";
2
2
  import { a as applyFieldWritePermissions, i as applyFieldReadPermissions, n as FieldPermissionMap, o as fields, t as FieldPermission } from "./fields-DFwdaWCq.mjs";
3
3
  import { i as UserBase, n as PermissionContext, r as PermissionResult, t as PermissionCheck } from "./types-BNUccdcf.mjs";
4
- import { l as createMongooseAdapter, o as createPrismaAdapter, s as MongooseAdapter, t as PrismaAdapter } from "./index-BIsZ_su5.mjs";
5
- import { A as RESERVED_QUERY_PARAMS, C as HookOperation, D as MAX_SEARCH_LENGTH, E as MAX_REGEX_LENGTH, O as MUTATION_OPERATIONS, S as HOOK_PHASES, T as MAX_FILTER_DEPTH, _ as DEFAULT_MAX_LIMIT, a as getControllerScope, b as DEFAULT_UPDATE_METHOD, g as DEFAULT_LIMIT, h as DEFAULT_ID_FIELD, j as SYSTEM_FIELDS, k as MutationOperation, m as CrudOperation, p as CRUD_OPERATIONS, v as DEFAULT_SORT, w as HookPhase, x as HOOK_OPERATIONS, y as DEFAULT_TENANT_FIELD } from "./index-Cb3gtbg7.mjs";
4
+ import { l as createMongooseAdapter, o as createPrismaAdapter, s as MongooseAdapter, t as PrismaAdapter } from "./index-CHeJa4Zd.mjs";
5
+ import { A as RESERVED_QUERY_PARAMS, C as HookOperation, D as MAX_SEARCH_LENGTH, E as MAX_REGEX_LENGTH, O as MUTATION_OPERATIONS, S as HOOK_PHASES, T as MAX_FILTER_DEPTH, _ as DEFAULT_MAX_LIMIT, a as getControllerScope, b as DEFAULT_UPDATE_METHOD, g as DEFAULT_LIMIT, h as DEFAULT_ID_FIELD, j as SYSTEM_FIELDS, k as MutationOperation, m as CrudOperation, p as CRUD_OPERATIONS, v as DEFAULT_SORT, w as HookPhase, x as HOOK_OPERATIONS, y as DEFAULT_TENANT_FIELD } from "./index-gz6iuzCp.mjs";
6
6
  import { C as presets_d_exports, E as readOnly, S as ownerWithAdminBypass, T as publicReadAdminWrite, a as allOf, b as authenticated, c as createDynamicPermissionMatrix, d as requireAuth, f as requireOrgMembership, g as requireTeamMembership, h as requireRoles, l as createOrgPermissions, m as requireOwnership, n as DynamicPermissionMatrix, o as allowPublic, p as requireOrgRole, r as DynamicPermissionMatrixConfig, s as anyOf, u as denyAll, v as when, w as publicRead, x as fullPublic, y as adminOnly } from "./index-NGZksqM5.mjs";
7
7
  import { a as NotFoundError, d as ValidationError, f as createDomainError, i as ForbiddenError, t as ArcError, u as UnauthorizedError } from "./errors-CcVbl1-T.mjs";
8
8
  import { AsyncLocalStorage } from "node:async_hooks";
package/dist/index.mjs CHANGED
@@ -1,11 +1,11 @@
1
1
  import { a as DEFAULT_SORT, c as HOOK_OPERATIONS, d as MAX_REGEX_LENGTH, f as MAX_SEARCH_LENGTH, h as SYSTEM_FIELDS, i as DEFAULT_MAX_LIMIT, l as HOOK_PHASES, m as RESERVED_QUERY_PARAMS, n as DEFAULT_ID_FIELD, o as DEFAULT_TENANT_FIELD, p as MUTATION_OPERATIONS, r as DEFAULT_LIMIT, s as DEFAULT_UPDATE_METHOD, t as CRUD_OPERATIONS, u as MAX_FILTER_DEPTH } from "./constants-Cxde4rpC.mjs";
2
- import { a as createMongooseAdapter, i as MongooseAdapter, r as createPrismaAdapter, t as PrismaAdapter } from "./adapters-CTn28N4y.mjs";
3
- import { t as BaseController } from "./BaseController-AbbRx3e0.mjs";
2
+ import { a as createMongooseAdapter, i as MongooseAdapter, r as createPrismaAdapter, t as PrismaAdapter } from "./adapters-gM-WYjNe.mjs";
3
+ import { t as BaseController } from "./BaseController-DzRtluEF.mjs";
4
4
  import { envelope } from "./types/index.mjs";
5
5
  import { n as applyFieldWritePermissions, r as fields, t as applyFieldReadPermissions } from "./fields-ipsbIRPK.mjs";
6
6
  import { t as requestContext } from "./requestContext-DYtmNpm5.mjs";
7
7
  import { d as createDomainError, i as NotFoundError, l as UnauthorizedError, r as ForbiddenError, t as ArcError, u as ValidationError } from "./errors-NoQKsbAT.mjs";
8
- import { a as validateResourceConfig, f as getControllerScope, i as formatValidationErrors, m as pipe, n as defineResource, r as assertValidConfig, t as ResourceDefinition } from "./defineResource-bVKHjQzE.mjs";
8
+ import { a as validateResourceConfig, f as getControllerScope, i as formatValidationErrors, m as pipe, n as defineResource, r as assertValidConfig, t as ResourceDefinition } from "./defineResource-wWMBB4GP.mjs";
9
9
  import { S as readOnly, _ as fullPublic, a as createOrgPermissions, b as publicRead, c as requireOrgMembership, d as requireRoles, f as requireTeamMembership, g as authenticated, h as adminOnly, i as createDynamicPermissionMatrix, l as requireOrgRole, m as when, n as allowPublic, o as denyAll, r as anyOf, s as requireAuth, t as allOf, u as requireOwnership, v as ownerWithAdminBypass, x as publicReadAdminWrite, y as presets_exports } from "./permissions-C8ImI8gC.mjs";
10
10
  import { n as configureArcLogger, t as arcLog } from "./logger-Dz3j1ItV.mjs";
11
11
  //#region src/middleware/middleware.ts
@@ -127,6 +127,6 @@ function transform(name, handlerOrOptions) {
127
127
  }
128
128
  //#endregion
129
129
  //#region src/index.ts
130
- const version = "2.6.1";
130
+ const version = "2.6.3";
131
131
  //#endregion
132
132
  export { ArcError, BaseController, 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, UnauthorizedError, ValidationError, adminOnly, allOf, allowPublic, anyOf, applyFieldReadPermissions, applyFieldWritePermissions, arcLog, assertValidConfig, authenticated, configureArcLogger, createDomainError, createDynamicPermissionMatrix, createMongooseAdapter, createOrgPermissions, createPrismaAdapter, defineResource, denyAll, envelope, fields, formatValidationErrors, fullPublic, getControllerScope, guard, intercept, middleware, ownerWithAdminBypass, presets_exports as permissions, pipe, publicRead, publicReadAdminWrite, readOnly, requestContext, requireAuth, requireOrgMembership, requireOrgRole, requireOwnership, requireRoles, requireTeamMembership, sortMiddlewares, transform, validateResourceConfig, version, when };
@@ -1,7 +1,7 @@
1
1
  import { WebSocketClient, WebSocketMessage, WebSocketPluginOptions } from "./websocket.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-D5rjsS_i.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-B4_TDdPe.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 { Bt as ResourceDefinition } from "../../interface-DDW43OmS.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-D5rjsS_i.mjs";
1
+ import { Vt as ResourceDefinition } from "../../interface-DYH8AXGe.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-B4_TDdPe.mjs";
3
3
  import { FastifyPluginAsync } from "fastify";
4
4
  import { z } from "zod";
5
5
 
@@ -1,4 +1,4 @@
1
- import { n as fieldRulesToZod, r as createMcpServer, t as resourceToTools } from "../../resourceToTools-DH3c3e-T.mjs";
1
+ import { n as fieldRulesToZod, r as createMcpServer, t as resourceToTools } from "../../resourceToTools-nCJWnG1r.mjs";
2
2
  import { createHash } from "node:crypto";
3
3
  import fp from "fastify-plugin";
4
4
  //#region src/integrations/mcp/definePrompt.ts
@@ -1,4 +1,4 @@
1
- import { o as McpAuthResult, s as McpPluginOptions } from "../../types-D5rjsS_i.mjs";
1
+ import { o as McpAuthResult, s as McpPluginOptions } from "../../types-B4_TDdPe.mjs";
2
2
 
3
3
  //#region src/integrations/mcp/testing.d.ts
4
4
  interface TestMcpClientOptions {
@@ -1,4 +1,4 @@
1
- import { r as createMcpServer, t as resourceToTools } from "../../resourceToTools-DH3c3e-T.mjs";
1
+ import { r as createMcpServer, t as resourceToTools } from "../../resourceToTools-nCJWnG1r.mjs";
2
2
  //#region src/integrations/mcp/testing.ts
3
3
  /**
4
4
  * @classytic/arc/mcp/testing — MCP Test Utilities
@@ -470,6 +470,9 @@ declare class ResourceDefinition<TDoc = AnyRecord> {
470
470
  readonly disabledRoutes: CrudRouteKey[];
471
471
  readonly events: Record<string, EventDefinition>;
472
472
  readonly rateLimit?: RateLimitConfig | false;
473
+ readonly audit?: boolean | {
474
+ operations?: ("create" | "update" | "delete")[];
475
+ };
473
476
  readonly updateMethod?: "PUT" | "PATCH" | "both";
474
477
  readonly pipe?: PipelineConfig;
475
478
  readonly fields?: FieldPermissionMap;
@@ -1034,6 +1037,25 @@ declare class BaseController<TDoc = AnyRecord, TRepository extends RepositoryLik
1034
1037
  getTree(req: IRequestContext): Promise<IControllerResponse<TDoc[]>>;
1035
1038
  getChildren(req: IRequestContext): Promise<IControllerResponse<TDoc[]>>;
1036
1039
  bulkCreate(req: IRequestContext): Promise<IControllerResponse<TDoc[]>>;
1040
+ /**
1041
+ * Build a tenant-scoped filter for bulk update/delete.
1042
+ *
1043
+ * Mirrors `AccessControl.buildIdFilter` semantics for single-doc ops:
1044
+ * - Always merge `_policyFilters` (from permission middleware)
1045
+ * - When `tenantField` is set AND a `member` scope is present, add the
1046
+ * org filter so cross-tenant data can't be touched.
1047
+ * - When the scope is `elevated` (platform admin), no org filter is
1048
+ * applied — admins can bulk-update across orgs intentionally.
1049
+ * - When the scope is `public` on a tenant-scoped resource, deny.
1050
+ * - When NO scope is present at all (e.g., direct controller calls in
1051
+ * unit tests, or app routes without auth middleware), the controller
1052
+ * stays lenient — it's the middleware layer's job to fail-close.
1053
+ * Apps that want fail-close on bulk routes should run the multi-tenant
1054
+ * preset middleware (or equivalent) ahead of these handlers.
1055
+ *
1056
+ * Returns the merged filter, or `null` when access must be denied.
1057
+ */
1058
+ private buildBulkFilter;
1037
1059
  bulkUpdate(req: IRequestContext): Promise<IControllerResponse<{
1038
1060
  matchedCount: number;
1039
1061
  modifiedCount: number;
@@ -1520,9 +1542,22 @@ interface ResourceConfig<TDoc = AnyRecord> {
1520
1542
  tenantField?: string | false;
1521
1543
  /**
1522
1544
  * Primary key field name (default: '_id').
1523
- * Override for non-MongoDB adapters (e.g., 'id' for SQL databases).
1545
+ *
1546
+ * Type-narrowed to `keyof TDoc` when `defineResource<TDoc>` is called with
1547
+ * a typed document interface — gives autocomplete for valid field names —
1548
+ * while still accepting any string when TDoc is `unknown` / `AnyRecord` so
1549
+ * adapters with dynamic shapes still work.
1550
+ *
1551
+ * @example
1552
+ * ```ts
1553
+ * defineResource<IJob>({ idField: 'jobId' }) // ← autocompletes from IJob fields
1554
+ * defineResource({ idField: 'sku' }) // ← any string allowed
1555
+ * ```
1556
+ *
1557
+ * Override for non-MongoDB adapters (e.g., 'id' for SQL databases) or
1558
+ * resources keyed by a business identifier (slug, sku, orderNumber).
1524
1559
  */
1525
- idField?: string;
1560
+ idField?: (keyof TDoc & string) | (string & {});
1526
1561
  module?: string;
1527
1562
  events?: Record<string, EventDefinition>;
1528
1563
  skipValidation?: boolean;
@@ -1558,6 +1593,34 @@ interface ResourceConfig<TDoc = AnyRecord> {
1558
1593
  * Requires `queryCachePlugin` to be registered.
1559
1594
  */
1560
1595
  cache?: ResourceCacheConfig;
1596
+ /**
1597
+ * Per-resource audit opt-in. When `auditPlugin` is registered with
1598
+ * `autoAudit: { perResource: true }`, only resources with this flag are audited.
1599
+ *
1600
+ * The cleanest pattern for apps where most resources don't need auditing —
1601
+ * no growing exclude lists, no centralized allowlist to maintain.
1602
+ *
1603
+ * - `true`: Audit create/update/delete on this resource
1604
+ * - `{ operations: ['delete'] }`: Audit only specific operations
1605
+ * - `false` or omit: Not audited (default)
1606
+ *
1607
+ * @example
1608
+ * ```ts
1609
+ * // app.ts
1610
+ * await fastify.register(auditPlugin, {
1611
+ * autoAudit: { perResource: true },
1612
+ * });
1613
+ *
1614
+ * // order.resource.ts
1615
+ * defineResource({ name: 'order', audit: true });
1616
+ *
1617
+ * // payment.resource.ts
1618
+ * defineResource({ name: 'payment', audit: { operations: ['delete'] } });
1619
+ * ```
1620
+ */
1621
+ audit?: boolean | {
1622
+ operations?: ("create" | "update" | "delete")[];
1623
+ };
1561
1624
  }
1562
1625
  /**
1563
1626
  * Resource-level permissions
@@ -2214,6 +2277,10 @@ interface RegistryEntry extends ResourceMetadata {
2214
2277
  disabledRoutes?: string[];
2215
2278
  /** Rate limit config */
2216
2279
  rateLimit?: RateLimitConfig | false;
2280
+ /** Per-resource audit opt-in flag (read by auditPlugin perResource mode) */
2281
+ audit?: boolean | {
2282
+ operations?: ("create" | "update" | "delete")[];
2283
+ };
2217
2284
  }
2218
2285
  interface RegistryStats {
2219
2286
  total?: number;
@@ -2332,9 +2399,15 @@ interface DataAdapter<TDoc = unknown> {
2332
2399
  * For example, Mongoose adapter can use mongokit to generate schemas from Mongoose models.
2333
2400
  *
2334
2401
  * @param options - Schema generation options (field rules, populate settings, etc.)
2402
+ * @param context - Resource-level context: idField (for params schema), resourceName.
2403
+ * Adapters should honor `context.idField` when producing the params
2404
+ * schema — e.g. skip the ObjectId pattern when idField is a custom
2405
+ * string field. Backwards compatible: legacy adapters ignoring the
2406
+ * context still work because Arc strips the mismatched pattern as
2407
+ * a safety net.
2335
2408
  * @returns OpenAPI schemas for CRUD operations or null if not supported
2336
2409
  */
2337
- generateSchemas?(options?: RouteSchemaOptions): OpenApiSchemas | Record<string, unknown> | null;
2410
+ generateSchemas?(options?: RouteSchemaOptions, context?: AdapterSchemaContext): OpenApiSchemas | Record<string, unknown> | null;
2338
2411
  /** Extract schema metadata for OpenAPI/introspection */
2339
2412
  getSchemaMetadata?(): SchemaMetadata | null;
2340
2413
  /** Validate data against schema before persistence */
@@ -2350,6 +2423,18 @@ interface DataAdapter<TDoc = unknown> {
2350
2423
  /** Close/cleanup resources */
2351
2424
  close?(): Promise<void>;
2352
2425
  }
2426
+ /**
2427
+ * Context passed to `adapter.generateSchemas()` so adapters can shape the
2428
+ * output to match resource-level configuration (idField overrides, etc).
2429
+ * All fields are optional — adapters are free to ignore this argument, in
2430
+ * which case Arc applies safety-net normalization to the generated schemas.
2431
+ */
2432
+ interface AdapterSchemaContext {
2433
+ /** The idField configured on the resource. Defaults to "_id". */
2434
+ idField?: string;
2435
+ /** Resource name (for error messages / logging). */
2436
+ resourceName?: string;
2437
+ }
2353
2438
  interface SchemaMetadata {
2354
2439
  name: string;
2355
2440
  fields: Record<string, FieldMetadata>;
@@ -2391,4 +2476,4 @@ interface ValidationResult {
2391
2476
  }
2392
2477
  type AdapterFactory<TDoc> = (config: unknown) => DataAdapter<TDoc>;
2393
2478
  //#endregion
2394
- export { RegistryEntry as $, PipelineStep as $t, GracefulShutdownOptions as A, AccessControlConfig as At, LookupOption as B, ResourceDefinition as Bt, CrudSchemas as C, BaseController as Ct, FastifyWithAuth as D, BodySanitizer as Dt, FastifyRequestExtras as E, QueryResolverConfig as Et, InferResourceDoc as F, IControllerResponse as Ft, OwnershipCheck as G, PaginationParams as Gt, MiddlewareHandler as H, CrudRepository as Ht, IntrospectionData as I, IRequestContext as It, PresetFunction as J, Interceptor as Jt, ParsedQuery as K, QueryOptions as Kt, IntrospectionPluginOptions as L, RouteHandler as Lt, HealthOptions as M, ControllerLike as Mt, InferAdapterDoc as N, FastifyHandler as Nt, FastifyWithDecorators as O, BodySanitizerConfig as Ot, InferDocType as P, IController as Pt, RateLimitConfig as Q, PipelineContext as Qt, JWTPayload as R, RegisterOptions as Rt, CrudRouterOptions as S, getUserId as St, EventsDecorator as T, QueryResolver as Tt, ObjectId as U, InferDoc as Ut, MiddlewareConfig as V, defineResource as Vt, OpenApiSchemas as W, PaginatedResult as Wt, PresetResult as X, OperationFilter as Xt, PresetHook as Y, NextFunction as Yt, QueryParserInterface as Z, PipelineConfig as Zt, AuthenticatorContext as _, UserLike as _t, RepositoryLike as a, HookPhase as an, ResourceConfig as at, CrudController as b, ValidationResult$1 as bt, AdditionalRoute as c, HookSystemOptions as cn, ResourceMetadata as ct, ArcDecorator as d, afterUpdate as dn, RouteSchemaOptions as dt, Transform as en, RegistryStats as et, ArcInternalMetadata as f, beforeCreate as fn, ServiceContext as ft, Authenticator as g, defineHook as gn, TypedResourceConfig as gt, AuthPluginOptions as h, createHookSystem as hn, TypedRepository as ht, RelationMetadata as i, HookOperation as in, ResourceCacheConfig as it, HealthCheck as j, ControllerHandler as jt, FieldRule as k, AccessControl as kt, AnyRecord as l, afterCreate as ln, ResourcePermissions as lt, AuthHelpers as m, beforeUpdate as mn, TypedController as mt, DataAdapter as n, HookContext as nn, RequestIdOptions as nt, SchemaMetadata as o, HookRegistration as on, ResourceHookContext as ot, ArcRequest as p, beforeDelete as pn, TokenPair as pt, PopulateOption as q, Guard as qt, FieldMetadata as r, HookHandler as rn, RequestWithExtras as rt, ValidationResult as s, HookSystem as sn, ResourceHooks as st, AdapterFactory as t, DefineHookOptions as tn, RequestContext as tt, ApiResponse as u, afterDelete as un, RouteHandlerMethod$1 as ut, ConfigError as v, UserOrganization as vt, EventDefinition as w, BaseControllerOptions as wt, CrudRouteKey as x, envelope as xt, ControllerQueryOptions as y, ValidateOptions as yt, JwtContext as z, ResourceRegistry as zt };
2479
+ export { RateLimitConfig as $, PipelineContext as $t, FieldRule as A, AccessControl as At, JwtContext as B, ResourceRegistry as Bt, CrudRouterOptions as C, getUserId as Ct, FastifyRequestExtras as D, QueryResolverConfig as Dt, EventsDecorator as E, QueryResolver as Et, InferDocType as F, IController as Ft, OpenApiSchemas as G, PaginatedResult as Gt, MiddlewareConfig as H, defineResource as Ht, InferResourceDoc as I, IControllerResponse as It, PopulateOption as J, Guard as Jt, OwnershipCheck as K, PaginationParams as Kt, IntrospectionData as L, IRequestContext as Lt, HealthCheck as M, ControllerHandler as Mt, HealthOptions as N, ControllerLike as Nt, FastifyWithAuth as O, BodySanitizer as Ot, InferAdapterDoc as P, FastifyHandler as Pt, QueryParserInterface as Q, PipelineConfig as Qt, IntrospectionPluginOptions as R, RouteHandler as Rt, CrudRouteKey as S, envelope as St, EventDefinition as T, BaseControllerOptions as Tt, MiddlewareHandler as U, CrudRepository as Ut, LookupOption as V, ResourceDefinition as Vt, ObjectId as W, InferDoc as Wt, PresetHook as X, NextFunction as Xt, PresetFunction as Y, Interceptor as Yt, PresetResult as Z, OperationFilter as Zt, Authenticator as _, defineHook as _n, TypedResourceConfig as _t, RelationMetadata as a, HookOperation as an, ResourceCacheConfig as at, ControllerQueryOptions as b, ValidateOptions as bt, ValidationResult as c, HookSystem as cn, ResourceHooks as ct, ApiResponse as d, afterDelete as dn, RouteHandlerMethod$1 as dt, PipelineStep as en, RegistryEntry as et, ArcDecorator as f, afterUpdate as fn, RouteSchemaOptions as ft, AuthPluginOptions as g, createHookSystem as gn, TypedRepository as gt, AuthHelpers as h, beforeUpdate as hn, TypedController as ht, FieldMetadata as i, HookHandler as in, RequestWithExtras as it, GracefulShutdownOptions as j, AccessControlConfig as jt, FastifyWithDecorators as k, BodySanitizerConfig as kt, AdditionalRoute as l, HookSystemOptions as ln, ResourceMetadata as lt, ArcRequest as m, beforeDelete as mn, TokenPair as mt, AdapterSchemaContext as n, DefineHookOptions as nn, RequestContext as nt, RepositoryLike as o, HookPhase as on, ResourceConfig as ot, ArcInternalMetadata as p, beforeCreate as pn, ServiceContext as pt, ParsedQuery as q, QueryOptions as qt, DataAdapter as r, HookContext as rn, RequestIdOptions as rt, SchemaMetadata as s, HookRegistration as sn, ResourceHookContext as st, AdapterFactory as t, Transform as tn, RegistryStats as tt, AnyRecord as u, afterCreate as un, ResourcePermissions as ut, AuthenticatorContext as v, UserLike as vt, CrudSchemas as w, BaseController as wt, CrudController as x, ValidationResult$1 as xt, ConfigError as y, UserOrganization as yt, JWTPayload as z, RegisterOptions as zt };
@@ -1,4 +1,4 @@
1
- import { Lt as RouteHandler } from "../interface-DDW43OmS.mjs";
1
+ import { Rt as RouteHandler } from "../interface-DYH8AXGe.mjs";
2
2
  import { i as UserBase } from "../types-BNUccdcf.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 { V as MiddlewareConfig, Y as PresetHook, c as AdditionalRoute, dt as RouteSchemaOptions, l as AnyRecord, sn as HookSystem, zt as ResourceRegistry } from "../interface-DDW43OmS.mjs";
1
+ import { Bt as ResourceRegistry, H as MiddlewareConfig, X as PresetHook, cn as HookSystem, ft as RouteSchemaOptions, l as AdditionalRoute, u as AnyRecord } from "../interface-DYH8AXGe.mjs";
2
2
  import { t as ExternalOpenApiPaths } from "../externalPaths-DpO-s7r8.mjs";
3
3
  import { _ as cachingPlugin, a as versioningPlugin, c as MetricsOptions, d as SSEOptions, f as _default$6, g as _default$1, h as CachingRule, i as _default$7, l as _default$4, m as CachingOptions, n as errorHandlerPlugin, o as MetricEntry, p as ssePlugin, r as VersioningOptions, s as MetricsCollector, t as ErrorHandlerOptions, u as metricsPlugin } from "../errorHandler-Do4vVQ1f.mjs";
4
4
  import { t as TracingOptions } from "../tracing-bz_U4EM1.mjs";
@@ -3,7 +3,7 @@ import { i as getOrgId } from "../types-BhtYdxZU.mjs";
3
3
  import { t as requestContext } from "../requestContext-DYtmNpm5.mjs";
4
4
  import { t as hasEvents } from "../typeGuards-Cj5Rgvlg.mjs";
5
5
  import { t as HookSystem } from "../HookSystem-COkyWztM.mjs";
6
- import { t as ResourceRegistry } from "../ResourceRegistry-DeCIFlix.mjs";
6
+ import { t as ResourceRegistry } from "../ResourceRegistry-C6ngvOnn.mjs";
7
7
  import { n as caching_default, t as cachingPlugin } from "../caching-BSXB-Xr7.mjs";
8
8
  import { t as errorHandlerPlugin } from "../errorHandler-r2595m8T.mjs";
9
9
  import { n as metrics_default, t as metricsPlugin } from "../metrics-Csh4nsvv.mjs";
@@ -44,7 +44,7 @@ try {
44
44
  function createTracerProvider(options) {
45
45
  if (!isAvailable) return null;
46
46
  const { serviceName = "@classytic/arc", serviceVersion, exporterUrl = "http://localhost:4318/v1/traces" } = options;
47
- const resolvedVersion = serviceVersion ?? "2.6.1";
47
+ const resolvedVersion = serviceVersion ?? "2.6.3";
48
48
  const exporter = new OTLPTraceExporter({ url: exporterUrl });
49
49
  const provider = new NodeTracerProvider({ resource: { attributes: {
50
50
  "service.name": serviceName,
@@ -1,4 +1,4 @@
1
- import { Ft as IControllerResponse, It as IRequestContext, Wt as PaginatedResult, X as PresetResult, at as ResourceConfig, l as AnyRecord } from "../interface-DDW43OmS.mjs";
1
+ import { Gt as PaginatedResult, It as IControllerResponse, Lt as IRequestContext, Z as PresetResult, ot as ResourceConfig, u as AnyRecord } from "../interface-DYH8AXGe.mjs";
2
2
  import { MultiTenantOptions, multiTenantPreset } from "./multiTenant.mjs";
3
3
 
4
4
  //#region src/presets/ownedByUser.d.ts
@@ -1,4 +1,4 @@
1
- import { X as PresetResult, x as CrudRouteKey } from "../interface-DDW43OmS.mjs";
1
+ import { S as CrudRouteKey, Z as PresetResult } from "../interface-DYH8AXGe.mjs";
2
2
 
3
3
  //#region src/presets/multiTenant.d.ts
4
4
  interface MultiTenantOptions {
@@ -1,4 +1,4 @@
1
- import { L as IntrospectionPluginOptions, Rt as RegisterOptions, zt as ResourceRegistry } from "../interface-DDW43OmS.mjs";
1
+ import { Bt as ResourceRegistry, R as IntrospectionPluginOptions, zt as RegisterOptions } from "../interface-DYH8AXGe.mjs";
2
2
  import { FastifyPluginAsync } from "fastify";
3
3
 
4
4
  //#region src/registry/introspectionPlugin.d.ts
@@ -1,3 +1,3 @@
1
1
  import { n as introspectionPlugin_default, t as introspectionPlugin } from "../registry-I-ogLgL9.mjs";
2
- import { t as ResourceRegistry } from "../ResourceRegistry-DeCIFlix.mjs";
2
+ import { t as ResourceRegistry } from "../ResourceRegistry-C6ngvOnn.mjs";
3
3
  export { ResourceRegistry, introspectionPlugin_default as introspectionPlugin, introspectionPlugin as introspectionPluginFn };