@classytic/arc 2.2.5 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import { a as RepositoryLike, i as RelationMetadata, n as DataAdapter, o as SchemaMetadata, r as FieldMetadata, s as ValidationResult, t as AdapterFactory } from "../interface-DZYNK9bb.mjs";
2
+ import { a as RepositoryLike, i as RelationMetadata, n as DataAdapter, o as SchemaMetadata, r as FieldMetadata, s as ValidationResult, t as AdapterFactory } from "../interface-BtdYtQUA.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
- import { a as PrismaQueryParserOptions, c as MongooseAdapterOptions, i as PrismaQueryParser, l as createMongooseAdapter, n as PrismaAdapterOptions, o as createPrismaAdapter, r as PrismaQueryOptions, s as MongooseAdapter, t as PrismaAdapter } from "../prisma-xjhMEq_S.mjs";
4
+ import { a as PrismaQueryParserOptions, c as MongooseAdapterOptions, i as PrismaQueryParser, l as createMongooseAdapter, n as PrismaAdapterOptions, o as createPrismaAdapter, r as PrismaQueryOptions, s as MongooseAdapter, t as PrismaAdapter } from "../prisma-Dy5S5F5i.mjs";
5
5
  export { type AdapterFactory, type DataAdapter, type FieldMetadata, MongooseAdapter, type MongooseAdapterOptions, PrismaAdapter, type PrismaAdapterOptions, type PrismaQueryOptions, PrismaQueryParser, type PrismaQueryParserOptions, type RelationMetadata, type RepositoryLike, type SchemaMetadata, type ValidationResult, createMongooseAdapter, createPrismaAdapter };
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import "../interface-DZYNK9bb.mjs";
2
+ import "../interface-BtdYtQUA.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
4
  import { a as AuditContext, c as AuditStore, i as AuditAction, l as AuditStoreOptions, n as MongoAuditStoreOptions, o as AuditEntry, r as MongoConnection, s as AuditQueryOptions, u as createAuditEntry } from "../mongodb-ClykrfGo.mjs";
5
5
  import { FastifyPluginAsync } from "fastify";
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import "../interface-DZYNK9bb.mjs";
2
+ import "../interface-BtdYtQUA.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
4
  import { n as MongoAuditStoreOptions, t as MongoAuditStore } from "../mongodb-ClykrfGo.mjs";
5
5
  export { MongoAuditStore, type MongoAuditStoreOptions };
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import "../interface-DZYNK9bb.mjs";
2
+ import "../interface-BtdYtQUA.mjs";
3
3
  import { t as PermissionCheck } from "../types-RLkFVgaw.mjs";
4
4
  import { AuthHelpers, AuthPluginOptions } from "../types/index.mjs";
5
5
  import { t as ExternalOpenApiPaths } from "../externalPaths-SyPF2tgK.mjs";
@@ -279,8 +279,7 @@ var ArcQueryParser = class {
279
279
  },
280
280
  _filterOperators: {
281
281
  type: "string",
282
- description: ["Available filter operators (use as field[operator]=value):", ...operatorLines].join("\n"),
283
- "x-internal": true
282
+ description: ["Available filter operators (use as field[operator]=value):", ...operatorLines].join("\n")
284
283
  }
285
284
  }
286
285
  };
