@web-ts-toolkit/access-router 0.46.0 → 0.47.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.
package/advanced.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as AccessRouterBaseRequest, a as AccessRouterFieldKey, b as AccessRouterLogger, c as AccessRouterRequest, d as AccessRouterRequestExtensions, e as AdvancedCreateBody, f as AdvancedListBody, g as AdvancedReadBody, h as AdvancedReadFilterBody, i as AdvancedUpdateBody, j as AdvancedUpsertBody, k as AfterPersistAccess, l as AjvErrorObjectLike, m as AjvValidationErrorLike, n as AjvValidatorLike, o as ArkTypeErrorsLike, p as ArkTypeLike, q as ArkTypeProblemLike, B as BaseFilterAccess, C as Change, r as Codes, s as CorrelatedCountInclude, t as CorrelatedFilter, u as CorrelatedInclude, v as CorrelatedIncludeArgs, w as CorrelatedListInclude, x as CorrelatedReadByFilterInclude, y as CorrelatedReadByIdInclude, z as CountBody, D as CreateArgs, E as CreateOptions, F as CreateQueryInput, G as CustomHeaders, H as DATA_MIDDLEWARE, I as DataBaseFilterHook, J as DataFilter, K as DataFindArgs, L as DataFindOneArgs, M as DataFindOneOptions, N as DataFindOptions, O as DataHook, P as DataHookContext, Q as DataIdentifierHook, R as DataListHook, S as DataOverrideFilterHook, T as DataRequest, U as DataRequestSchemas, V as DataRouterOptions, W as DecorateAccess, X as DecorateAllAccess, Y as DeepFieldPath, Z as DefaultModelRouterOptions, _ as Defaults, $ as DistinctArgs, a0 as DistinctBody, a1 as DocPermissionsAccess, a2 as ErrorResult, a3 as ExistsOptions, a4 as ExtendedDataRouterOptions, a5 as ExtendedDefaultModelRouterOptions, a6 as ExtendedModelRouterOptions, a7 as Filter, a8 as FilterOperator, a9 as FindAccess, aa as FindArgs, ab as FindByIdArgs, ac as FindByIdOptions, ad as FindOneArgs, ae as FindOneOptions, af as FindOptions, ag as GlobalOptions, ah as GlobalPermissionValue, ai as GuardHook, aj as IdentifierHook, ak as Include, al as IoTsContextEntryLike, am as IoTsDecodeErrorLike, an as IoTsDecoderLike, ao as JoiSchemaLike, ap as JoiValidationErrorDetailLike, aq as KeyValueProjection, ar as LegacyInclude, as as ListQueryInput, at as ListResult, au as MIDDLEWARE, av as MaybePromise, aw as ModelBaseFilterHook, ax as ModelChangeHook, ay as ModelDeleteHook, az as ModelDocPermissionsHook, aA as ModelDocument, aB as ModelDocumentHook, aC as ModelHook, aD as ModelHookContext, aE as ModelIdentifierHook, aF as ModelListHook, aG as ModelOverrideFilterHook, aH as ModelRequest, aI as ModelRouterOptions, aJ as ModelValidateHook, aK as PERMISSIONS, aL as PERMISSION_KEYS, aM as ParentRef, aN as PathValue, aO as PermissionSchema, aP as Populate, aQ as PopulateAccess, aR as PrepareAccess, aS as Projection, aT as PublicCreateArgs, aU as PublicCreateOptions, aV as PublicErrorResult, aW as PublicListArgs, aX as PublicListOptions, aY as PublicListResult, aZ as PublicOutput, a_ as PublicReadArgs, a$ as PublicReadOptions, b0 as PublicServiceResult, b1 as PublicSingleResult, b2 as PublicUpdateArgs, b3 as PublicUpdateOptions, b4 as PublicUpsertArgs, b5 as PublicUpsertOptions, b6 as ReadQueryInput, b7 as Request, b8 as RequestSchemaAdapter, b9 as RequestSchemaFailure, ba as RequestSchemaIssue, bb as RequestSchemaLike, bc as RequestSchemaOptions, bd as RequestSchemaResult, be as RequestSchemaSuccess, bf as RequestSchemaValidator, bg as RequestSchemas, bh as RootDataListQueryEntry, bi as RootDataOperation, bj as RootDataReadByFilterQueryEntry, bk as RootDataReadByIdQueryEntry, bl as RootModelCountQueryEntry, bm as RootModelCreateQueryEntry, bn as RootModelDeleteQueryEntry, bo as RootModelDistinctQueryEntry, bp as RootModelListQueryEntry, bq as RootModelNewQueryEntry, br as RootModelOperation, bs as RootModelReadByFilterQueryEntry, bt as RootModelReadByIdQueryEntry, bu as RootModelSubBulkUpdateQueryEntry, bv as RootModelSubCreateQueryEntry, bw as RootModelSubDeleteQueryEntry, bx as RootModelSubListQueryEntry, by as RootModelSubReadQueryEntry, bz as RootModelSubUpdateQueryEntry, bA as RootModelUpdateQueryEntry, bB as RootModelUpsertQueryEntry, bC as RootOperationResult, bD as RootQueryEntry, bE as RootRouterOptions, bF as RootSubOperation, bG as RootTarget, bH as RouteGuardAccess, bI as SelectAccess, bJ as SelectedPopulatedPublicOutput, bK as SelectedPublicOutput, bL as ServiceResult, bM as SingleResult, bN as Sort, bO as SortOrder, bP as StandardSchemaFailure, bQ as StandardSchemaInferOutput, bR as StandardSchemaIssue, bS as StandardSchemaPathSegment, bT as StandardSchemaResult, bU as StandardSchemaSuccess, bV as StandardSchemaV1, bW as StatusCodes, bX as SubListBody, bY as SubPopulate, bZ as SubQueryEntry, b_ as SubReadBody, b$ as SubdocumentBulkRecord, c0 as SubdocumentBulkUpdateInput, c1 as SubdocumentCreateInput, c2 as SubdocumentCreateOptions, c3 as SubdocumentId, c4 as SubdocumentListOptions, c5 as SubdocumentName, c6 as SubdocumentParentArgs, c7 as SubdocumentParentOptions, c8 as SubdocumentReadOptions, c9 as SubdocumentRecord, ca as SuperstructFailureLike, cb as SuperstructValidateLike, cc as Task, cd as TaskType, ce as TransformAccess, cf as TypedFilter, cg as UpdateByIdArgs, ch as UpdateByIdOptions, ci as UpdateOneArgs, cj as UpdateOneOptions, ck as UpdateQueryInput, cl as UpsertArgs, cm as UpsertOptions, cn as UpsertQueryInput, co as ValibotIssueLike, cp as ValibotPathItemLike, cq as ValibotSafeParseLike, cr as ValibotSafeParseResult, cs as ValidateAccess, ct as ValidateRule, cu as Validation, cv as ValidationError, cw as VineValidationErrorLike, cx as VineValidationMessageLike, cy as VineValidatorLike, cz as YupSchemaLike, cA as YupValidationErrorLike, cB as defineRequestSchema, cC as fromAjv, cD as fromArkType, cE as fromIoTs, cF as fromJoi, cG as fromStandardSchema, cH as fromSuperstruct, cI as fromValibot, cJ as fromVine, cK as fromYup, cL as fromZod, cM as parseBody, cN as parseBodyWithSchema, cO as parseNestedBodyWithSchema, cP as parsePathParam, cQ as parseQuery } from './parsers-BKF7VX2-.mjs';
1
+ export { A as AccessRouterBaseRequest, a as AccessRouterFieldKey, b as AccessRouterLogger, c as AccessRouterRequest, d as AccessRouterRequestExtensions, e as AdvancedCreateBody, f as AdvancedListBody, g as AdvancedReadBody, h as AdvancedReadFilterBody, i as AdvancedUpdateBody, j as AdvancedUpsertBody, k as AfterPersistAccess, l as AjvErrorObjectLike, m as AjvValidationErrorLike, n as AjvValidatorLike, o as ArkTypeErrorsLike, p as ArkTypeLike, q as ArkTypeProblemLike, B as BaseFilterAccess, C as Change, r as Codes, s as CorrelatedCountInclude, t as CorrelatedFilter, u as CorrelatedInclude, v as CorrelatedIncludeArgs, w as CorrelatedListInclude, x as CorrelatedReadByFilterInclude, y as CorrelatedReadByIdInclude, z as CountBody, D as CreateArgs, E as CreateOptions, F as CreateQueryInput, G as CustomHeaders, H as DATA_MIDDLEWARE, I as DataBaseFilterHook, J as DataFilter, K as DataFindArgs, L as DataFindOneArgs, M as DataFindOneOptions, N as DataFindOptions, O as DataHook, P as DataHookContext, Q as DataIdentifierHook, R as DataListHook, S as DataOverrideFilterHook, T as DataRequest, U as DataRequestSchemas, V as DataRouterOptions, W as DecorateAccess, X as DecorateAllAccess, Y as DeepFieldPath, Z as DefaultModelRouterOptions, _ as Defaults, $ as DistinctArgs, a0 as DistinctBody, a1 as DocPermissionsAccess, a2 as ErrorResult, a3 as ExistsOptions, a4 as ExtendedDataRouterOptions, a5 as ExtendedDefaultModelRouterOptions, a6 as ExtendedModelRouterOptions, a7 as Filter, a8 as FilterOperator, a9 as FindAccess, aa as FindArgs, ab as FindByIdArgs, ac as FindByIdOptions, ad as FindOneArgs, ae as FindOneOptions, af as FindOptions, ag as GlobalOptions, ah as GlobalPermissionValue, ai as GuardHook, aj as IdentifierHook, ak as Include, al as IoTsContextEntryLike, am as IoTsDecodeErrorLike, an as IoTsDecoderLike, ao as JoiSchemaLike, ap as JoiValidationErrorDetailLike, aq as KeyValueProjection, ar as LegacyInclude, as as ListQueryInput, at as ListResult, au as MIDDLEWARE, av as MaybePromise, aw as ModelBaseFilterHook, ax as ModelChangeHook, ay as ModelDeleteHook, az as ModelDocPermissionsHook, aA as ModelDocument, aB as ModelDocumentHook, aC as ModelHook, aD as ModelHookContext, aE as ModelIdentifierHook, aF as ModelListHook, aG as ModelOverrideFilterHook, aH as ModelRequest, aI as ModelRouterOptions, aJ as ModelValidateHook, aK as PERMISSIONS, aL as PERMISSION_KEYS, aM as ParentRef, aN as PathValue, aO as PermissionSchema, aP as Populate, aQ as PopulateAccess, aR as PrepareAccess, aS as Projection, aT as PublicCreateArgs, aU as PublicCreateOptions, aV as PublicErrorResult, aW as PublicListArgs, aX as PublicListOptions, aY as PublicListResult, aZ as PublicOutput, a_ as PublicReadArgs, a$ as PublicReadOptions, b0 as PublicServiceResult, b1 as PublicSingleResult, b2 as PublicUpdateArgs, b3 as PublicUpdateOptions, b4 as PublicUpsertArgs, b5 as PublicUpsertOptions, b6 as ReadQueryInput, b7 as Request, b8 as RequestSchemaAdapter, b9 as RequestSchemaFailure, ba as RequestSchemaIssue, bb as RequestSchemaLike, bc as RequestSchemaOptions, bd as RequestSchemaResult, be as RequestSchemaSuccess, bf as RequestSchemaValidator, bg as RequestSchemas, bh as RootDataListQueryEntry, bi as RootDataOperation, bj as RootDataReadByFilterQueryEntry, bk as RootDataReadByIdQueryEntry, bl as RootModelCountQueryEntry, bm as RootModelCreateQueryEntry, bn as RootModelDeleteQueryEntry, bo as RootModelDistinctQueryEntry, bp as RootModelListQueryEntry, bq as RootModelNewQueryEntry, br as RootModelOperation, bs as RootModelReadByFilterQueryEntry, bt as RootModelReadByIdQueryEntry, bu as RootModelSubBulkUpdateQueryEntry, bv as RootModelSubCreateQueryEntry, bw as RootModelSubDeleteQueryEntry, bx as RootModelSubListQueryEntry, by as RootModelSubReadQueryEntry, bz as RootModelSubUpdateQueryEntry, bA as RootModelUpdateQueryEntry, bB as RootModelUpsertQueryEntry, bC as RootOperationResult, bD as RootQueryEntry, bE as RootRouterOptions, bF as RootSubOperation, bG as RootTarget, bH as RouteGuardAccess, bI as SelectAccess, bJ as SelectedPopulatedPublicOutput, bK as SelectedPublicOutput, bL as ServiceResult, bM as SingleResult, bN as Sort, bO as SortOrder, bP as StandardSchemaFailure, bQ as StandardSchemaInferOutput, bR as StandardSchemaIssue, bS as StandardSchemaPathSegment, bT as StandardSchemaResult, bU as StandardSchemaSuccess, bV as StandardSchemaV1, bW as StatusCodes, bX as SubListBody, bY as SubPopulate, bZ as SubQueryEntry, b_ as SubReadBody, b$ as SubdocumentBulkRecord, c0 as SubdocumentBulkUpdateInput, c1 as SubdocumentCreateInput, c2 as SubdocumentCreateOptions, c3 as SubdocumentId, c4 as SubdocumentListOptions, c5 as SubdocumentName, c6 as SubdocumentParentArgs, c7 as SubdocumentParentOptions, c8 as SubdocumentReadOptions, c9 as SubdocumentRecord, ca as SuperstructFailureLike, cb as SuperstructValidateLike, cc as Task, cd as TaskType, ce as TransformAccess, cf as TypedFilter, cg as UpdateByIdArgs, ch as UpdateByIdOptions, ci as UpdateOneArgs, cj as UpdateOneOptions, ck as UpdateQueryInput, cl as UpsertArgs, cm as UpsertOptions, cn as UpsertQueryInput, co as ValibotIssueLike, cp as ValibotPathItemLike, cq as ValibotSafeParseLike, cr as ValibotSafeParseResult, cs as ValidateAccess, ct as ValidateRule, cu as Validation, cv as ValidationError, cw as VineValidationErrorLike, cx as VineValidationMessageLike, cy as VineValidatorLike, cz as YupSchemaLike, cA as YupValidationErrorLike, cB as defineRequestSchema, cC as fromAjv, cD as fromArkType, cE as fromIoTs, cF as fromJoi, cG as fromStandardSchema, cH as fromSuperstruct, cI as fromValibot, cJ as fromVine, cK as fromYup, cL as fromZod, cM as parseBody, cN as parseBodyWithSchema, cO as parseNestedBodyWithSchema, cP as parsePathParam, cQ as parseQuery } from './parsers-BidvJUu7.mjs';
2
2
  import { z } from 'zod';
3
3
  import 'mongoose';
4
4
  import 'express';
package/advanced.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as AccessRouterBaseRequest, a as AccessRouterFieldKey, b as AccessRouterLogger, c as AccessRouterRequest, d as AccessRouterRequestExtensions, e as AdvancedCreateBody, f as AdvancedListBody, g as AdvancedReadBody, h as AdvancedReadFilterBody, i as AdvancedUpdateBody, j as AdvancedUpsertBody, k as AfterPersistAccess, l as AjvErrorObjectLike, m as AjvValidationErrorLike, n as AjvValidatorLike, o as ArkTypeErrorsLike, p as ArkTypeLike, q as ArkTypeProblemLike, B as BaseFilterAccess, C as Change, r as Codes, s as CorrelatedCountInclude, t as CorrelatedFilter, u as CorrelatedInclude, v as CorrelatedIncludeArgs, w as CorrelatedListInclude, x as CorrelatedReadByFilterInclude, y as CorrelatedReadByIdInclude, z as CountBody, D as CreateArgs, E as CreateOptions, F as CreateQueryInput, G as CustomHeaders, H as DATA_MIDDLEWARE, I as DataBaseFilterHook, J as DataFilter, K as DataFindArgs, L as DataFindOneArgs, M as DataFindOneOptions, N as DataFindOptions, O as DataHook, P as DataHookContext, Q as DataIdentifierHook, R as DataListHook, S as DataOverrideFilterHook, T as DataRequest, U as DataRequestSchemas, V as DataRouterOptions, W as DecorateAccess, X as DecorateAllAccess, Y as DeepFieldPath, Z as DefaultModelRouterOptions, _ as Defaults, $ as DistinctArgs, a0 as DistinctBody, a1 as DocPermissionsAccess, a2 as ErrorResult, a3 as ExistsOptions, a4 as ExtendedDataRouterOptions, a5 as ExtendedDefaultModelRouterOptions, a6 as ExtendedModelRouterOptions, a7 as Filter, a8 as FilterOperator, a9 as FindAccess, aa as FindArgs, ab as FindByIdArgs, ac as FindByIdOptions, ad as FindOneArgs, ae as FindOneOptions, af as FindOptions, ag as GlobalOptions, ah as GlobalPermissionValue, ai as GuardHook, aj as IdentifierHook, ak as Include, al as IoTsContextEntryLike, am as IoTsDecodeErrorLike, an as IoTsDecoderLike, ao as JoiSchemaLike, ap as JoiValidationErrorDetailLike, aq as KeyValueProjection, ar as LegacyInclude, as as ListQueryInput, at as ListResult, au as MIDDLEWARE, av as MaybePromise, aw as ModelBaseFilterHook, ax as ModelChangeHook, ay as ModelDeleteHook, az as ModelDocPermissionsHook, aA as ModelDocument, aB as ModelDocumentHook, aC as ModelHook, aD as ModelHookContext, aE as ModelIdentifierHook, aF as ModelListHook, aG as ModelOverrideFilterHook, aH as ModelRequest, aI as ModelRouterOptions, aJ as ModelValidateHook, aK as PERMISSIONS, aL as PERMISSION_KEYS, aM as ParentRef, aN as PathValue, aO as PermissionSchema, aP as Populate, aQ as PopulateAccess, aR as PrepareAccess, aS as Projection, aT as PublicCreateArgs, aU as PublicCreateOptions, aV as PublicErrorResult, aW as PublicListArgs, aX as PublicListOptions, aY as PublicListResult, aZ as PublicOutput, a_ as PublicReadArgs, a$ as PublicReadOptions, b0 as PublicServiceResult, b1 as PublicSingleResult, b2 as PublicUpdateArgs, b3 as PublicUpdateOptions, b4 as PublicUpsertArgs, b5 as PublicUpsertOptions, b6 as ReadQueryInput, b7 as Request, b8 as RequestSchemaAdapter, b9 as RequestSchemaFailure, ba as RequestSchemaIssue, bb as RequestSchemaLike, bc as RequestSchemaOptions, bd as RequestSchemaResult, be as RequestSchemaSuccess, bf as RequestSchemaValidator, bg as RequestSchemas, bh as RootDataListQueryEntry, bi as RootDataOperation, bj as RootDataReadByFilterQueryEntry, bk as RootDataReadByIdQueryEntry, bl as RootModelCountQueryEntry, bm as RootModelCreateQueryEntry, bn as RootModelDeleteQueryEntry, bo as RootModelDistinctQueryEntry, bp as RootModelListQueryEntry, bq as RootModelNewQueryEntry, br as RootModelOperation, bs as RootModelReadByFilterQueryEntry, bt as RootModelReadByIdQueryEntry, bu as RootModelSubBulkUpdateQueryEntry, bv as RootModelSubCreateQueryEntry, bw as RootModelSubDeleteQueryEntry, bx as RootModelSubListQueryEntry, by as RootModelSubReadQueryEntry, bz as RootModelSubUpdateQueryEntry, bA as RootModelUpdateQueryEntry, bB as RootModelUpsertQueryEntry, bC as RootOperationResult, bD as RootQueryEntry, bE as RootRouterOptions, bF as RootSubOperation, bG as RootTarget, bH as RouteGuardAccess, bI as SelectAccess, bJ as SelectedPopulatedPublicOutput, bK as SelectedPublicOutput, bL as ServiceResult, bM as SingleResult, bN as Sort, bO as SortOrder, bP as StandardSchemaFailure, bQ as StandardSchemaInferOutput, bR as StandardSchemaIssue, bS as StandardSchemaPathSegment, bT as StandardSchemaResult, bU as StandardSchemaSuccess, bV as StandardSchemaV1, bW as StatusCodes, bX as SubListBody, bY as SubPopulate, bZ as SubQueryEntry, b_ as SubReadBody, b$ as SubdocumentBulkRecord, c0 as SubdocumentBulkUpdateInput, c1 as SubdocumentCreateInput, c2 as SubdocumentCreateOptions, c3 as SubdocumentId, c4 as SubdocumentListOptions, c5 as SubdocumentName, c6 as SubdocumentParentArgs, c7 as SubdocumentParentOptions, c8 as SubdocumentReadOptions, c9 as SubdocumentRecord, ca as SuperstructFailureLike, cb as SuperstructValidateLike, cc as Task, cd as TaskType, ce as TransformAccess, cf as TypedFilter, cg as UpdateByIdArgs, ch as UpdateByIdOptions, ci as UpdateOneArgs, cj as UpdateOneOptions, ck as UpdateQueryInput, cl as UpsertArgs, cm as UpsertOptions, cn as UpsertQueryInput, co as ValibotIssueLike, cp as ValibotPathItemLike, cq as ValibotSafeParseLike, cr as ValibotSafeParseResult, cs as ValidateAccess, ct as ValidateRule, cu as Validation, cv as ValidationError, cw as VineValidationErrorLike, cx as VineValidationMessageLike, cy as VineValidatorLike, cz as YupSchemaLike, cA as YupValidationErrorLike, cB as defineRequestSchema, cC as fromAjv, cD as fromArkType, cE as fromIoTs, cF as fromJoi, cG as fromStandardSchema, cH as fromSuperstruct, cI as fromValibot, cJ as fromVine, cK as fromYup, cL as fromZod, cM as parseBody, cN as parseBodyWithSchema, cO as parseNestedBodyWithSchema, cP as parsePathParam, cQ as parseQuery } from './parsers-BKF7VX2-.js';
1
+ export { A as AccessRouterBaseRequest, a as AccessRouterFieldKey, b as AccessRouterLogger, c as AccessRouterRequest, d as AccessRouterRequestExtensions, e as AdvancedCreateBody, f as AdvancedListBody, g as AdvancedReadBody, h as AdvancedReadFilterBody, i as AdvancedUpdateBody, j as AdvancedUpsertBody, k as AfterPersistAccess, l as AjvErrorObjectLike, m as AjvValidationErrorLike, n as AjvValidatorLike, o as ArkTypeErrorsLike, p as ArkTypeLike, q as ArkTypeProblemLike, B as BaseFilterAccess, C as Change, r as Codes, s as CorrelatedCountInclude, t as CorrelatedFilter, u as CorrelatedInclude, v as CorrelatedIncludeArgs, w as CorrelatedListInclude, x as CorrelatedReadByFilterInclude, y as CorrelatedReadByIdInclude, z as CountBody, D as CreateArgs, E as CreateOptions, F as CreateQueryInput, G as CustomHeaders, H as DATA_MIDDLEWARE, I as DataBaseFilterHook, J as DataFilter, K as DataFindArgs, L as DataFindOneArgs, M as DataFindOneOptions, N as DataFindOptions, O as DataHook, P as DataHookContext, Q as DataIdentifierHook, R as DataListHook, S as DataOverrideFilterHook, T as DataRequest, U as DataRequestSchemas, V as DataRouterOptions, W as DecorateAccess, X as DecorateAllAccess, Y as DeepFieldPath, Z as DefaultModelRouterOptions, _ as Defaults, $ as DistinctArgs, a0 as DistinctBody, a1 as DocPermissionsAccess, a2 as ErrorResult, a3 as ExistsOptions, a4 as ExtendedDataRouterOptions, a5 as ExtendedDefaultModelRouterOptions, a6 as ExtendedModelRouterOptions, a7 as Filter, a8 as FilterOperator, a9 as FindAccess, aa as FindArgs, ab as FindByIdArgs, ac as FindByIdOptions, ad as FindOneArgs, ae as FindOneOptions, af as FindOptions, ag as GlobalOptions, ah as GlobalPermissionValue, ai as GuardHook, aj as IdentifierHook, ak as Include, al as IoTsContextEntryLike, am as IoTsDecodeErrorLike, an as IoTsDecoderLike, ao as JoiSchemaLike, ap as JoiValidationErrorDetailLike, aq as KeyValueProjection, ar as LegacyInclude, as as ListQueryInput, at as ListResult, au as MIDDLEWARE, av as MaybePromise, aw as ModelBaseFilterHook, ax as ModelChangeHook, ay as ModelDeleteHook, az as ModelDocPermissionsHook, aA as ModelDocument, aB as ModelDocumentHook, aC as ModelHook, aD as ModelHookContext, aE as ModelIdentifierHook, aF as ModelListHook, aG as ModelOverrideFilterHook, aH as ModelRequest, aI as ModelRouterOptions, aJ as ModelValidateHook, aK as PERMISSIONS, aL as PERMISSION_KEYS, aM as ParentRef, aN as PathValue, aO as PermissionSchema, aP as Populate, aQ as PopulateAccess, aR as PrepareAccess, aS as Projection, aT as PublicCreateArgs, aU as PublicCreateOptions, aV as PublicErrorResult, aW as PublicListArgs, aX as PublicListOptions, aY as PublicListResult, aZ as PublicOutput, a_ as PublicReadArgs, a$ as PublicReadOptions, b0 as PublicServiceResult, b1 as PublicSingleResult, b2 as PublicUpdateArgs, b3 as PublicUpdateOptions, b4 as PublicUpsertArgs, b5 as PublicUpsertOptions, b6 as ReadQueryInput, b7 as Request, b8 as RequestSchemaAdapter, b9 as RequestSchemaFailure, ba as RequestSchemaIssue, bb as RequestSchemaLike, bc as RequestSchemaOptions, bd as RequestSchemaResult, be as RequestSchemaSuccess, bf as RequestSchemaValidator, bg as RequestSchemas, bh as RootDataListQueryEntry, bi as RootDataOperation, bj as RootDataReadByFilterQueryEntry, bk as RootDataReadByIdQueryEntry, bl as RootModelCountQueryEntry, bm as RootModelCreateQueryEntry, bn as RootModelDeleteQueryEntry, bo as RootModelDistinctQueryEntry, bp as RootModelListQueryEntry, bq as RootModelNewQueryEntry, br as RootModelOperation, bs as RootModelReadByFilterQueryEntry, bt as RootModelReadByIdQueryEntry, bu as RootModelSubBulkUpdateQueryEntry, bv as RootModelSubCreateQueryEntry, bw as RootModelSubDeleteQueryEntry, bx as RootModelSubListQueryEntry, by as RootModelSubReadQueryEntry, bz as RootModelSubUpdateQueryEntry, bA as RootModelUpdateQueryEntry, bB as RootModelUpsertQueryEntry, bC as RootOperationResult, bD as RootQueryEntry, bE as RootRouterOptions, bF as RootSubOperation, bG as RootTarget, bH as RouteGuardAccess, bI as SelectAccess, bJ as SelectedPopulatedPublicOutput, bK as SelectedPublicOutput, bL as ServiceResult, bM as SingleResult, bN as Sort, bO as SortOrder, bP as StandardSchemaFailure, bQ as StandardSchemaInferOutput, bR as StandardSchemaIssue, bS as StandardSchemaPathSegment, bT as StandardSchemaResult, bU as StandardSchemaSuccess, bV as StandardSchemaV1, bW as StatusCodes, bX as SubListBody, bY as SubPopulate, bZ as SubQueryEntry, b_ as SubReadBody, b$ as SubdocumentBulkRecord, c0 as SubdocumentBulkUpdateInput, c1 as SubdocumentCreateInput, c2 as SubdocumentCreateOptions, c3 as SubdocumentId, c4 as SubdocumentListOptions, c5 as SubdocumentName, c6 as SubdocumentParentArgs, c7 as SubdocumentParentOptions, c8 as SubdocumentReadOptions, c9 as SubdocumentRecord, ca as SuperstructFailureLike, cb as SuperstructValidateLike, cc as Task, cd as TaskType, ce as TransformAccess, cf as TypedFilter, cg as UpdateByIdArgs, ch as UpdateByIdOptions, ci as UpdateOneArgs, cj as UpdateOneOptions, ck as UpdateQueryInput, cl as UpsertArgs, cm as UpsertOptions, cn as UpsertQueryInput, co as ValibotIssueLike, cp as ValibotPathItemLike, cq as ValibotSafeParseLike, cr as ValibotSafeParseResult, cs as ValidateAccess, ct as ValidateRule, cu as Validation, cv as ValidationError, cw as VineValidationErrorLike, cx as VineValidationMessageLike, cy as VineValidatorLike, cz as YupSchemaLike, cA as YupValidationErrorLike, cB as defineRequestSchema, cC as fromAjv, cD as fromArkType, cE as fromIoTs, cF as fromJoi, cG as fromStandardSchema, cH as fromSuperstruct, cI as fromValibot, cJ as fromVine, cK as fromYup, cL as fromZod, cM as parseBody, cN as parseBodyWithSchema, cO as parseNestedBodyWithSchema, cP as parsePathParam, cQ as parseQuery } from './parsers-BidvJUu7.js';
2
2
  import { z } from 'zod';