@@ -485,7 +484,7 @@ function mutationResponse(itemSchema) {
485
484
  /**
486
485
  * Create a delete response schema
487
486
  *
488
- * Runtime format: { success, message }
487
+ * Runtime format: { success, data: { message, id?, soft? } }
489
488
  */
490
489
  function deleteResponse() {
491
490
  return {
@@ -495,9 +494,23 @@ function deleteResponse() {
495
494
  type: "boolean",
496
495
  example: true
497
496
  },
498
- message: {
499
- type: "string",
500
- example: "Deleted successfully"
497
+ data: {
498
+ type: "object",
499
+ properties: {
500
+ message: {
501
+ type: "string",
502
+ example: "Deleted successfully"
503
+ },
504
+ id: {
505
+ type: "string",
506
+ example: "507f1f77bcf86cd799439011"
507
+ },
508
+ soft: {
509
+ type: "boolean",
510
+ example: false
511
+ }
512
+ },
513
+ required: ["message"]
501
514
  }
502
515
  },
503
516
  required: ["success"],
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import { E as defineResource, T as ResourceDefinition, c as BaseController, d as QueryResolverConfig, f as BodySanitizer, h as AccessControlConfig, l as BaseControllerOptions, m as AccessControl, p as BodySanitizerConfig, u as QueryResolver } from "../interface-DZYNK9bb.mjs";
2
+ import { E as defineResource, T as ResourceDefinition, c as BaseController, d as QueryResolverConfig, f as BodySanitizer, h as AccessControlConfig, l as BaseControllerOptions, m as AccessControl, p as BodySanitizerConfig, u as QueryResolver } from "../interface-BtdYtQUA.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
- import { A as createCrudRouter, C as MutationOperation, D as ActionRouterConfig, E as ActionHandler, O as IdempotencyService, S as MUTATION_OPERATIONS, T as SYSTEM_FIELDS, _ as HookOperation, a as getControllerScope, b as MAX_REGEX_LENGTH, c as CrudOperation, d as DEFAULT_MAX_LIMIT, f as DEFAULT_SORT, g as HOOK_PHASES, h as HOOK_OPERATIONS, i as getControllerContext, j as createPermissionMiddleware, k as createActionRouter, l as DEFAULT_ID_FIELD, m as DEFAULT_UPDATE_METHOD, n as createFastifyHandler, o as sendControllerResponse, p as DEFAULT_TENANT_FIELD, r as createRequestContext, s as CRUD_OPERATIONS, t as createCrudHandlers, u as DEFAULT_LIMIT, v as HookPhase, w as RESERVED_QUERY_PARAMS, x as MAX_SEARCH_LENGTH, y as MAX_FILTER_DEPTH } from "../fastifyAdapter-CyAA2zlB.mjs";
4
+ import { A as createCrudRouter, C as MutationOperation, D as ActionRouterConfig, E as ActionHandler, O as IdempotencyService, S as MUTATION_OPERATIONS, T as SYSTEM_FIELDS, _ as HookOperation, a as getControllerScope, b as MAX_REGEX_LENGTH, c as CrudOperation, d as DEFAULT_MAX_LIMIT, f as DEFAULT_SORT, g as HOOK_PHASES, h as HOOK_OPERATIONS, i as getControllerContext, j as createPermissionMiddleware, k as createActionRouter, l as DEFAULT_ID_FIELD, m as DEFAULT_UPDATE_METHOD, n as createFastifyHandler, o as sendControllerResponse, p as DEFAULT_TENANT_FIELD, r as createRequestContext, s as CRUD_OPERATIONS, t as createCrudHandlers, u as DEFAULT_LIMIT, v as HookPhase, w as RESERVED_QUERY_PARAMS, x as MAX_SEARCH_LENGTH, y as MAX_FILTER_DEPTH } from "../fastifyAdapter-6b_eRDBw.mjs";
5
5
  export { AccessControl, type AccessControlConfig, type ActionHandler, type ActionRouterConfig, BaseController, type BaseControllerOptions, BodySanitizer, type BodySanitizerConfig, 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, type IdempotencyService, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, MutationOperation, QueryResolver, type QueryResolverConfig, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, createActionRouter, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineResource, getControllerContext, getControllerScope, sendControllerResponse };
@@ -1,4 +1,4 @@
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-DdXFXQtN.mjs";
2
- import { _ as QueryResolver, c as createPermissionMiddleware, d as createFastifyHandler, f as createRequestContext, g as BaseController, h as sendControllerResponse, m as getControllerScope, n as defineResource, o as createActionRouter, p as getControllerContext, s as createCrudRouter, t as ResourceDefinition, u as createCrudHandlers, v as BodySanitizer, y as AccessControl } from "../defineResource-DO9ONe_D.mjs";
2
+ import { _ as QueryResolver, c as createPermissionMiddleware, d as createFastifyHandler, f as createRequestContext, g as BaseController, h as sendControllerResponse, m as getControllerScope, n as defineResource, o as createActionRouter, p as getControllerContext, s as createCrudRouter, t as ResourceDefinition, u as createCrudHandlers, v as BodySanitizer, y as AccessControl } from "../defineResource-DWbpJYtm.mjs";
3
3
 
4
4
  export { AccessControl, BaseController, BodySanitizer, CRUD_OPERATIONS, DEFAULT_ID_FIELD, DEFAULT_LIMIT, DEFAULT_MAX_LIMIT, DEFAULT_SORT, DEFAULT_TENANT_FIELD, DEFAULT_UPDATE_METHOD, HOOK_OPERATIONS, HOOK_PHASES, MAX_FILTER_DEPTH, MAX_REGEX_LENGTH, MAX_SEARCH_LENGTH, MUTATION_OPERATIONS, QueryResolver, RESERVED_QUERY_PARAMS, ResourceDefinition, SYSTEM_FIELDS, createActionRouter, createCrudHandlers, createCrudRouter, createFastifyHandler, createPermissionMiddleware, createRequestContext, defineResource, getControllerContext, getControllerScope, sendControllerResponse };
@@ -315,7 +315,7 @@ async function createApp(options) {
315
315
  coerceTypes: true,
316
316
  useDefaults: true,
317
317
  removeAdditional: false,
318
- keywords: ["example"]
318
+ keywords: ["example", ...config.ajv?.keywords ?? []]
319
319
  } }
320
320
  });