3
3
  import 'mongoose';
4
4
  import 'express';
package/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import mongoose, { Schema } from 'mongoose';
2
2
  import { Response, NextFunction, RequestHandler, Router } from 'express';
3
- import { A as AccessRouterBaseRequest, ai as GuardHook, aH as ModelRequest, cR as AccessRuntime, V as DataRouterOptions, T as DataRequest, cS as DataService, a7 as Filter, aS as Projection, bN as Sort, aP as Populate, aI as ModelRouterOptions, cT as Service, cU as PublicService, a6 as ExtendedModelRouterOptions, cu as Validation, bE as RootRouterOptions, cV as OpenApiRouterOptions, cW as OpenApiRegistryOptions, cX as OpenApiRouteDescriptor, cY as OpenApiDocumentOptions, cZ as OpenApiParameter, c_ as OpenApiSchema, c$ as OpenApiResponses, ag as GlobalOptions, Z as DefaultModelRouterOptions, a5 as ExtendedDefaultModelRouterOptions } from './parsers-BKF7VX2-.mjs';
4
- export { d0 as AccessRouterPermissionMap, d1 as AccessRouterPermissions, c as AccessRouterRequest, d as AccessRouterRequestExtensions, l as AjvErrorObjectLike, n as AjvValidatorLike, o as ArkTypeErrorsLike, p as ArkTypeLike, ah as GlobalPermissionValue, al as IoTsContextEntryLike, am as IoTsDecodeErrorLike, an as IoTsDecoderLike, ao as JoiSchemaLike, ap as JoiValidationErrorDetailLike, av as MaybePromise, aw as ModelBaseFilterHook, ay as ModelDeleteHook, az as ModelDocPermissionsHook, aB as ModelDocumentHook, aC as ModelHook, aE as ModelIdentifierHook, aF as ModelListHook, aG as ModelOverrideFilterHook, aJ as ModelValidateHook, d2 as OpenApiMethod, d3 as Permissions, b8 as RequestSchemaAdapter, b9 as RequestSchemaFailure, ba as RequestSchemaIssue, bb as RequestSchemaLike, bc as RequestSchemaOptions, bd as RequestSchemaResult, be as RequestSchemaSuccess, bf as RequestSchemaValidator, bH as RouteGuardAccess, bP as StandardSchemaFailure, bQ as StandardSchemaInferOutput, bR as StandardSchemaIssue, bS as StandardSchemaPathSegment, bT as StandardSchemaResult, bU as StandardSchemaSuccess, bV as StandardSchemaV1, ca as SuperstructFailureLike, cb as SuperstructValidateLike, co as ValibotIssueLike, cp as ValibotPathItemLike, cq as ValibotSafeParseLike, cr as ValibotSafeParseResult, cw as VineValidationErrorLike, cx as VineValidationMessageLike, cy as VineValidatorLike, cz as YupSchemaLike, cA as YupValidationErrorLike, d4 as defaultRuntime, cB as defineRequestSchema, cC as fromAjv, cD as fromArkType, cE as fromIoTs, cF as fromJoi, cG as fromStandardSchema, cH as fromSuperstruct, cI as fromValibot, cJ as fromVine, cK as fromYup, cL as fromZod } from './parsers-BKF7VX2-.mjs';
3
+ import { A as AccessRouterBaseRequest, ai as GuardHook, aH as ModelRequest, cR as AccessRuntime, V as DataRouterOptions, T as DataRequest, cS as DataService, a7 as Filter, aS as Projection, bN as Sort, aP as Populate, aI as ModelRouterOptions, cT as Service, cU as PublicService, a6 as ExtendedModelRouterOptions, cu as Validation, bE as RootRouterOptions, cV as OpenApiRouterOptions, cW as OpenApiRegistryOptions, cX as OpenApiRouteDescriptor, cY as OpenApiDocumentOptions, cZ as OpenApiParameter, c_ as OpenApiSchema, c$ as OpenApiResponses, ag as GlobalOptions, Z as DefaultModelRouterOptions, a5 as ExtendedDefaultModelRouterOptions } from './parsers-BidvJUu7.mjs';
4
+ export { d0 as AccessRouterPermissionMap, d1 as AccessRouterPermissions, c as AccessRouterRequest, d as AccessRouterRequestExtensions, l as AjvErrorObjectLike, n as AjvValidatorLike, o as ArkTypeErrorsLike, p as ArkTypeLike, ah as GlobalPermissionValue, al as IoTsContextEntryLike, am as IoTsDecodeErrorLike, an as IoTsDecoderLike, ao as JoiSchemaLike, ap as JoiValidationErrorDetailLike, av as MaybePromise, aw as ModelBaseFilterHook, ay as ModelDeleteHook, az as ModelDocPermissionsHook, aB as ModelDocumentHook, aC as ModelHook, aE as ModelIdentifierHook, aF as ModelListHook, aG as ModelOverrideFilterHook, aJ as ModelValidateHook, d2 as OpenApiMethod, d3 as Permissions, b8 as RequestSchemaAdapter, b9 as RequestSchemaFailure, ba as RequestSchemaIssue, bb as RequestSchemaLike, bc as RequestSchemaOptions, bd as RequestSchemaResult, be as RequestSchemaSuccess, bf as RequestSchemaValidator, bH as RouteGuardAccess, bP as StandardSchemaFailure, bQ as StandardSchemaInferOutput, bR as StandardSchemaIssue, bS as StandardSchemaPathSegment, bT as StandardSchemaResult, bU as StandardSchemaSuccess, bV as StandardSchemaV1, ca as SuperstructFailureLike, cb as SuperstructValidateLike, co as ValibotIssueLike, cp as ValibotPathItemLike, cq as ValibotSafeParseLike, cr as ValibotSafeParseResult, cw as VineValidationErrorLike, cx as VineValidationMessageLike, cy as VineValidatorLike, cz as YupSchemaLike, cA as YupValidationErrorLike, d4 as defaultRuntime, cB as defineRequestSchema, cC as fromAjv, cD as fromArkType, cE as fromIoTs, cF as fromJoi, cG as fromStandardSchema, cH as fromSuperstruct, cI as fromValibot, cJ as fromVine, cK as fromYup, cL as fromZod } from './parsers-BidvJUu7.mjs';
5
5
  import JsonRouter from '@web-ts-toolkit/express-json-router';
6
6
  import 'zod';
7
7
 
package/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import mongoose, { Schema } from 'mongoose';
2
2
  import { Response, NextFunction, RequestHandler, Router } from 'express';
3
- import { A as AccessRouterBaseRequest, ai as GuardHook, aH as ModelRequest, cR as AccessRuntime, V as DataRouterOptions, T as DataRequest, cS as DataService, a7 as Filter, aS as Projection, bN as Sort, aP as Populate, aI as ModelRouterOptions, cT as Service, cU as PublicService, a6 as ExtendedModelRouterOptions, cu as Validation, bE as RootRouterOptions, cV as OpenApiRouterOptions, cW as OpenApiRegistryOptions, cX as OpenApiRouteDescriptor, cY as OpenApiDocumentOptions, cZ as OpenApiParameter, c_ as OpenApiSchema, c$ as OpenApiResponses, ag as GlobalOptions, Z as DefaultModelRouterOptions, a5 as ExtendedDefaultModelRouterOptions } from './parsers-BKF7VX2-.js';
4
- export { d0 as AccessRouterPermissionMap, d1 as AccessRouterPermissions, c as AccessRouterRequest, d as AccessRouterRequestExtensions, l as AjvErrorObjectLike, n as AjvValidatorLike, o as ArkTypeErrorsLike, p as ArkTypeLike, ah as GlobalPermissionValue, al as IoTsContextEntryLike, am as IoTsDecodeErrorLike, an as IoTsDecoderLike, ao as JoiSchemaLike, ap as JoiValidationErrorDetailLike, av as MaybePromise, aw as ModelBaseFilterHook, ay as ModelDeleteHook, az as ModelDocPermissionsHook, aB as ModelDocumentHook, aC as ModelHook, aE as ModelIdentifierHook, aF as ModelListHook, aG as ModelOverrideFilterHook, aJ as ModelValidateHook, d2 as OpenApiMethod, d3 as Permissions, b8 as RequestSchemaAdapter, b9 as RequestSchemaFailure, ba as RequestSchemaIssue, bb as RequestSchemaLike, bc as RequestSchemaOptions, bd as RequestSchemaResult, be as RequestSchemaSuccess, bf as RequestSchemaValidator, bH as RouteGuardAccess, bP as StandardSchemaFailure, bQ as StandardSchemaInferOutput, bR as StandardSchemaIssue, bS as StandardSchemaPathSegment, bT as StandardSchemaResult, bU as StandardSchemaSuccess, bV as StandardSchemaV1, ca as SuperstructFailureLike, cb as SuperstructValidateLike, co as ValibotIssueLike, cp as ValibotPathItemLike, cq as ValibotSafeParseLike, cr as ValibotSafeParseResult, cw as VineValidationErrorLike, cx as VineValidationMessageLike, cy as VineValidatorLike, cz as YupSchemaLike, cA as YupValidationErrorLike, d4 as defaultRuntime, cB as defineRequestSchema, cC as fromAjv, cD as fromArkType, cE as fromIoTs, cF as fromJoi, cG as fromStandardSchema, cH as fromSuperstruct, cI as fromValibot, cJ as fromVine, cK as fromYup, cL as fromZod } from './parsers-BKF7VX2-.js';
3
+ import { A as AccessRouterBaseRequest, ai as GuardHook, aH as ModelRequest, cR as AccessRuntime, V as DataRouterOptions, T as DataRequest, cS as DataService, a7 as Filter, aS as Projection, bN as Sort, aP as Populate, aI as ModelRouterOptions, cT as Service, cU as PublicService, a6 as ExtendedModelRouterOptions, cu as Validation, bE as RootRouterOptions, cV as OpenApiRouterOptions, cW as OpenApiRegistryOptions, cX as OpenApiRouteDescriptor, cY as OpenApiDocumentOptions, cZ as OpenApiParameter, c_ as OpenApiSchema, c$ as OpenApiResponses, ag as GlobalOptions, Z as DefaultModelRouterOptions, a5 as ExtendedDefaultModelRouterOptions } from './parsers-BidvJUu7.js';
4
+ export { d0 as AccessRouterPermissionMap, d1 as AccessRouterPermissions, c as AccessRouterRequest, d as AccessRouterRequestExtensions, l as AjvErrorObjectLike, n as AjvValidatorLike, o as ArkTypeErrorsLike, p as ArkTypeLike, ah as GlobalPermissionValue, al as IoTsContextEntryLike, am as IoTsDecodeErrorLike, an as IoTsDecoderLike, ao as JoiSchemaLike, ap as JoiValidationErrorDetailLike, av as MaybePromise, aw as ModelBaseFilterHook, ay as ModelDeleteHook, az as ModelDocPermissionsHook, aB as ModelDocumentHook, aC as ModelHook, aE as ModelIdentifierHook, aF as ModelListHook, aG as ModelOverrideFilterHook, aJ as ModelValidateHook, d2 as OpenApiMethod, d3 as Permissions, b8 as RequestSchemaAdapter, b9 as RequestSchemaFailure, ba as RequestSchemaIssue, bb as RequestSchemaLike, bc as RequestSchemaOptions, bd as RequestSchemaResult, be as RequestSchemaSuccess, bf as RequestSchemaValidator, bH as RouteGuardAccess, bP as StandardSchemaFailure, bQ as StandardSchemaInferOutput, bR as StandardSchemaIssue, bS as StandardSchemaPathSegment, bT as StandardSchemaResult, bU as StandardSchemaSuccess, bV as StandardSchemaV1, ca as SuperstructFailureLike, cb as SuperstructValidateLike, co as ValibotIssueLike, cp as ValibotPathItemLike, cq as ValibotSafeParseLike, cr as ValibotSafeParseResult, cw as VineValidationErrorLike, cx as VineValidationMessageLike, cy as VineValidatorLike, cz as YupSchemaLike, cA as YupValidationErrorLike, d4 as defaultRuntime, cB as defineRequestSchema, cC as fromAjv, cD as fromArkType, cE as fromIoTs, cF as fromJoi, cG as fromStandardSchema, cH as fromSuperstruct, cI as fromValibot, cJ as fromVine, cK as fromYup, cL as fromZod } from './parsers-BidvJUu7.js';
5
5
  import JsonRouter from '@web-ts-toolkit/express-json-router';