321
321
  if (config.typeProvider === "typebox") try {
@@ -3,7 +3,7 @@ import { c as isElevated, l as isMember, n as PUBLIC_SCOPE, r as getOrgId } from
3
3
  import { getUserId } from "./types/index.mjs";
4
4
  import { i as resolveEffectiveRoles, n as applyFieldWritePermissions, t as applyFieldReadPermissions } from "./fields-CTd_CrKr.mjs";
5
5
  import { t as getUserRoles } from "./types-DelU6kln.mjs";
6
- import { C as ArcQueryParser, u as getDefaultCrudSchemas } from "./circuitBreaker-DYhWBW_D.mjs";
6
+ import { C as ArcQueryParser, u as getDefaultCrudSchemas } from "./circuitBreaker-CSS2VvL6.mjs";
7
7
  import { t as buildQueryKey } from "./keys-DhqDRxv3.mjs";
8
8
  import { r as ForbiddenError } from "./errors-DBANPbGr.mjs";
9
9
  import { t as hasEvents } from "./typeGuards-DwxA1t_L.mjs";
@@ -782,9 +782,14 @@ var BaseController = class {
782
782
  context: arcContext,
783
783
  meta: { id }
784
784
  });
785
+ const deleteResult = typeof result === "object" && result !== null ? result : {};
785
786
  return {
786
787
  success: true,
787
- data: { message: "Deleted successfully" },
788
+ data: {
789
+ message: deleteResult.message || "Deleted successfully",
790
+ ...id ? { id } : {},
791
+ ...deleteResult.soft ? { soft: true } : {}
792
+ },
788
793
  status: 200
789
794
  };
790
795
  }