6
6
  import 'zod';
7
7
 
package/index.js CHANGED
@@ -376,6 +376,41 @@ function normalizeSortForOrderBy(sort) {
376
376
  orders: normalized.fields.map(({ direction }) => direction)
377
377
  };
378
378
  }
379
+ function sanitizeSortFields(sort, allowedFields) {
380
+ const { fields, errors } = normalizeSort(sort);
381
+ if (errors.length > 0) return { sort: void 0, stripped: [], errors };
382
+ const allowedSet = new Set(allowedFields.concat(["id", "_id"]));
383
+ const kept = fields.filter(({ field }) => allowedSet.has(field));
384
+ const stripped = fields.filter(({ field }) => !allowedSet.has(field)).map(({ field }) => field);
385
+ if (stripped.length === 0) return { sort, stripped, errors: [] };
386
+ if (kept.length === 0) return { sort: void 0, stripped, errors: [] };
387
+ if (typeof sort === "string") {
388
+ return {
389
+ sort: kept.map(({ field, direction }) => direction === "desc" ? `-${field}` : field).join(" "),
390
+ stripped,
391
+ errors: []
392
+ };
393
+ }
394
+ if (sort instanceof Map) {
395
+ return {
396
+ sort: new Map(kept.map(({ field, direction }) => [field, direction])),
397
+ stripped,
398
+ errors: []
399
+ };
400
+ }
401
+ if (Array.isArray(sort)) {
402
+ return {
403
+ sort: kept.map(({ field, direction }) => [field, direction]),
404
+ stripped,
405
+ errors: []
406
+ };
407
+ }
408
+ return {
409
+ sort: Object.fromEntries(kept.map(({ field, direction }) => [field, direction])),
410
+ stripped,
411
+ errors: []
412
+ };
413
+ }
379
414
 
380
415
  // src/helpers/index.ts
381
416
  var import_utils6 = require("@web-ts-toolkit/utils");
@@ -3515,6 +3550,10 @@ var Service = class extends Base {
3515
3550
  asServiceHookContext(context) {
3516
3551
  return context;
3517
3552
  }
3553
+ getEffectiveAllowedSortFields(allowedSortFields) {
3554
+ const extra = this.options?.sortableFields ?? [];
3555
+ return extra.length > 0 ? [...allowedSortFields, ...extra] : allowedSortFields;
3556
+ }
3518
3557
  beginOp(op, filter2, extra) {
3519
3558
  const startedAt = Date.now();
3520
3559
  debug({
@@ -3561,14 +3600,18 @@ var Service = class extends Base {
3561
3600
  const { includes, correlatedIncludes, includeLocalFields, includePaths, correlatedReferenceFields } = processedInclude;
3562
3601
  const correlatedOutputPaths = correlatedIncludes.map((entry) => entry.path);
3563
3602
  const finalSelect = normalizeSelect(_select).concat(includeLocalFields, correlatedReferenceFields);
3603
+ const effectiveAllowedSortFields = this.getEffectiveAllowedSortFields(allowedSortFields);
3604
+ const stripDisallowedSort = this.options?.stripDisallowedSort ?? false;
3605
+ const sanitizedSort = stripDisallowedSort ? sanitizeSortFields(sort, effectiveAllowedSortFields) : null;
3606
+ const effectiveSort = stripDisallowedSort ? sanitizedSort?.sort : sort;
3564
3607
  const query = {
3565
3608
  filter: _filter,
3566
3609
  select: finalSelect,
3567
- sort,
3610
+ sort: effectiveSort,
3568
3611
  populate: _populate
3569
3612
  };
3570
3613
  const startedAt = this.beginOp("findOne", _filter, {
3571
- sort,
3614
+ sort: effectiveSort,
3572
3615
  selectCount: finalSelect.length,
3573
3616
  populateCount: Array.isArray(_populate) ? _populate.length : _populate ? 1 : 0
3574
3617
  });
@@ -3576,10 +3619,17 @@ var Service = class extends Base {
3576
3619
  this.completeOp("findOne", startedAt, "forbidden" /* Forbidden */, _filter);
3577
3620
  return { success: false, kind: "error", code: "forbidden" /* Forbidden */, query };
3578
3621
  }
3579
- const sortErrors = validateSortFields(sort, allowedSortFields);
3580
- if (sortErrors.length > 0) {
3581
- this.completeOp("findOne", startedAt, "bad_request" /* BadRequest */, _filter);
3582
- return { success: false, kind: "error", code: "bad_request" /* BadRequest */, errors: sortErrors, query };
3622
+ if (stripDisallowedSort) {
3623
+ if (sanitizedSort && sanitizedSort.errors.length > 0) {
3624
+ this.completeOp("findOne", startedAt, "bad_request" /* BadRequest */, _filter);
3625
+ return { success: false, kind: "error", code: "bad_request" /* BadRequest */, errors: sanitizedSort.errors, query };
3626
+ }
3627
+ } else {
3628
+ const sortErrors = validateSortFields(sort, effectiveAllowedSortFields);
3629
+ if (sortErrors.length > 0) {
3630
+ this.completeOp("findOne", startedAt, "bad_request" /* BadRequest */, _filter);
3631
+ return { success: false, kind: "error", code: "bad_request" /* BadRequest */, errors: sortErrors, query };
3632
+ }
3583
3633
  }
3584
3634
  let doc = await this.model.findOne({ ...query, lean });
3585
3635
  if (!doc) {
@@ -3683,15 +3733,19 @@ var Service = class extends Base {
3683
3733
  const filteredPopulate = (0, import_utils17.isArray)(finalSelect) && (0, import_utils17.isArray)(_populate) ? _populate.filter((p) => finalSelect.includes(p.path.split(".")[0])) : _populate;
3684
3734
  const { includes, correlatedIncludes, includeLocalFields, includePaths, correlatedReferenceFields } = processedInclude;
3685
3735
  const correlatedOutputPaths = correlatedIncludes.map((entry) => entry.path);
3736
+ const effectiveAllowedSortFields = this.getEffectiveAllowedSortFields(allowedSortFields);
3737
+ const stripDisallowedSort = this.options?.stripDisallowedSort ?? false;
3738
+ const sanitizedSort = stripDisallowedSort ? sanitizeSortFields(sort, effectiveAllowedSortFields) : null;
3739
+ const effectiveSort = stripDisallowedSort ? sanitizedSort?.sort : sort;
3686
3740
  const query = {
3687
3741
  filter: _filter,
3688
3742
  select: finalSelect.concat(includeLocalFields, correlatedReferenceFields),
3689
3743
  populate: filteredPopulate,
3690
- sort,
3744
+ sort: effectiveSort,
3691
3745
  ...pagination
3692
3746
  };
3693
3747
  const startedAt = this.beginOp("find", _filter, {
3694
- sort,
3748
+ sort: effectiveSort,
3695
3749
  skip: pagination.skip,
3696
3750
  limit: pagination.limit,
3697
3751
  selectCount: finalSelect.concat(includeLocalFields, correlatedReferenceFields).length,
@@ -3701,10 +3755,17 @@ var Service = class extends Base {
3701
3755
  this.completeOp("find", startedAt, "forbidden" /* Forbidden */, _filter);
3702
3756
  return { success: false, kind: "error", code: "forbidden" /* Forbidden */, query };
3703
3757
  }
3704
- const sortErrors = validateSortFields(sort, allowedSortFields);
3705
- if (sortErrors.length > 0) {
3706
- this.completeOp("find", startedAt, "bad_request" /* BadRequest */, _filter);
3707
- return { success: false, kind: "error", code: "bad_request" /* BadRequest */, errors: sortErrors, query };
3758
+ if (stripDisallowedSort) {
3759
+ if (sanitizedSort && sanitizedSort.errors.length > 0) {
3760
+ this.completeOp("find", startedAt, "bad_request" /* BadRequest */, _filter);
3761
+ return { success: false, kind: "error", code: "bad_request" /* BadRequest */, errors: sanitizedSort.errors, query };
3762
+ }
3763
+ } else {
3764
+ const sortErrors = validateSortFields(sort, effectiveAllowedSortFields);
3765
+ if (sortErrors.length > 0) {
3766
+ this.completeOp("find", startedAt, "bad_request" /* BadRequest */, _filter);
3767
+ return { success: false, kind: "error", code: "bad_request" /* BadRequest */, errors: sortErrors, query };
3768
+ }
3708
3769
  }
3709
3770
  let docs = await this.model.find({
3710
3771
  ...query,
@@ -5478,6 +5539,7 @@ async function resolveSelectForRequest({
5478
5539
  }
5479
5540
 
5480
5541
  // src/core.ts
5542
+ var emptyPermissionLeaf = () => ({ $: "_" });
5481
5543
  var Core = class {
5482
5544
  constructor(req) {
5483
5545
  this.cachedPermissions = null;
@@ -5681,7 +5743,7 @@ var Core = class {
5681
5743
  }
5682
5744
  addEmptyPermissions(modelName, doc) {
5683
5745
  const docPermissionField = getModelOption(modelName, "documentPermissionField");
5684
- setDocValue(doc, docPermissionField, { _view: { $: "_" }, _edit: { $: "_" } });
5746
+ setDocValue(doc, docPermissionField, { _view: emptyPermissionLeaf(), _edit: emptyPermissionLeaf() });
5685
5747
  return doc;
5686
5748
  }
5687
5749
  async addDocPermissions(modelName, doc, access, context) {
@@ -5731,8 +5793,8 @@ var Core = class {
5731
5793
  },
5732
5794
  {}
5733
5795
  );
5734
- setDocValue(doc, `${docPermissionField}._view`, viewObj);
5735
- setDocValue(doc, `${docPermissionField}._edit`, editObj);
5796
+ setDocValue(doc, `${docPermissionField}._view`, Object.keys(viewObj).length > 0 ? viewObj : emptyPermissionLeaf());
5797
+ setDocValue(doc, `${docPermissionField}._edit`, Object.keys(editObj).length > 0 ? editObj : emptyPermissionLeaf());
5736
5798
  return doc;
5737
5799
  }
5738
5800
  async decorate(modelName, doc, access, context) {
package/index.mjs CHANGED
@@ -320,6 +320,41 @@ function normalizeSortForOrderBy(sort) {
320
320
  orders: normalized.fields.map(({ direction }) => direction)
321
321
  };
322
322
  }
323
+ function sanitizeSortFields(sort, allowedFields) {
324
+ const { fields, errors } = normalizeSort(sort);
325
+ if (errors.length > 0) return { sort: void 0, stripped: [], errors };
326
+ const allowedSet = new Set(allowedFields.concat(["id", "_id"]));
327
+ const kept = fields.filter(({ field }) => allowedSet.has(field));
328
+ const stripped = fields.filter(({ field }) => !allowedSet.has(field)).map(({ field }) => field);
329
+ if (stripped.length === 0) return { sort, stripped, errors: [] };
330
+ if (kept.length === 0) return { sort: void 0, stripped, errors: [] };
331
+ if (typeof sort === "string") {
332
+ return {
333
+ sort: kept.map(({ field, direction }) => direction === "desc" ? `-${field}` : field).join(" "),
334
+ stripped,
335
+ errors: []
336
+ };
337
+ }
338
+ if (sort instanceof Map) {
339
+ return {
340
+ sort: new Map(kept.map(({ field, direction }) => [field, direction])),
341
+ stripped,
342
+ errors: []
343
+ };
344
+ }
345
+ if (Array.isArray(sort)) {
346
+ return {
347
+ sort: kept.map(({ field, direction }) => [field, direction]),
348
+ stripped,
349
+ errors: []
350
+ };
351
+ }
352
+ return {
353
+ sort: Object.fromEntries(kept.map(({ field, direction }) => [field, direction])),
354
+ stripped,
355
+ errors: []
356
+ };
357
+ }
323
358
 
324
359
  // src/helpers/index.ts
325
360
  import { forEach, isArray as isArray2, isEmpty, isObject, isPlainObject as isPlainObject4, isString as isString3 } from "@web-ts-toolkit/utils";
@@ -3481,6 +3516,10 @@ var Service = class extends Base {
3481
3516
  asServiceHookContext(context) {
3482
3517
  return context;
3483
3518
  }
3519
+ getEffectiveAllowedSortFields(allowedSortFields) {
3520
+ const extra = this.options?.sortableFields ?? [];
3521
+ return extra.length > 0 ? [...allowedSortFields, ...extra] : allowedSortFields;
3522
+ }
3484
3523
  beginOp(op, filter2, extra) {
3485
3524
  const startedAt = Date.now();
3486
3525
  debug({
@@ -3527,14 +3566,18 @@ var Service = class extends Base {
3527
3566
  const { includes, correlatedIncludes, includeLocalFields, includePaths, correlatedReferenceFields } = processedInclude;
3528
3567
  const correlatedOutputPaths = correlatedIncludes.map((entry) => entry.path);
3529
3568
  const finalSelect = normalizeSelect(_select).concat(includeLocalFields, correlatedReferenceFields);
3569
+ const effectiveAllowedSortFields = this.getEffectiveAllowedSortFields(allowedSortFields);
3570
+ const stripDisallowedSort = this.options?.stripDisallowedSort ?? false;
3571
+ const sanitizedSort = stripDisallowedSort ? sanitizeSortFields(sort, effectiveAllowedSortFields) : null;
3572
+ const effectiveSort = stripDisallowedSort ? sanitizedSort?.sort : sort;
3530
3573
  const query = {
3531
3574
  filter: _filter,
3532
3575
  select: finalSelect,
3533
- sort,
3576
+ sort: effectiveSort,
3534
3577
  populate: _populate
3535
3578
  };
3536
3579
  const startedAt = this.beginOp("findOne", _filter, {
3537
- sort,
3580
+ sort: effectiveSort,
3538
3581
  selectCount: finalSelect.length,
3539
3582
  populateCount: Array.isArray(_populate) ? _populate.length : _populate ? 1 : 0
3540
3583
  });
@@ -3542,10 +3585,17 @@ var Service = class extends Base {
3542
3585
  this.completeOp("findOne", startedAt, "forbidden" /* Forbidden */, _filter);
3543
3586
  return { success: false, kind: "error", code: "forbidden" /* Forbidden */, query };
3544
3587
  }
3545
- const sortErrors = validateSortFields(sort, allowedSortFields);
3546
- if (sortErrors.length > 0) {
3547
- this.completeOp("findOne", startedAt, "bad_request" /* BadRequest */, _filter);
3548
- return { success: false, kind: "error", code: "bad_request" /* BadRequest */, errors: sortErrors, query };
3588
+ if (stripDisallowedSort) {
3589
+ if (sanitizedSort && sanitizedSort.errors.length > 0) {
3590
+ this.completeOp("findOne", startedAt, "bad_request" /* BadRequest */, _filter);
3591
+ return { success: false, kind: "error", code: "bad_request" /* BadRequest */, errors: sanitizedSort.errors, query };
3592
+ }
3593
+ } else {
3594
+ const sortErrors = validateSortFields(sort, effectiveAllowedSortFields);
3595
+ if (sortErrors.length > 0) {
3596
+ this.completeOp("findOne", startedAt, "bad_request" /* BadRequest */, _filter);
3597
+ return { success: false, kind: "error", code: "bad_request" /* BadRequest */, errors: sortErrors, query };
3598
+ }
3549
3599
  }
3550
3600
  let doc = await this.model.findOne({ ...query, lean });
3551
3601
  if (!doc) {
@@ -3649,15 +3699,19 @@ var Service = class extends Base {
3649
3699
  const filteredPopulate = isArray8(finalSelect) && isArray8(_populate) ? _populate.filter((p) => finalSelect.includes(p.path.split(".")[0])) : _populate;
3650
3700
  const { includes, correlatedIncludes, includeLocalFields, includePaths, correlatedReferenceFields } = processedInclude;
3651
3701
  const correlatedOutputPaths = correlatedIncludes.map((entry) => entry.path);
3702
+ const effectiveAllowedSortFields = this.getEffectiveAllowedSortFields(allowedSortFields);
3703
+ const stripDisallowedSort = this.options?.stripDisallowedSort ?? false;
3704
+ const sanitizedSort = stripDisallowedSort ? sanitizeSortFields(sort, effectiveAllowedSortFields) : null;
3705
+ const effectiveSort = stripDisallowedSort ? sanitizedSort?.sort : sort;
3652
3706
  const query = {
3653
3707
  filter: _filter,
3654
3708
  select: finalSelect.concat(includeLocalFields, correlatedReferenceFields),
3655
3709
  populate: filteredPopulate,
3656
- sort,
3710
+ sort: effectiveSort,
3657
3711
  ...pagination
3658
3712
  };
3659
3713
  const startedAt = this.beginOp("find", _filter, {
3660
- sort,
3714
+ sort: effectiveSort,
3661
3715
  skip: pagination.skip,
3662
3716
  limit: pagination.limit,
3663
3717
  selectCount: finalSelect.concat(includeLocalFields, correlatedReferenceFields).length,
@@ -3667,10 +3721,17 @@ var Service = class extends Base {
3667
3721
  this.completeOp("find", startedAt, "forbidden" /* Forbidden */, _filter);
3668
3722
  return { success: false, kind: "error", code: "forbidden" /* Forbidden */, query };
3669
3723
  }
3670
- const sortErrors = validateSortFields(sort, allowedSortFields);
3671
- if (sortErrors.length > 0) {
3672
- this.completeOp("find", startedAt, "bad_request" /* BadRequest */, _filter);
3673
- return { success: false, kind: "error", code: "bad_request" /* BadRequest */, errors: sortErrors, query };
3724
+ if (stripDisallowedSort) {
3725
+ if (sanitizedSort && sanitizedSort.errors.length > 0) {
3726
+ this.completeOp("find", startedAt, "bad_request" /* BadRequest */, _filter);
3727
+ return { success: false, kind: "error", code: "bad_request" /* BadRequest */, errors: sanitizedSort.errors, query };
3728
+ }
3729
+ } else {
3730
+ const sortErrors = validateSortFields(sort, effectiveAllowedSortFields);
3731
+ if (sortErrors.length > 0) {
3732
+ this.completeOp("find", startedAt, "bad_request" /* BadRequest */, _filter);
3733
+ return { success: false, kind: "error", code: "bad_request" /* BadRequest */, errors: sortErrors, query };
3734
+ }
3674
3735
  }
3675
3736
  let docs = await this.model.find({
3676
3737
  ...query,
@@ -5455,6 +5516,7 @@ async function resolveSelectForRequest({
5455
5516
  }
5456
5517
 
5457
5518
  // src/core.ts
5519
+ var emptyPermissionLeaf = () => ({ $: "_" });
5458
5520
  var Core = class {
5459
5521
  constructor(req) {
5460
5522
  this.cachedPermissions = null;
@@ -5658,7 +5720,7 @@ var Core = class {
5658
5720
  }
5659
5721
  addEmptyPermissions(modelName, doc) {
5660
5722
  const docPermissionField = getModelOption(modelName, "documentPermissionField");
5661
- setDocValue(doc, docPermissionField, { _view: { $: "_" }, _edit: { $: "_" } });
5723
+ setDocValue(doc, docPermissionField, { _view: emptyPermissionLeaf(), _edit: emptyPermissionLeaf() });
5662
5724
  return doc;
5663
5725
  }
5664
5726
  async addDocPermissions(modelName, doc, access, context) {
@@ -5708,8 +5770,8 @@ var Core = class {
5708
5770
  },
5709
5771
  {}
5710
5772
  );
5711
- setDocValue(doc, `${docPermissionField}._view`, viewObj);
5712
- setDocValue(doc, `${docPermissionField}._edit`, editObj);
5773
+ setDocValue(doc, `${docPermissionField}._view`, Object.keys(viewObj).length > 0 ? viewObj : emptyPermissionLeaf());
5774
+ setDocValue(doc, `${docPermissionField}._edit`, Object.keys(editObj).length > 0 ? editObj : emptyPermissionLeaf());
5713
5775
  return doc;
5714
5776
  }
5715
5777
  async decorate(modelName, doc, access, context) {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@web-ts-toolkit/access-router",
3
3
  "description": "ACL-aware Express routers and in-memory data services for Mongoose-backed APIs",
4
4
  "homepage": "https://web-ts-toolkit.pages.dev/docs/packages/access-router",
5
- "version": "0.46.0",
5
+ "version": "0.47.0",
6
6
  "sideEffects": [
7
7
  "./**/index.js",
8
8
  "./**/index.mjs",
@@ -57,8 +57,8 @@
57
57
  "node": ">=22"
58
58
  },
59
59
  "dependencies": {
60
- "@web-ts-toolkit/express-json-router": "0.46.0",
61
- "@web-ts-toolkit/utils": "0.46.0",
60
+ "@web-ts-toolkit/express-json-router": "0.47.0",
61
+ "@web-ts-toolkit/utils": "0.47.0",
62
62
  "just-diff": "^6.0.2",
63
63
  "mongoose-schema-jsonschema": "^4.0.1",
64
64
  "sift": "^17.1.3",
@@ -40,6 +40,7 @@ declare class Service<TModel = unknown> extends Base<TModel> {
40
40
  protected createModelAdapter(modelName: string): any;
41
41
  protected getModelRouterOptions(modelName: string): ModelRouterOptions<TModel>;
42
42
  private asServiceHookContext;
43
+ private getEffectiveAllowedSortFields;
43
44
  private beginOp;
44
45
  private completeOp;
45
46
  constructor(req: ModelRequest, modelName: string);
@@ -1715,6 +1716,19 @@ interface DefaultModelRouterOptions<TModel = unknown> {
1715
1716
  mutationRouteSegment?: string;
1716
1717
  operationAccess?: Validation | OperationAccess;
1717
1718
  modelPermissionPrefix?: string;
1719
+ /**
1720
+ * Extra fields allowed in `sort` regardless of `list`/`read` field policy.
1721
+ * Merged as a union with permission-derived allowed fields (`id`/`_id` are
1722
+ * always allowed). Does not grant output visibility, only sortability.
1723
+ */
1724
+ sortableFields?: string[];
1725
+ /**
1726
+ * When `true`, disallowed `sort` keys are omitted from the sort sent upstream
1727
+ * (Mongoose) instead of returning `BadRequest`. Malformed sort syntax still
1728
+ * returns `BadRequest`. If every key is stripped, no sort is applied.
1729
+ * Defaults to `false` (strict: disallowed sort returns `BadRequest`).
1730
+ */
1731
+ stripDisallowedSort?: boolean;
1718
1732
  }
1719
1733
  interface ExtendedDefaultModelRouterOptions<TModel = unknown> extends DefaultModelRouterOptions<TModel> {
1720
1734
  'operationAccess.default'?: Validation;
@@ -40,6 +40,7 @@ declare class Service<TModel = unknown> extends Base<TModel> {
40
40
  protected createModelAdapter(modelName: string): any;
41
41
  protected getModelRouterOptions(modelName: string): ModelRouterOptions<TModel>;
42
42
  private asServiceHookContext;
43
+ private getEffectiveAllowedSortFields;
43
44
  private beginOp;
44
45
  private completeOp;
45
46
  constructor(req: ModelRequest, modelName: string);
@@ -1715,6 +1716,19 @@ interface DefaultModelRouterOptions<TModel = unknown> {
1715
1716
  mutationRouteSegment?: string;
1716
1717
  operationAccess?: Validation | OperationAccess;
1717
1718
  modelPermissionPrefix?: string;
1719
+ /**
1720
+ * Extra fields allowed in `sort` regardless of `list`/`read` field policy.
1721
+ * Merged as a union with permission-derived allowed fields (`id`/`_id` are
1722
+ * always allowed). Does not grant output visibility, only sortability.
1723
+ */
1724
+ sortableFields?: string[];
1725
+ /**
1726
+ * When `true`, disallowed `sort` keys are omitted from the sort sent upstream
1727
+ * (Mongoose) instead of returning `BadRequest`. Malformed sort syntax still
1728
+ * returns `BadRequest`. If every key is stripped, no sort is applied.
1729
+ * Defaults to `false` (strict: disallowed sort returns `BadRequest`).
1730
+ */
1731
+ stripDisallowedSort?: boolean;
1718
1732
  }
1719
1733
  interface ExtendedDefaultModelRouterOptions<TModel = unknown> extends DefaultModelRouterOptions<TModel> {
1720
1734
  'operationAccess.default'?: Validation;