@@ -1981,19 +1986,28 @@ function defineResource(config) {
1981
1986
  const resolvedConfig = config.presets?.length ? applyPresets(config, config.presets) : config;
1982
1987
  resolvedConfig._appliedPresets = originalPresets;
1983
1988
  let controller = resolvedConfig.controller;
1984
- if (!controller && hasCrudRoutes && repository) controller = new BaseController(repository, {
1985
- resourceName: resolvedConfig.name,
1986
- schemaOptions: resolvedConfig.schemaOptions,
1987
- queryParser: resolvedConfig.queryParser,
1988
- tenantField: resolvedConfig.tenantField,
1989
- idField: resolvedConfig.idField,
1990
- matchesFilter: config.adapter?.matchesFilter,
1991
- cache: resolvedConfig.cache,
1992
- presetFields: resolvedConfig._controllerOptions ? {
1993
- slugField: resolvedConfig._controllerOptions.slugField,
1994
- parentField: resolvedConfig._controllerOptions.parentField
1995
- } : void 0
1996
- });
1989
+ if (!controller && hasCrudRoutes && repository) {
1990
+ const qp = resolvedConfig.queryParser;
1991
+ let maxLimitFromParser;
1992
+ if (qp?.getQuerySchema) {
1993
+ const limitProp = qp.getQuerySchema()?.properties?.limit;
1994
+ if (limitProp?.maximum) maxLimitFromParser = limitProp.maximum;
1995
+ }
1996
+ controller = new BaseController(repository, {
1997
+ resourceName: resolvedConfig.name,
1998
+ schemaOptions: resolvedConfig.schemaOptions,
1999
+ queryParser: resolvedConfig.queryParser,
2000
+ maxLimit: maxLimitFromParser,
2001
+ tenantField: resolvedConfig.tenantField,
2002
+ idField: resolvedConfig.idField,
2003
+ matchesFilter: config.adapter?.matchesFilter,
2004
+ cache: resolvedConfig.cache,
2005
+ presetFields: resolvedConfig._controllerOptions ? {
2006
+ slugField: resolvedConfig._controllerOptions.slugField,
2007
+ parentField: resolvedConfig._controllerOptions.parentField
2008
+ } : void 0
2009
+ });
2010
+ }
1997
2011
  const resource = new ResourceDefinition({
1998
2012
  ...resolvedConfig,
1999
2013
  adapter: config.adapter,
@@ -2138,6 +2152,30 @@ var ResourceDefinition = class {
2138
2152
  schemas[key] = schemas[key] ? deepMergeSchemas(schemas[key], converted) : converted;
2139
2153
  }
2140
2154
  }
2155
+ const listQuerySchema = self._registryMeta?.openApiSchemas?.listQuery;
2156
+ if (listQuerySchema) {
2157
+ const FLEXIBLE_PARAMS = [
2158
+ "populate",
2159
+ "select",
2160
+ "lookup",
2161
+ "aggregate"
2162
+ ];
2163
+ const props = listQuerySchema.properties;
2164
+ const normalizedProps = props ? { ...props } : void 0;
2165
+ if (normalizedProps) {
2166
+ for (const key of FLEXIBLE_PARAMS) if (normalizedProps[key] && typeof normalizedProps[key] === "object") {
2167
+ const { type: _type, ...rest } = normalizedProps[key];
2168
+ normalizedProps[key] = rest;
2169
+ }
2170
+ }
2171
+ const normalizedSchema = {
2172
+ ...listQuerySchema,
2173
+ ...normalizedProps ? { properties: normalizedProps } : {},
2174
+ additionalProperties: listQuerySchema.additionalProperties ?? true
2175
+ };
2176
+ schemas = schemas ?? {};
2177
+ schemas.list = schemas.list ? deepMergeSchemas({ querystring: normalizedSchema }, schemas.list) : { querystring: normalizedSchema };
2178
+ }
2141
2179
  const resolvedRoutes = self.additionalRoutes;
2142
2180
  createCrudRouter(typedInstance, self.controller, {
2143
2181
  tag: self.tag,
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import "../interface-DZYNK9bb.mjs";
2
+ import "../interface-BtdYtQUA.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
4
  import { RegistryEntry } from "../types/index.mjs";
5
5
  import { t as ExternalOpenApiPaths } from "../externalPaths-SyPF2tgK.mjs";
@@ -1,10 +1,10 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import "../interface-DZYNK9bb.mjs";
2
+ import "../interface-BtdYtQUA.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
4
  import "../queryCachePlugin-Q6SYuHZ6.mjs";
5
5
  import "../eventPlugin-H6wDDjGO.mjs";
6
6
  import "../errorHandler-CW3OOeYq.mjs";
7
- import { a as CustomPluginAuthOption, c as RawBodyOptions, i as CustomAuthenticatorOption, l as UnderPressureOptions, n as BetterAuthOption, o as JwtAuthOption, r as CreateAppOptions, s as MultipartOptions, t as AuthOption } from "../types-DMSBMkaZ.mjs";
7
+ import { a as CustomPluginAuthOption, c as RawBodyOptions, i as CustomAuthenticatorOption, l as UnderPressureOptions, n as BetterAuthOption, o as JwtAuthOption, r as CreateAppOptions, s as MultipartOptions, t as AuthOption } from "../types-tKwaViYB.mjs";
8
8
  import { FastifyInstance } from "fastify";
9
9
 
10
10
  //#region src/factory/createApp.d.ts
@@ -1,3 +1,3 @@
1
- import { a as getPreset, i as developmentPreset, n as createApp, o as productionPreset, s as testingPreset, t as ArcFactory } from "../createApp-BKHSl2nT.mjs";
1
+ import { a as getPreset, i as developmentPreset, n as createApp, o as productionPreset, s as testingPreset, t as ArcFactory } from "../createApp-CgKOPhA4.mjs";
2
2
 
3
3
  export { ArcFactory, createApp, developmentPreset, getPreset, productionPreset, testingPreset };
@@ -1,5 +1,5 @@
1
1
  import { s as RequestScope } from "./elevation-DGo5shaX.mjs";
2
- import { b as IControllerResponse, x as IRequestContext, y as IController } from "./interface-DZYNK9bb.mjs";
2
+ import { b as IControllerResponse, x as IRequestContext, y as IController } from "./interface-BtdYtQUA.mjs";
3
3
  import { t as PermissionCheck } from "./types-RLkFVgaw.mjs";
4
4
  import { CrudController, CrudRouterOptions, FastifyWithDecorators, RequestContext, RequestWithExtras } from "./types/index.mjs";
5
5
  import { FastifyInstance, FastifyReply, FastifyRequest, RouteHandlerMethod } from "fastify";
@@ -1,4 +1,4 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import { $ as beforeUpdate, B as DefineHookOptions, G as HookRegistration, H as HookHandler, J as afterCreate, K as HookSystem, Q as beforeDelete, U as HookOperation, V as HookContext, W as HookPhase, X as afterUpdate, Y as afterDelete, Z as beforeCreate, et as createHookSystem, q as HookSystemOptions, tt as defineHook } from "../interface-DZYNK9bb.mjs";
2
+ import { $ as beforeUpdate, B as DefineHookOptions, G as HookRegistration, H as HookHandler, J as afterCreate, K as HookSystem, Q as beforeDelete, U as HookOperation, V as HookContext, W as HookPhase, X as afterUpdate, Y as afterDelete, Z as beforeCreate, et as createHookSystem, q as HookSystemOptions, tt as defineHook } from "../interface-BtdYtQUA.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
4
  export { type DefineHookOptions, type HookContext, type HookHandler, type HookOperation, type HookPhase, type HookRegistration, HookSystem, type HookSystemOptions, afterCreate, afterDelete, afterUpdate, beforeCreate, beforeDelete, beforeUpdate, createHookSystem, defineHook };
package/dist/index.d.mts CHANGED
@@ -1,11 +1,11 @@
1
1
  import "./elevation-DGo5shaX.mjs";
2
- import { D as CrudRepository, E as defineResource, F as OperationFilter, I as PipelineConfig, L as PipelineContext, M as Guard, N as Interceptor, P as NextFunction, R as PipelineStep, S as RouteHandler, T as ResourceDefinition, _ as ControllerLike, a as RepositoryLike, b as IControllerResponse, c as BaseController, i as RelationMetadata, j as QueryOptions, k as PaginatedResult, l as BaseControllerOptions, n as DataAdapter, o as SchemaMetadata, r as FieldMetadata, s as ValidationResult, x as IRequestContext, y as IController, z as Transform } from "./interface-DZYNK9bb.mjs";
2
+ import { D as CrudRepository, E as defineResource, F as OperationFilter, I as PipelineConfig, L as PipelineContext, M as Guard, N as Interceptor, P as NextFunction, R as PipelineStep, S as RouteHandler, T as ResourceDefinition, _ as ControllerLike, a as RepositoryLike, b as IControllerResponse, c as BaseController, i as RelationMetadata, j as QueryOptions, k as PaginatedResult, l as BaseControllerOptions, n as DataAdapter, o as SchemaMetadata, r as FieldMetadata, s as ValidationResult, x as IRequestContext, y as IController, z as Transform } from "./interface-BtdYtQUA.mjs";
3
3
  import { a as applyFieldWritePermissions, i as applyFieldReadPermissions, n as FieldPermissionMap, o as fields, t as FieldPermission } from "./fields-Bi_AVKSo.mjs";
4
4
  import { i as UserBase, n as PermissionContext, r as PermissionResult, t as PermissionCheck } from "./types-RLkFVgaw.mjs";
5
5
  import { AdditionalRoute, AnyRecord, ApiResponse, ArcInternalMetadata, AuthPluginOptions, ConfigError, CrudController, CrudRouteKey, CrudRouterOptions, CrudSchemas, EventDefinition, FastifyRequestExtras, FastifyWithAuth, FastifyWithDecorators, FieldRule, GracefulShutdownOptions, HealthCheck, HealthOptions, InferAdapterDoc, InferDocType, InferResourceDoc, IntrospectionData, IntrospectionPluginOptions, JWTPayload, MiddlewareConfig, MiddlewareHandler, OwnershipCheck, PresetFunction, PresetResult, RateLimitConfig, RegistryEntry, RegistryStats, RequestContext, RequestIdOptions, RequestWithExtras, ResourceConfig, ResourceMetadata, RouteHandlerMethod, RouteSchemaOptions, ServiceContext, TypedController, TypedRepository, TypedResourceConfig, UserOrganization, ValidateOptions, ValidationResult as ValidationResult$1 } from "./types/index.mjs";
6
- import { c as MongooseAdapterOptions, l as createMongooseAdapter, n as PrismaAdapterOptions, o as createPrismaAdapter, s as MongooseAdapter, t as PrismaAdapter } from "./prisma-xjhMEq_S.mjs";
6
+ import { c as MongooseAdapterOptions, l as createMongooseAdapter, n as PrismaAdapterOptions, o as createPrismaAdapter, s as MongooseAdapter, t as PrismaAdapter } from "./prisma-Dy5S5F5i.mjs";
7
7
  import "./adapters/index.mjs";
8
- import { C as MutationOperation, S as MUTATION_OPERATIONS, T as SYSTEM_FIELDS, _ as HookOperation, a as getControllerScope, b as MAX_REGEX_LENGTH, c as CrudOperation, d as DEFAULT_MAX_LIMIT, f as DEFAULT_SORT, g as HOOK_PHASES, h as HOOK_OPERATIONS, l as DEFAULT_ID_FIELD, m as DEFAULT_UPDATE_METHOD, p as DEFAULT_TENANT_FIELD, s as CRUD_OPERATIONS, u as DEFAULT_LIMIT, v as HookPhase, w as RESERVED_QUERY_PARAMS, x as MAX_SEARCH_LENGTH, y as MAX_FILTER_DEPTH } from "./fastifyAdapter-CyAA2zlB.mjs";
8
+ import { C as MutationOperation, S as MUTATION_OPERATIONS, T as SYSTEM_FIELDS, _ as HookOperation, a as getControllerScope, b as MAX_REGEX_LENGTH, c as CrudOperation, d as DEFAULT_MAX_LIMIT, f as DEFAULT_SORT, g as HOOK_PHASES, h as HOOK_OPERATIONS, l as DEFAULT_ID_FIELD, m as DEFAULT_UPDATE_METHOD, p as DEFAULT_TENANT_FIELD, s as CRUD_OPERATIONS, u as DEFAULT_LIMIT, v as HookPhase, w as RESERVED_QUERY_PARAMS, x as MAX_SEARCH_LENGTH, y as MAX_FILTER_DEPTH } from "./fastifyAdapter-6b_eRDBw.mjs";
9
9
  import "./core/index.mjs";
10
10
  import { a as NotFoundError, d as ValidationError, i as ForbiddenError, t as ArcError, u as UnauthorizedError } from "./errors-DAWRdiYP.mjs";
11
11
  import { a as presets_d_exports, c as readOnly, i as ownerWithAdminBypass, n as authenticated, o as publicRead, r as fullPublic, s as publicReadAdminWrite, t as adminOnly } from "./presets-BTeYbw7h.mjs";
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
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-DdXFXQtN.mjs";
2
2
  import { a as createMongooseAdapter, i as MongooseAdapter, r as createPrismaAdapter, t as PrismaAdapter } from "./prisma-DJbMt3yf.mjs";
3
- import { a as validateResourceConfig, g as BaseController, i as formatValidationErrors, l as pipe, m as getControllerScope, n as defineResource, r as assertValidConfig, t as ResourceDefinition } from "./defineResource-DO9ONe_D.mjs";
3
+ import { a as validateResourceConfig, g as BaseController, i as formatValidationErrors, l as pipe, m as getControllerScope, n as defineResource, r as assertValidConfig, t as ResourceDefinition } from "./defineResource-DWbpJYtm.mjs";
4
4
  import { n as applyFieldWritePermissions, r as fields, t as applyFieldReadPermissions } from "./fields-CTd_CrKr.mjs";
5
5
  import { i as NotFoundError, l as UnauthorizedError, r as ForbiddenError, t as ArcError, u as ValidationError } from "./errors-DBANPbGr.mjs";
6
6
  import { t as requestContext } from "./requestContext-xi6OKBL-.mjs";
@@ -1010,6 +1010,8 @@ declare class BaseController<TDoc = AnyRecord, TRepository extends RepositoryLik
1010
1010
  update(req: IRequestContext): Promise<IControllerResponse<TDoc>>;
1011
1011
  delete(req: IRequestContext): Promise<IControllerResponse<{
1012
1012
  message: string;
1013
+ id?: string;
1014
+ soft?: boolean;
1013
1015
  }>>;
1014
1016
  getBySlug(req: IRequestContext): Promise<IControllerResponse<TDoc>>;
1015
1017
  getDeleted(req: IRequestContext): Promise<IControllerResponse<PaginatedResult<TDoc>>>;
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import { S as RouteHandler } from "../interface-DZYNK9bb.mjs";
2
+ import { S as RouteHandler } from "../interface-BtdYtQUA.mjs";
3
3
  import { i as UserBase } from "../types-RLkFVgaw.mjs";
4
4
  import "../types/index.mjs";
5
5
  import { InvitationAdapter, InvitationDoc, MemberDoc, OrgAdapter, OrgDoc, OrgPermissionStatement, OrgRole, OrganizationPluginOptions } from "./types.mjs";
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import { K as HookSystem, w as ResourceRegistry } from "../interface-DZYNK9bb.mjs";
2
+ import { K as HookSystem, w as ResourceRegistry } from "../interface-BtdYtQUA.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
4
  import { AdditionalRoute, AnyRecord, MiddlewareConfig, PresetHook, RouteSchemaOptions } from "../types/index.mjs";
5
5
  import { t as ExternalOpenApiPaths } from "../externalPaths-SyPF2tgK.mjs";
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import { b as IControllerResponse, k as PaginatedResult, x as IRequestContext } from "../interface-DZYNK9bb.mjs";
2
+ import { b as IControllerResponse, k as PaginatedResult, x as IRequestContext } from "../interface-BtdYtQUA.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
4
  import { AnyRecord, PresetResult, ResourceConfig } from "../types/index.mjs";
5
5
  import multiTenantPreset, { MultiTenantOptions } from "./multiTenant.mjs";
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import "../interface-DZYNK9bb.mjs";
2
+ import "../interface-BtdYtQUA.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
4
  import { CrudRouteKey, PresetResult } from "../types/index.mjs";
5
5
 
@@ -1,4 +1,4 @@
1
- import { D as CrudRepository, a as RepositoryLike, n as DataAdapter, o as SchemaMetadata, s as ValidationResult } from "./interface-DZYNK9bb.mjs";
1
+ import { D as CrudRepository, a as RepositoryLike, n as DataAdapter, o as SchemaMetadata, s as ValidationResult } from "./interface-BtdYtQUA.mjs";
2
2
  import { OpenApiSchemas, ParsedQuery, QueryParserInterface, RouteSchemaOptions } from "./types/index.mjs";
3
3
  import { Model } from "mongoose";
4
4
 
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import { C as RegisterOptions, w as ResourceRegistry } from "../interface-DZYNK9bb.mjs";
2
+ import { C as RegisterOptions, w as ResourceRegistry } from "../interface-BtdYtQUA.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
4
  import { IntrospectionPluginOptions } from "../types/index.mjs";
5
5
  import { FastifyPluginAsync } from "fastify";
@@ -57,7 +57,7 @@ declare function ArcPaginationQuery(): _sinclair_typebox0.TObject<{
57
57
  limit: _sinclair_typebox0.TOptional<_sinclair_typebox0.TInteger>;
58
58
  sort: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
59
59
  select: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
60
- populate: _sinclair_typebox0.TOptional<_sinclair_typebox0.TString>;
60
+ populate: _sinclair_typebox0.TOptional<_sinclair_typebox0.TAny>;
61
61
  }>;
62
62
  //#endregion
63
63
  export { ArcDeleteResponse, ArcErrorResponse, ArcItemResponse, ArcListResponse, ArcMutationResponse, ArcPaginationQuery, type FastifyPluginAsyncTypebox, type FastifyPluginCallbackTypebox, type Static, type TObject, type TSchema, Type, type TypeBoxTypeProvider, TypeBoxValidatorCompiler };
@@ -74,8 +74,8 @@ function ArcPaginationQuery() {
74
74
  })),
75
75
  sort: Type$1.Optional(Type$1.String()),
76
76
  select: Type$1.Optional(Type$1.String()),
77
- populate: Type$1.Optional(Type$1.String())
78
- });
77
+ populate: Type$1.Optional(Type$1.Any())
78
+ }, { additionalProperties: true });
79
79
  }
80
80
 
81
81
  //#endregion
@@ -1,11 +1,11 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import { D as CrudRepository, T as ResourceDefinition } from "../interface-DZYNK9bb.mjs";
2
+ import { D as CrudRepository, T as ResourceDefinition } from "../interface-BtdYtQUA.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
4
  import { AnyRecord } from "../types/index.mjs";
5
5
  import "../queryCachePlugin-Q6SYuHZ6.mjs";
6
6
  import "../eventPlugin-H6wDDjGO.mjs";
7
7
  import "../errorHandler-CW3OOeYq.mjs";
8
- import { r as CreateAppOptions } from "../types-DMSBMkaZ.mjs";
8
+ import { r as CreateAppOptions } from "../types-tKwaViYB.mjs";
9
9
  import Fastify, { FastifyInstance } from "fastify";
10
10
  import { Mock } from "vitest";
11
11
  import { Connection } from "mongoose";
@@ -1000,7 +1000,7 @@ var DatabaseSnapshot = class {
1000
1000
  * ```
1001
1001
  */
1002
1002
  async function createTestApp(options = {}) {
1003
- const { createApp } = await import("../createApp-BKHSl2nT.mjs").then((n) => n.r);
1003
+ const { createApp } = await import("../createApp-CgKOPhA4.mjs").then((n) => n.r);
1004
1004
  const { useInMemoryDb = true, mongoUri: providedMongoUri, ...appOptions } = options;
1005
1005
  const defaultAuth = {
1006
1006
  type: "jwt",
@@ -1,5 +1,5 @@
1
1
  import { a as AUTHENTICATED_SCOPE, c as getOrgId, d as hasOrgAccess, f as isAuthenticated, l as getOrgRoles, m as isMember, n as ElevationOptions, o as PUBLIC_SCOPE, p as isElevated, s as RequestScope, t as ElevationEvent, u as getTeamId } from "../elevation-DGo5shaX.mjs";
2
- import { A as PaginationParams, D as CrudRepository, I as PipelineConfig, K as HookSystem, O as InferDoc, S as RouteHandler, _ as ControllerLike, b as IControllerResponse, g as ControllerHandler, j as QueryOptions, k as PaginatedResult, l as BaseControllerOptions, n as DataAdapter, v as FastifyHandler, w as ResourceRegistry, x as IRequestContext, y as IController } from "../interface-DZYNK9bb.mjs";
2
+ import { A as PaginationParams, D as CrudRepository, I as PipelineConfig, K as HookSystem, O as InferDoc, S as RouteHandler, _ as ControllerLike, b as IControllerResponse, g as ControllerHandler, j as QueryOptions, k as PaginatedResult, l as BaseControllerOptions, n as DataAdapter, v as FastifyHandler, w as ResourceRegistry, x as IRequestContext, y as IController } from "../interface-BtdYtQUA.mjs";
3
3
  import { n as FieldPermissionMap } from "../fields-Bi_AVKSo.mjs";
4
4
  import { i as UserBase, n as PermissionContext, r as PermissionResult, t as PermissionCheck } from "../types-RLkFVgaw.mjs";
5
5
  import { FastifyInstance, FastifyReply, FastifyRequest, RouteHandlerMethod, RouteHandlerMethod as RouteHandlerMethod$1 } from "fastify";
@@ -423,6 +423,23 @@ interface CreateAppOptions {
423
423
  * Set to false to disable, or pass ErrorHandlerOptions for fine control.
424
424
  */
425
425
  errorHandler?: ErrorHandlerOptions | false;
426
+ /**
427
+ * Custom AJV keywords to allow in route schemas.
428
+ *
429
+ * Arc already allows `"example"` by default. Use this to add
430
+ * additional non-standard keywords your query parsers or schema
431
+ * generators may use (e.g., `x-internal` from MongoKit).
432
+ *
433
+ * @example
434
+ * ```typescript
435
+ * const app = await createApp({
436
+ * ajv: { keywords: ['x-internal'] },
437
+ * });
438
+ * ```
439
+ */
440
+ ajv?: {
441
+ keywords?: string[];
442
+ };
426
443
  /** Custom plugin registration function */
427
444
  plugins?: (fastify: FastifyInstance) => Promise<void>;
428
445
  /** Hook called after all plugins are loaded and the app is ready */
@@ -1,5 +1,5 @@
1
1
  import "../elevation-DGo5shaX.mjs";
2
- import "../interface-DZYNK9bb.mjs";
2
+ import "../interface-BtdYtQUA.mjs";
3
3
  import "../types-RLkFVgaw.mjs";
4
4
  import { AnyRecord, OpenApiSchemas, ParsedQuery, QueryParserInterface } from "../types/index.mjs";
5
5
  import { a as NotFoundError, c as RateLimitError, d as ValidationError, f as createError, i as ForbiddenError, l as ServiceUnavailableError, n as ConflictError, o as OrgAccessDeniedError, p as isArcError, r as ErrorDetails, s as OrgRequiredError, t as ArcError, u as UnauthorizedError } from "../errors-DAWRdiYP.mjs";
@@ -65,7 +65,7 @@ declare function mutationResponse(itemSchema: JsonSchema): JsonSchema;
65
65
  /**
66
66
  * Create a delete response schema
67
67
  *
68
- * Runtime format: { success, message }
68
+ * Runtime format: { success, data: { message, id?, soft? } }
69
69
  */
70
70
  declare function deleteResponse(): JsonSchema;
71
71
  /**
@@ -1,4 +1,4 @@
1
- import { C as ArcQueryParser, S as wrapResponse, _ as paginateWrapper, a as createCircuitBreaker, b as responses, c as deleteResponse, d as getListQueryParams, f as itemResponse, g as mutationResponse, h as messageWrapper, i as CircuitState, l as errorResponseSchema, m as listResponse, n as CircuitBreakerError, o as createCircuitBreakerRegistry, p as itemWrapper, r as CircuitBreakerRegistry, s as createStateMachine, t as CircuitBreaker, u as getDefaultCrudSchemas, v as paginationSchema, w as createQueryParser, x as successResponseSchema, y as queryParams } from "../circuitBreaker-DYhWBW_D.mjs";
1
+ import { C as ArcQueryParser, S as wrapResponse, _ as paginateWrapper, a as createCircuitBreaker, b as responses, c as deleteResponse, d as getListQueryParams, f as itemResponse, g as mutationResponse, h as messageWrapper, i as CircuitState, l as errorResponseSchema, m as listResponse, n as CircuitBreakerError, o as createCircuitBreakerRegistry, p as itemWrapper, r as CircuitBreakerRegistry, s as createStateMachine, t as CircuitBreaker, u as getDefaultCrudSchemas, v as paginationSchema, w as createQueryParser, x as successResponseSchema, y as queryParams } from "../circuitBreaker-CSS2VvL6.mjs";
2
2
  import { a as OrgAccessDeniedError, c as ServiceUnavailableError, d as createError, f as isArcError, i as NotFoundError, l as UnauthorizedError, n as ConflictError, o as OrgRequiredError, r as ForbiddenError, s as RateLimitError, t as ArcError, u as ValidationError } from "../errors-DBANPbGr.mjs";
3
3
  import { t as hasEvents } from "../typeGuards-DwxA1t_L.mjs";
4
4
  import { a as toJsonSchema, i as isZodSchema, n as convertRouteSchema, r as isJsonSchema, t as convertOpenApiSchemas } from "../schemaConverter-Dtg0Kt9T.mjs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classytic/arc",
3
- "version": "2.2.5",
3
+ "version": "2.3.0",
4
4
  "description": "Resource-oriented backend framework for Fastify — clean, minimal, powerful, tree-shakable",
5
5
  "type": "module",
6
6
  "exports": {
@@ -191,7 +191,7 @@
191
191
  "node": ">=22"
192
192
  },
193
193
  "peerDependencies": {
194
- "@classytic/mongokit": "^3.2.4",
194
+ "@classytic/mongokit": ">=3.3.2",
195
195
  "@classytic/streamline": ">=1.0.0",
196
196
  "@fastify/cors": "^11.0.0",
197
197
  "@fastify/helmet": "^13.0.0",
@@ -304,11 +304,11 @@
304
304
  "qs": "^6.14.1"
305
305
  },
306
306
  "devDependencies": {
307
- "@classytic/mongokit": "^3.2.3",
307
+ "@classytic/mongokit": "^3.3.2",
308
308
  "@fastify/jwt": "^10.0.0",
309
309
  "@fastify/multipart": "^9.0.0",
310
- "@fastify/websocket": "^11.0.0",
311
310
  "@fastify/type-provider-typebox": "^6.0.0",
311
+ "@fastify/websocket": "^11.0.0",
312
312
  "@sinclair/typebox": "^0.34.0",
313
313
  "@types/node": "^22.10.0",
314
314
  "@types/qs": "^6.14.0",
@@ -346,4 +346,4 @@
346
346
  "type": "git",
347
347
  "url": "https://github.com/classytic/arc.git"
348
348
  }
349
- }
349
+ }