@web-ts-toolkit/access-router 0.52.0 → 0.54.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/README.md +175 -14
- package/advanced.d.mts +1 -4
- package/advanced.d.ts +1 -4
- package/advanced.js +81 -5
- package/advanced.mjs +81 -5
- package/index.d.mts +7 -4
- package/index.d.ts +7 -4
- package/index.js +840 -658
- package/index.mjs +436 -254
- package/llms.txt +4 -1
- package/package.json +3 -3
- package/{parsers-BnmChTfF.d.mts → parsers-ZSrF7SNu.d.mts} +71 -26
- package/{parsers-BnmChTfF.d.ts → parsers-ZSrF7SNu.d.ts} +71 -26
- package/processors.js +86 -47
- package/processors.mjs +49 -10
package/README.md
CHANGED
|
@@ -18,6 +18,7 @@ ACL-aware Express routers and in-memory data services for Mongoose-backed APIs.
|
|
|
18
18
|
[Persistence limits](#persistence-concurrency-and-resource-limits)
|
|
19
19
|
|
|
20
20
|
**Migration:** [Removed overrides](#breaking-release-service-overrides-migration) ·
|
|
21
|
+
[Server-owned hydration](#breaking-release-server-owned-hydration) ·
|
|
21
22
|
[Named helpers](#breaking-release-named-helpers-and-default-behavior) ·
|
|
22
23
|
[Distinct values](#distinct-whole-value-request-authorization) ·
|
|
23
24
|
[Numeric grouped counts](#numeric-grouped-count-service-api-breaking-migration) ·
|
|
@@ -124,11 +125,11 @@ package-managed execution, falling back to `defaultRuntime` outside it.
|
|
|
124
125
|
| Layer / public type | Where to put it | Scope and examples |
|
|
125
126
|
| ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
126
127
|
| Runtime/global — `GlobalOptions` | `api.setGlobalOptions({...})`, `api.setGlobalOption(key, value)`; `api.set` is an alias for these forms | That runtime's request grants (`globalPermissions`, `requestPermissionField`), logger, registered-populate policy and `requestComplexity`. |
|
|
127
|
-
| Model defaults — `DefaultModelRouterOptions` | `api.setDefaultModelOptions({...})`, `api.setDefaultModelOption(path, value)` | Shared model starting values such as `listHardLimit`, IDs, route segments, `operationAccess` and metadata posture. Data/root routers do not inherit them.
|
|
128
|
-
| Model router — `ModelRouterOptions<Model, Virtuals>` | `api.createRouter(Model, {...})`, then `router.setOptions`, `router.setOption` / `router.set` | One registered model's guards, `permissionSchema`, hooks, virtuals, request schemas and method defaults. Routers for the same model/runtime share its stored options.
|
|
128
|
+
| Model defaults — `DefaultModelRouterOptions` | `api.setDefaultModelOptions({...})`, `api.setDefaultModelOption(path, value)` | Shared model starting values such as `listHardLimit`, IDs, route segments, `operationAccess`, `hydration` and metadata posture. Data/root routers do not inherit them. |
|
|
129
|
+
| Model router — `ModelRouterOptions<Model, Virtuals>` | `api.createRouter(Model, {...})`, then `router.setOptions`, `router.setOption` / `router.set` | One registered model's guards, `permissionSchema`, hooks, virtuals, request schemas, `hydration` and method defaults. Routers for the same model/runtime share its stored options. |
|
|
129
130
|
| Data router — `DataRouterOptions<Data>` | `api.createDataRouter(name, {...})`, its setters, or `api.runtime.setDataOptions` / `setDataOption` | Owned in-memory `data`, list/read guards, request-only fields/filters and decorators. No model `defaults` or model authorization policy. Set `idParam` and `idField` explicitly for data identifier routes. |
|
|
130
131
|
| Root router — `RootRouterOptions` | Single-argument `api.createRouter({ basePath, operationAccess, ... })` | The batch endpoint's scalar guard and batch/order/whole-operation limits; each target keeps its own policy. |
|
|
131
|
-
| Per-method defaults — `Defaults<Model>` from `/advanced` | `ModelRouterOptions.defaults`, e.g. `defaults.publicListArgs` or `defaults.findOptions` | Query/presentation defaults for the **named method**, not global settings or trusted authority. Public wrappers and internal methods have separate buckets.
|
|
132
|
+
| Per-method defaults — `Defaults<Model>` from `/advanced` | `ModelRouterOptions.defaults`, e.g. `defaults.publicListArgs` or `defaults.findOptions` | Query/presentation defaults for the **named method**, not hydration, global settings or trusted authority. Public wrappers and internal methods have separate buckets. |
|
|
132
133
|
| Wire query / `args` / `options` | GET query, advanced body, or root entry | Request-controlled selection, sorting, pagination and allowed presentation options; placement and spelling depend on transport (below). |
|
|
133
134
|
| Trusted per-call policy — `ServiceAuthorization`, `MutationAuthorization`, etc. | The internal service's final `options.authorization` | Server-owned, method-specific row/input/output/related authority. Absent dimensions use request authority. Never a router default, HTTP option or reusable permission mutation. |
|
|
134
135
|
|
|
@@ -164,8 +165,9 @@ package-managed execution, falling back to `defaultRuntime` outside it.
|
|
|
164
165
|
and selection meanings still apply. Public `_list`/`_read`/`_create`/`_update`
|
|
165
166
|
resolve `public*Args`/`public*Options` first, then forward resolved values to
|
|
166
167
|
internal methods. A still-undefined query setting can reach the internal bucket;
|
|
167
|
-
an already resolved built-in (such as public list `
|
|
168
|
-
over that internal default. By-ID delegations similarly forward
|
|
168
|
+
an already resolved built-in (such as public list `includeCount: false`) takes
|
|
169
|
+
precedence over that internal default. By-ID delegations similarly forward
|
|
170
|
+
resolved values. Hydration is separate model configuration, not a method value.
|
|
169
171
|
Public `_upsert` uses the public create or update bucket for its branch; trusted
|
|
170
172
|
`upsert` has `upsertArgs`/`upsertOptions`. There is no `publicUpsertOptions` bucket.
|
|
171
173
|
5. **Metadata posture is absolute.** Model `stripPermissionsField: true` removes
|
|
@@ -179,6 +181,8 @@ The supported `Defaults` buckets are `findArgs`/`findOptions`,
|
|
|
179
181
|
`updateByIdArgs`/`updateByIdOptions`, `upsertArgs`/`upsertOptions`, `existsOptions`,
|
|
180
182
|
and the four `publicList`, `publicRead`, `publicCreate`, `publicUpdate` Args/Options
|
|
181
183
|
pairs. There is no general `defaults.options`, count, or data-method bucket.
|
|
184
|
+
An explicit `service.defaults` assignment replaces the entire runtime defaults bag
|
|
185
|
+
for that service; it does not merge buckets. Neither form selects hydration.
|
|
182
186
|
|
|
183
187
|
<!-- doc-example: partial -->
|
|
184
188
|
|
|
@@ -246,8 +250,9 @@ GET flag values are strings `true`/`false`; body/root flags are booleans. The ta
|
|
|
246
250
|
describes list/read fields on routes that support them, not arbitrary forwarding.
|
|
247
251
|
GET lists start with `{}` as their client filter; use an advanced body for `filter`,
|
|
248
252
|
`populate` or `include`. Model GET-by-ID also accepts `select`; basic data GET-by-ID
|
|
249
|
-
does not project query selection (use its advanced read). `lean`
|
|
250
|
-
|
|
253
|
+
does not project query selection (use its advanced read). Neither `lean` nor
|
|
254
|
+
`hydration` is a supported service/wire option; use server model configuration.
|
|
255
|
+
Mutation bodies use
|
|
251
256
|
top-level `data`/`select`/`populate`/`tasks` and their own allowed `options`; see
|
|
252
257
|
[advanced mutation validation](#advanced-mutation-validation).
|
|
253
258
|
|
|
@@ -270,7 +275,7 @@ separate from both objects. Root entries keep `target`, `name`, base `op`, `filt
|
|
|
270
275
|
| `requestSchemas` / `validate` / `prepare` / `transform` | HTTP parsing / admitted model-input validation / trusted data preparation / live-document mutation before save. |
|
|
271
276
|
| `populate` / `include` / `related` | Declared Mongoose references / output-only related query attachments / independent trusted target policy for an exact requested path. |
|
|
272
277
|
| `access` / `populateAccess` | Method-specific effective row/field access / target populate access (`list` or `read` on the wire). Neither chooses a basic/advanced route variant. |
|
|
273
|
-
| `
|
|
278
|
+
| Model `hydration` / `skim` / metadata flags | Server-owned Mongoose fetch choice / deprecated per-call no-op / serialization and field-map choices. All preserve authorization. |
|
|
274
279
|
| `maxConcurrentOperations` / `maxHookConcurrency` / `maxBulkConcurrency` | Whole root operations per order group / request-runtime hook chains / request-runtime leaf persistence operations. Separate counted units and pools. |
|
|
275
280
|
| `count` / `includeCount` / `countByFieldValues` | One exact numeric query result / list match-total option / bounded numeric counts per original key alias. Returned-row counts and overlapping per-key counts are not union totals. |
|
|
276
281
|
|
|
@@ -279,11 +284,160 @@ separate from both objects. Root entries keep `target`, `name`, base `op`, `filt
|
|
|
279
284
|
`skim` remains accepted in existing service/default and supported wire option slots
|
|
280
285
|
for compatibility, but is **deprecated and has no behavioral effect** in canonical
|
|
281
286
|
model operations. True, false and omission all keep field/row authorization, document
|
|
282
|
-
grants, virtuals and decoration. Remove it from new code. Use `
|
|
283
|
-
|
|
287
|
+
grants, virtuals and decoration. Remove it from new code. Use model `hydration`
|
|
288
|
+
configuration for fetch mode, `includePermissions`/`includeFieldPermissions` for metadata, or the
|
|
284
289
|
router's absolute metadata postures; none skips authorization. Existing examples
|
|
285
290
|
that retain `skim` below demonstrate this compatibility contract.
|
|
286
291
|
|
|
292
|
+
### Breaking release: server-owned hydration
|
|
293
|
+
|
|
294
|
+
**Removed:** per-call `lean` from `PublicListOptions`, `PublicReadOptions`,
|
|
295
|
+
`FindOptions`, `FindOneOptions`, inherited `FindByIdOptions`, and
|
|
296
|
+
`SubdocumentParentOptions`. There is no renamed per-call, client, GET/body/root,
|
|
297
|
+
include or populate hydration switch. Raw Mongoose `.lean()` remains supported.
|
|
298
|
+
|
|
299
|
+
Configure the optional **model-level** `hydration: ModelHydrationOptions` record.
|
|
300
|
+
Both it and `HydrationMode = 'lean' | 'hydrated'` are exported from the package root
|
|
301
|
+
and `/advanced`. Exactly these five independent entries are supported:
|
|
302
|
+
|
|
303
|
+
| Entry | Built-in mode | Applies to |
|
|
304
|
+
| ------------ | ------------- | ------------------------------------------------------------------------------------------------- |
|
|
305
|
+
| `publicList` | `'lean'` | Public `_list`, direct/root model lists |
|
|
306
|
+
| `publicRead` | `'hydrated'` | Public `_read`/`_readFilter`, identifier/filter routes and both attempts of read-to-list fallback |
|
|
307
|
+
| `find` | `'hydrated'` | Internal service `find` |
|
|
308
|
+
| `findOne` | `'hydrated'` | Internal service `findOne` |
|
|
309
|
+
| `findById` | `'hydrated'` | Internal service `findById`, independently of `findOne` |
|
|
310
|
+
|
|
311
|
+
<!-- doc-example: partial -->
|
|
312
|
+
|
|
313
|
+
```ts
|
|
314
|
+
import mongoose from 'mongoose';
|
|
315
|
+
import { createAccessRuntime, type ModelRouterOptions } from '@web-ts-toolkit/access-router';
|
|
316
|
+
import type { ModelRequest } from '@web-ts-toolkit/access-router/advanced';
|
|
317
|
+
|
|
318
|
+
const api = createAccessRuntime();
|
|
319
|
+
const Thing = mongoose.model('Thing', new mongoose.Schema({ name: String }));
|
|
320
|
+
// Server-owned hydration migration: configure once, not around each request.
|
|
321
|
+
const options = {
|
|
322
|
+
operationAccess: { list: true, read: true },
|
|
323
|
+
permissionSchema: { name: true },
|
|
324
|
+
// Before: defaults.publicListOptions.lean = false; findOneOptions.lean = true.
|
|
325
|
+
hydration: { publicList: 'hydrated', findOne: 'lean', find: 'lean' },
|
|
326
|
+
defaults: { publicListOptions: { includeCount: true } },
|
|
327
|
+
} satisfies ModelRouterOptions;
|
|
328
|
+
const router = api.createRouter(Thing, options);
|
|
329
|
+
router.setOption('hydration.publicRead', 'lean'); // Keeps the other stored entries.
|
|
330
|
+
|
|
331
|
+
export async function findThings(req: ModelRequest) {
|
|
332
|
+
// req must be initialized by this runtime's middleware (for example router.routes).
|
|
333
|
+
const service = router.getService(req);
|
|
334
|
+
// Before: service.defaults = { findOptions: { lean: true, includeCount: true } }.
|
|
335
|
+
// Fetch mode is now model-wide hydration.find above, not service-instance state.
|
|
336
|
+
service.defaults = { findOptions: { includeCount: true } };
|
|
337
|
+
return service.find({}); // No fetch-mode option.
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
Supported writers are model construction/router setters,
|
|
342
|
+
`api.runtime.setModelOptions` / `setModelOption`, and starting defaults through
|
|
343
|
+
`api.setDefaultModelOptions` / `setDefaultModelOption` (also on `api.runtime`).
|
|
344
|
+
`GlobalOptions`, data/root router options, method `defaults`, `service.defaults`
|
|
345
|
+
and client defaults are not hydration scopes. Decorator applications use the same
|
|
346
|
+
record through `@Router`, per-model/default `@RouterOptions`, `@ModelOption` and
|
|
347
|
+
`@DefaultModelOption`; see `@web-ts-toolkit/access-router-deco`'s installed README
|
|
348
|
+
for its compiling configuration example.
|
|
349
|
+
No dedicated hydration decorator is needed.
|
|
350
|
+
|
|
351
|
+
Assignment follows `{ ...runtimeStartingDefaults, ...storedModelOptions,
|
|
352
|
+
...incomingModelOptions }`: a supplied hydration record **replaces** the previous
|
|
353
|
+
record, not individual members. Omitted/undefined entries use the matrix's
|
|
354
|
+
built-ins, never an older record's members or generic nested `.default` lookup.
|
|
355
|
+
For example, replacing `{ publicList: 'hydrated' }` with `{ find: 'lean' }`
|
|
356
|
+
restores public lists to their built-in lean mode. The five exact
|
|
357
|
+
`hydration.<entry>` setters change one stored member; member `undefined` clears
|
|
358
|
+
that override and whole-record `undefined` clears the setting. Starting-default
|
|
359
|
+
changes do not broadcast over an existing stored record. Default providers obey
|
|
360
|
+
the same shallow semantics and existing decorator precedence.
|
|
361
|
+
|
|
362
|
+
Only plain records with those five keys and mode strings (or `undefined`) are
|
|
363
|
+
valid; scalars, null, arrays, unknown keys and invalid modes throw a path-bearing
|
|
364
|
+
`TypeError` **before publication**. Failed updates preserve the prior snapshot;
|
|
365
|
+
failed decorator bootstrap rolls back package-controlled state. Fresh service
|
|
366
|
+
calls capture their owning runtime/model's current configuration; suspended calls,
|
|
367
|
+
read fallback and already-captured related work retain their capture, even if
|
|
368
|
+
another runtime later replaces `req.macl`.
|
|
369
|
+
|
|
370
|
+
**Defaults migration:** move each old `defaults.<bucket>.lean` entry as follows;
|
|
371
|
+
convert `true` to `'lean'` and `false` to `'hydrated'`:
|
|
372
|
+
|
|
373
|
+
| Old bucket | New model setting |
|
|
374
|
+
| ------------------- | ---------------------- |
|
|
375
|
+
| `publicListOptions` | `hydration.publicList` |
|
|
376
|
+
| `publicReadOptions` | `hydration.publicRead` |
|
|
377
|
+
| `findOptions` | `hydration.find` |
|
|
378
|
+
| `findOneOptions` | `hydration.findOne` |
|
|
379
|
+
| `findByIdOptions` | `hydration.findById` |
|
|
380
|
+
|
|
381
|
+
Keep unrelated presentation defaults in their existing buckets. Old `lean` keys,
|
|
382
|
+
even `undefined`, and `hydration` keys in method-option buckets throw migration
|
|
383
|
+
diagnostics instead of being translated or silently ignored. This covers model
|
|
384
|
+
setters, synchronous `service.defaults` assignment, and later mutation of an
|
|
385
|
+
assigned defaults bag detected before querying. Other methods explain their fixed
|
|
386
|
+
mode rather than offer a replacement knob. Moving a former `service.defaults`
|
|
387
|
+
override changes **all services for that model in its runtime**, not just one
|
|
388
|
+
service instance; make that choice deliberately, never emulate request-local mode
|
|
389
|
+
by changing shared configuration around a call.
|
|
390
|
+
|
|
391
|
+
**Old JavaScript/wire inputs:** stale `lean` or `hydration` controls in permissive
|
|
392
|
+
service/direct/root/`$$sq`/legacy-include/populate slots are inert and never select
|
|
393
|
+
fetch mode. Strict correlated includes still reject nonempty execution options,
|
|
394
|
+
including these keys. Ordinary business fields named `lean` or `hydration` remain
|
|
395
|
+
valid in filters, selections, mutations and task data. Private execution choices
|
|
396
|
+
are not added to public query/context metadata or response DTOs.
|
|
397
|
+
|
|
398
|
+
| Fixed/related stage | Fetch contract (not a new setting) |
|
|
399
|
+
| --------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
400
|
+
| Legacy/correlated include list/read targets | Fixed lean; read fallback disabled for correlated reads |
|
|
401
|
+
| `$$sq` list/read target | Target's captured `publicList`/`publicRead`; no read fallback |
|
|
402
|
+
| Mongoose populate, including nested targets | Inherits the originating parent query's mode, not target hydration configuration |
|
|
403
|
+
| `getParentDoc(id, sub, args?, { access? })`, `findRawParentDoc({ filter, select, populate })` | Raw hydrated parent/null; not finalized DTOs or permission metadata. `getParentDoc` keeps its row/projection/populate checks; the low-level raw adapter helper is not an authorization boundary |
|
|
404
|
+
| Dedicated subdocument read/mutation parent; `readSub` populate | Fixed hydrated parent/live document; post-save visibility re-fetch alone stays fixed lean |
|
|
405
|
+
| Create/new, update/upsert mutation lookup/save, delete hooks | Live hydrated documents for setters, validation, saves and deletion, regardless of read configuration |
|
|
406
|
+
| Exists/public-upsert existence, field-membership queries | Fixed lean `_id` lookups; count/distinct/aggregates do not hydrate document results |
|
|
407
|
+
|
|
408
|
+
**Value caveat:** finalized model results and output-stage hook views are
|
|
409
|
+
plain objects in both modes; this is not a promise of identical values. Hydration
|
|
410
|
+
can apply missing schema defaults, init hooks and schema getters/`toObject`
|
|
411
|
+
transforms that bare lean skips. Package virtuals, authorization, selection,
|
|
412
|
+
decoration and metadata rules still run in both modes. Test your application's
|
|
413
|
+
schema/plugins before switching; no universal JSON parity or measured speedup is
|
|
414
|
+
claimed. Client save-capable `Model` wrappers are a separate client feature.
|
|
415
|
+
|
|
416
|
+
### Finalized permissions alias
|
|
417
|
+
|
|
418
|
+
**Compatibility expansion:** when a package-finalized model row already carries
|
|
419
|
+
serialized permission metadata, `row.permissions` aliases that finalized value at
|
|
420
|
+
`documentPermissionField` (default `_permissions`, also dotted paths such as
|
|
421
|
+
`meta.grants`), independently of hydration and plugin installation. It is a
|
|
422
|
+
non-enumerable, writable, configurable own data property: JSON, `Object.keys` and
|
|
423
|
+
object spread omit the generated alias. It is a convenience value, **not authority
|
|
424
|
+
or a live binding** after application reassignment.
|
|
425
|
+
|
|
426
|
+
Exposure pruning, metadata flags, field-map disabling and empty/placeholder
|
|
427
|
+
metadata apply before aliasing; private/unfiltered grants are never copied from
|
|
428
|
+
raw documents. `stripPermissionsField: true` suppresses both canonical metadata
|
|
429
|
+
and its generated alias. Existing `permissions` output wins, including selected
|
|
430
|
+
business fields, package virtuals and include attachments/descriptors. A canonical
|
|
431
|
+
path of `permissions` or `permissions.grants` keeps its existing enumerable
|
|
432
|
+
property; no separate alias is created.
|
|
433
|
+
|
|
434
|
+
Package-owned copies/related attachments preserve the alias **where metadata is
|
|
435
|
+
already present**; ordinary populated/dedicated subdocument outputs do not gain
|
|
436
|
+
metadata just to create one. Arbitrary application copies/transform replacements
|
|
437
|
+
and client `Model` wrappers need not retain non-enumerable properties. The optional
|
|
438
|
+
[Mongoose plugin](#optional-permissions-plugin) is a separate raw-document getter,
|
|
439
|
+
not a prerequisite for this finalized alias.
|
|
440
|
+
|
|
287
441
|
### Root batch bounds
|
|
288
442
|
|
|
289
443
|
Create the batch endpoint with the **single-options** overload,
|
|
@@ -787,6 +941,7 @@ async function runServiceAuthorizationExample() {
|
|
|
787
941
|
const router = api.createRouter<Order, Virtuals>(OrderModel, {
|
|
788
942
|
basePath: '/orders',
|
|
789
943
|
operationAccess: { read: true },
|
|
944
|
+
hydration: { findOne: 'lean' },
|
|
790
945
|
stripPermissionsField: true,
|
|
791
946
|
baseFilter: { read: () => ({ tenantId: 'request-tenant' }) },
|
|
792
947
|
overrideFilter: {
|
|
@@ -830,7 +985,7 @@ async function runServiceAuthorizationExample() {
|
|
|
830
985
|
...output,
|
|
831
986
|
rows: { mode: 'scope', filter: { tenantId: 'backend' } },
|
|
832
987
|
} as const satisfies ServiceAuthorization<Order, Virtuals>;
|
|
833
|
-
const quiet = { skim: true,
|
|
988
|
+
const quiet = { skim: true, includePermissions: false, includeFieldPermissions: false };
|
|
834
989
|
const selected = { select: ['status', 'internalNote', '-_id'] };
|
|
835
990
|
|
|
836
991
|
async function verifyServiceAuthorization(req: ModelRequest) {
|
|
@@ -1771,6 +1926,7 @@ Root entrypoint (`@web-ts-toolkit/access-router`):
|
|
|
1771
1926
|
- logger helpers: `redactFilter`, `redactPayload`, `safeStringify`, `isLevelEnabled` + `OpLogContext` type
|
|
1772
1927
|
- option helpers: `setGlobalOptions`, `setGlobalOption`, `getGlobalOptions`, `getGlobalOption`, `setModelOptions`, `setModelOption`, `getModelOptions`, `getModelOption`, `getModelNames`, `getModelJsonSchema`, `setDefaultModelOptions`, `setDefaultModelOption`, `getDefaultModelOptions`, `getDefaultModelOption`
|
|
1773
1928
|
- route-policy types: `OperationAccess`, `SubOperationAccess`, `Validation`, `GuardHook`, `RouteVariantAccess`, `ModelRouterOptions`, `DefaultModelRouterOptions`, `DataRouterOptions`, `ExtendedModelRouterOptions`, `ExtendedDefaultModelRouterOptions`, and `ExtendedDataRouterOptions` for typed setters; `PermissionSchema` / `FieldOperationAccess` are separate base-operation field grants. These types are also available from `/advanced`.
|
|
1929
|
+
- fetch configuration types (also `/advanced`): `HydrationMode`, `ModelHydrationOptions` — server-owned model/default configuration, never per-call/wire options.
|
|
1774
1930
|
- trusted service policy types (also `/advanced`): `ServiceAuthorization` (reads), `MutationAuthorization` (update/upsert), `CreateAuthorization`, `InputFieldAuthorization`, `InputFieldPath`, `OutputAuthorization`, `FieldAuthorization`, `RowAuthorization`, `OperationAuthorization`, `RelatedAuthorization`, `OutputFieldPath`. Input paths use persisted types only; output paths also include virtuals. Unknown models have an explicit runtime-validated string fallback; grant arrays may be readonly.
|
|
1775
1931
|
- named helper/result types (also `/advanced`): `OutputPlanningOptions`, `OutputFieldOptions`, `AllowedOutputFieldOptions`, opaque `DocumentAuthorization`, `ServiceOutputContext`, `ServiceOutputDecorator`, `AuthorizedSingleResult`, `AuthorizedListResult`, `NewArgs`, `NewOptions`. Acquire the service from a router/request; there is no standalone `Service` export or public issuer/execution/prepared API.
|
|
1776
1932
|
|
|
@@ -1952,8 +2108,11 @@ schema.plugin(permissionsPlugin, { modelName: 'User', virtualPermissionField: 'p
|
|
|
1952
2108
|
```
|
|
1953
2109
|
|
|
1954
2110
|
Use it only when application code needs that hydrated-document alias. Package output
|
|
1955
|
-
finalization
|
|
1956
|
-
|
|
2111
|
+
finalization supplies its own [non-enumerable alias](#finalized-permissions-alias)
|
|
2112
|
+
from exposed metadata in both modes, without the plugin. The raw getter retains
|
|
2113
|
+
literal `_doc[documentPermissionField]` lookup (not dotted-path traversal).
|
|
2114
|
+
`virtualPermissionField` names only that raw getter, not the finalized alias or the
|
|
2115
|
+
package's computed `virtuals` API.
|
|
1957
2116
|
|
|
1958
2117
|
## Include Cardinality
|
|
1959
2118
|
|
|
@@ -2315,10 +2474,12 @@ getter fields are type errors (and configuration rejections at runtime).
|
|
|
2315
2474
|
Virtual names are never added to persisted `Filter`, sort/distinct inputs, or
|
|
2316
2475
|
client write types.
|
|
2317
2476
|
|
|
2318
|
-
Lean/hydrated
|
|
2477
|
+
Lean/hydrated normalization: getters always receive an isolated, stable plain-object
|
|
2319
2478
|
view (`toObject({ virtuals: false })` for documents, recursively isolated
|
|
2320
2479
|
copies for lean results, with `Date`/`Buffer`/`ObjectId` cloned by their own
|
|
2321
2480
|
constructors), so package virtuals compute for both lean and hydrated results.
|
|
2481
|
+
Schema defaults/getters/transforms/init hooks can still change their input values;
|
|
2482
|
+
see the [hydration value caveat](#breaking-release-server-owned-hydration).
|
|
2322
2483
|
Only returned field values are committed via document-aware helpers;
|
|
2323
2484
|
`undefined` omits the field; a throw omits it fail-closed with a structural
|
|
2324
2485
|
log (no raw values or secret-bearing text). Sibling virtual values are never
|
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 AllowedOutputFieldOptions, p as ArkTypeErrorsLike, q as ArkTypeLike, r as ArkTypeProblemLike, s as AuthorizedListResult, t as AuthorizedSingleResult, B as BaseFilterAccess, C as Change, u as Codes, v as CorrelatedCountInclude, w as CorrelatedFilter, x as CorrelatedInclude, y as CorrelatedIncludeArgs, z as CorrelatedListInclude, D as CorrelatedReadByFilterInclude, E as CorrelatedReadByIdInclude, F as CountBody, G as CreateArgs, H as CreateAuthorization, I as CreateOptions, J as CreateQueryInput, K as CustomHeaders, L as DATA_MIDDLEWARE, M as DataBaseFilterHook, N as DataFieldOptions, O as DataFilter, P as DataFindArgs, Q as DataFindOneArgs, R as DataFindOneOptions, S as DataFindOptions, T as DataHook, U as DataHookContext, V as DataIdentifierHook, W as DataListHook, X as DataOverrideFilterHook, Y as DataRequest, Z as DataRequestSchemas, _ as DataRouterOptions, $ as DecorateAccess, a0 as DecorateAllAccess, a1 as DeepFieldPath, a2 as DefaultModelRouterOptions, a3 as Defaults, a4 as DistinctArgs, a5 as DistinctBody, a6 as DocPermissionsAccess, a7 as DocumentAuthorization, a8 as ErrorResult, a9 as ExistsOptions, aa as ExtendedDataRouterOptions, ab as ExtendedDefaultModelRouterOptions, ac as ExtendedModelRouterOptions, ad as FieldAuthorization, ae as FieldOperationAccess, af as Filter, ag as FilterOperator, ah as FindAccess, ai as FindArgs, aj as FindByIdArgs, ak as FindByIdOptions, al as FindOneArgs, am as FindOneOptions, an as FindOptions, ao as GlobalOptions, ap as GlobalPermissionValue, aq as GuardHook, ar as
|
|
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 AllowedOutputFieldOptions, p as ArkTypeErrorsLike, q as ArkTypeLike, r as ArkTypeProblemLike, s as AuthorizedListResult, t as AuthorizedSingleResult, B as BaseFilterAccess, C as Change, u as Codes, v as CorrelatedCountInclude, w as CorrelatedFilter, x as CorrelatedInclude, y as CorrelatedIncludeArgs, z as CorrelatedListInclude, D as CorrelatedReadByFilterInclude, E as CorrelatedReadByIdInclude, F as CountBody, G as CreateArgs, H as CreateAuthorization, I as CreateOptions, J as CreateQueryInput, K as CustomHeaders, L as DATA_MIDDLEWARE, M as DataBaseFilterHook, N as DataFieldOptions, O as DataFilter, P as DataFindArgs, Q as DataFindOneArgs, R as DataFindOneOptions, S as DataFindOptions, T as DataHook, U as DataHookContext, V as DataIdentifierHook, W as DataListHook, X as DataOverrideFilterHook, Y as DataRequest, Z as DataRequestSchemas, _ as DataRouterOptions, $ as DecorateAccess, a0 as DecorateAllAccess, a1 as DeepFieldPath, a2 as DefaultModelRouterOptions, a3 as Defaults, a4 as DistinctArgs, a5 as DistinctBody, a6 as DocPermissionsAccess, a7 as DocumentAuthorization, a8 as ErrorResult, a9 as ExistsOptions, aa as ExtendedDataRouterOptions, ab as ExtendedDefaultModelRouterOptions, ac as ExtendedModelRouterOptions, ad as FieldAuthorization, ae as FieldOperationAccess, af as Filter, ag as FilterOperator, ah as FindAccess, ai as FindArgs, aj as FindByIdArgs, ak as FindByIdOptions, al as FindOneArgs, am as FindOneOptions, an as FindOptions, ao as GlobalOptions, ap as GlobalPermissionValue, aq as GuardHook, ar as HydrationMode, as as IdentifierHook, at as Include, au as InputFieldAuthorization, av as InputFieldPath, aw as IoTsContextEntryLike, ax as IoTsDecodeErrorLike, ay as IoTsDecoderLike, az as JoiSchemaLike, aA as JoiValidationErrorDetailLike, aB as KeyValueProjection, aC as LegacyInclude, aD as ListQueryInput, aE as ListResult, aF as MIDDLEWARE, aG as MaybePromise, aH as ModelBaseFilterHook, aI as ModelChangeHook, aJ as ModelDeleteHook, aK as ModelDocPermissionsHook, aL as ModelDocument, aM as ModelDocumentHook, aN as ModelHook, aO as ModelHookContext, aP as ModelHydrationOptions, aQ as ModelIdentifierHook, aR as ModelListHook, aS as ModelOverrideFilterHook, aT as ModelRequest, aU as ModelRouterOptions, aV as ModelValidateHook, aW as ModelVirtualAccess, aX as ModelVirtualAccessRecord, aY as ModelVirtualContext, aZ as ModelVirtualDescriptor, a_ as ModelVirtualDoc, a$ as ModelVirtualGetter, b0 as ModelVirtualLeaf, b1 as ModelVirtualRecordAccess, b2 as ModelVirtuals, b3 as MutationAuthorization, b4 as NewArgs, b5 as NewOptions, b6 as OperationAccess, b7 as OperationAuthorization, b8 as OutputAuthorization, b9 as OutputFieldOptions, ba as OutputFieldPath, bb as OutputPlanningOptions, bc as PERMISSIONS, bd as PERMISSION_KEYS, be as PairedRouteAccess, bf as ParentRef, bg as PathValue, bh as PermissionSchema, bi as Populate, bj as PopulateAccess, bk as PopulatePlanningOptions, bl as PrepareAccess, bm as Projection, bn as PublicCreateArgs, bo as PublicCreateOptions, bp as PublicErrorResult, bq as PublicListArgs, br as PublicListOptions, bs as PublicListResult, bt as PublicOutput, bu as PublicReadArgs, bv as PublicReadOptions, bw as PublicServiceResult, bx as PublicSingleResult, by as PublicSubdocumentCreateOptions, bz as PublicSubdocumentListOptions, bA as PublicSubdocumentMutationOptions, bB as PublicSubdocumentReadOptions, bC as PublicUpdateArgs, bD as PublicUpdateOptions, bE as PublicUpsertArgs, bF as PublicUpsertOptions, bG as ReadQueryInput, bH as RelatedAuthorization, bI as Request, bJ as RequestSchemaAdapter, bK as RequestSchemaFailure, bL as RequestSchemaIssue, bM as RequestSchemaLike, bN as RequestSchemaOptions, bO as RequestSchemaResult, bP as RequestSchemaSuccess, bQ as RequestSchemaValidator, bR as RequestSchemas, bS as RootDataListQueryEntry, bT as RootDataOperation, bU as RootDataReadByFilterQueryEntry, bV as RootDataReadByIdQueryEntry, bW as RootModelCountQueryEntry, bX as RootModelCreateQueryEntry, bY as RootModelDeleteQueryEntry, bZ as RootModelDistinctQueryEntry, b_ as RootModelListQueryEntry, b$ as RootModelNewQueryEntry, c0 as RootModelOperation, c1 as RootModelReadByFilterQueryEntry, c2 as RootModelReadByIdQueryEntry, c3 as RootModelSubBulkUpdateQueryEntry, c4 as RootModelSubCreateQueryEntry, c5 as RootModelSubDeleteQueryEntry, c6 as RootModelSubListQueryEntry, c7 as RootModelSubReadQueryEntry, c8 as RootModelSubUpdateQueryEntry, c9 as RootModelUpdateQueryEntry, ca as RootModelUpsertQueryEntry, cb as RootOperationResult, cc as RootQueryEntry, cd as RootRouterOptions, ce as RootSubOperation, cf as RootTarget, cg as RouteBaseAccess, ch as RouteGuardAccess, ci as RouteVariant, cj as RouteVariantAccess, ck as RowAuthorization, cl as SelectAccess, cm as SelectedPopulatedPublicOutput, cn as SelectedPublicOutput, co as ServiceAuthorization, cp as ServiceOutputContext, cq as ServiceOutputDecorator, cr as ServiceResult, cs as SingleResult, ct as Sort, cu as SortOrder, cv as StandardSchemaFailure, cw as StandardSchemaInferOutput, cx as StandardSchemaIssue, cy as StandardSchemaPathSegment, cz as StandardSchemaResult, cA as StandardSchemaSuccess, cB as StandardSchemaV1, cC as StatusCodes, cD as SubListBody, cE as SubOperationAccess, cF as SubPopulate, cG as SubQueryEntry, cH as SubReadBody, cI as SubRouteGuardOptions, cJ as SubdocumentBulkRecord, cK as SubdocumentBulkUpdateInput, cL as SubdocumentCreateAuthorization, cM as SubdocumentCreateInput, cN as SubdocumentCreateOptions, cO as SubdocumentCreateVisibilityAuthorization, cP as SubdocumentDeleteAuthorization, cQ as SubdocumentDeleteOptions, cR as SubdocumentGateAuthorization, cS as SubdocumentId, cT as SubdocumentInputAuthorization, cU as SubdocumentListOptions, cV as SubdocumentModel, cW as SubdocumentMutationAuthorization, cX as SubdocumentName, cY as SubdocumentOutputAuthorization, cZ as SubdocumentParentArgs, c_ as SubdocumentParentOptions, c$ as SubdocumentReadAuthorization, d0 as SubdocumentReadOptions, d1 as SubdocumentRecord, d2 as SubdocumentUpdateOptions, d3 as SubdocumentVirtuals, d4 as SubdocumentVisibilityAuthorization, d5 as SuperstructFailureLike, d6 as SuperstructValidateLike, d7 as Task, d8 as TaskType, d9 as TransformAccess, da as TypedFilter, db as UpdateByIdArgs, dc as UpdateByIdOptions, dd as UpdateOneArgs, de as UpdateOneOptions, df as UpdateQueryInput, dg as UpsertArgs, dh as UpsertOptions, di as UpsertQueryInput, dj as ValibotIssueLike, dk as ValibotPathItemLike, dl as ValibotSafeParseLike, dm as ValibotSafeParseResult, dn as ValidateAccess, dp as ValidateRule, dq as Validation, dr as ValidationError, ds as VineValidationErrorLike, dt as VineValidationMessageLike, du as VineValidatorLike, dv as VirtualSubModel, dw as WithVirtuals, dx as YupSchemaLike, dy as YupValidationErrorLike, dz as defineRequestSchema, dA as fromAjv, dB as fromArkType, dC as fromIoTs, dD as fromJoi, dE as fromStandardSchema, dF as fromSuperstruct, dG as fromValibot, dH as fromVine, dI as fromYup, dJ as fromZod, dK as parseBody, dL as parseBodyWithSchema, dM as parseNestedBodyWithSchema, dN as parsePathParam, dO as parseQuery } from './parsers-ZSrF7SNu.mjs';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import 'mongoose';
|
|
4
4
|
import 'express';
|
|
@@ -1049,7 +1049,6 @@ declare const rootQuerySchema: z.ZodArray<z.ZodUnion<readonly [z.ZodUnion<readon
|
|
|
1049
1049
|
list: "list";
|
|
1050
1050
|
read: "read";
|
|
1051
1051
|
}>>;
|
|
1052
|
-
lean: z.ZodOptional<z.ZodBoolean>;
|
|
1053
1052
|
}, z.core.$loose>>;
|
|
1054
1053
|
name: z.ZodString;
|
|
1055
1054
|
order: z.ZodOptional<z.ZodNumber>;
|
|
@@ -1228,7 +1227,6 @@ declare const rootQuerySchema: z.ZodArray<z.ZodUnion<readonly [z.ZodUnion<readon
|
|
|
1228
1227
|
list: "list";
|
|
1229
1228
|
read: "read";
|
|
1230
1229
|
}>>;
|
|
1231
|
-
lean: z.ZodOptional<z.ZodBoolean>;
|
|
1232
1230
|
}, z.core.$loose>>;
|
|
1233
1231
|
name: z.ZodString;
|
|
1234
1232
|
order: z.ZodOptional<z.ZodNumber>;
|
|
@@ -1408,7 +1406,6 @@ declare const rootQuerySchema: z.ZodArray<z.ZodUnion<readonly [z.ZodUnion<readon
|
|
|
1408
1406
|
list: "list";
|
|
1409
1407
|
read: "read";
|
|
1410
1408
|
}>>;
|
|
1411
|
-
lean: z.ZodOptional<z.ZodBoolean>;
|
|
1412
1409
|
}, z.core.$loose>>;
|
|
1413
1410
|
name: z.ZodString;
|
|
1414
1411
|
order: z.ZodOptional<z.ZodNumber>;
|
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 AllowedOutputFieldOptions, p as ArkTypeErrorsLike, q as ArkTypeLike, r as ArkTypeProblemLike, s as AuthorizedListResult, t as AuthorizedSingleResult, B as BaseFilterAccess, C as Change, u as Codes, v as CorrelatedCountInclude, w as CorrelatedFilter, x as CorrelatedInclude, y as CorrelatedIncludeArgs, z as CorrelatedListInclude, D as CorrelatedReadByFilterInclude, E as CorrelatedReadByIdInclude, F as CountBody, G as CreateArgs, H as CreateAuthorization, I as CreateOptions, J as CreateQueryInput, K as CustomHeaders, L as DATA_MIDDLEWARE, M as DataBaseFilterHook, N as DataFieldOptions, O as DataFilter, P as DataFindArgs, Q as DataFindOneArgs, R as DataFindOneOptions, S as DataFindOptions, T as DataHook, U as DataHookContext, V as DataIdentifierHook, W as DataListHook, X as DataOverrideFilterHook, Y as DataRequest, Z as DataRequestSchemas, _ as DataRouterOptions, $ as DecorateAccess, a0 as DecorateAllAccess, a1 as DeepFieldPath, a2 as DefaultModelRouterOptions, a3 as Defaults, a4 as DistinctArgs, a5 as DistinctBody, a6 as DocPermissionsAccess, a7 as DocumentAuthorization, a8 as ErrorResult, a9 as ExistsOptions, aa as ExtendedDataRouterOptions, ab as ExtendedDefaultModelRouterOptions, ac as ExtendedModelRouterOptions, ad as FieldAuthorization, ae as FieldOperationAccess, af as Filter, ag as FilterOperator, ah as FindAccess, ai as FindArgs, aj as FindByIdArgs, ak as FindByIdOptions, al as FindOneArgs, am as FindOneOptions, an as FindOptions, ao as GlobalOptions, ap as GlobalPermissionValue, aq as GuardHook, ar as
|
|
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 AllowedOutputFieldOptions, p as ArkTypeErrorsLike, q as ArkTypeLike, r as ArkTypeProblemLike, s as AuthorizedListResult, t as AuthorizedSingleResult, B as BaseFilterAccess, C as Change, u as Codes, v as CorrelatedCountInclude, w as CorrelatedFilter, x as CorrelatedInclude, y as CorrelatedIncludeArgs, z as CorrelatedListInclude, D as CorrelatedReadByFilterInclude, E as CorrelatedReadByIdInclude, F as CountBody, G as CreateArgs, H as CreateAuthorization, I as CreateOptions, J as CreateQueryInput, K as CustomHeaders, L as DATA_MIDDLEWARE, M as DataBaseFilterHook, N as DataFieldOptions, O as DataFilter, P as DataFindArgs, Q as DataFindOneArgs, R as DataFindOneOptions, S as DataFindOptions, T as DataHook, U as DataHookContext, V as DataIdentifierHook, W as DataListHook, X as DataOverrideFilterHook, Y as DataRequest, Z as DataRequestSchemas, _ as DataRouterOptions, $ as DecorateAccess, a0 as DecorateAllAccess, a1 as DeepFieldPath, a2 as DefaultModelRouterOptions, a3 as Defaults, a4 as DistinctArgs, a5 as DistinctBody, a6 as DocPermissionsAccess, a7 as DocumentAuthorization, a8 as ErrorResult, a9 as ExistsOptions, aa as ExtendedDataRouterOptions, ab as ExtendedDefaultModelRouterOptions, ac as ExtendedModelRouterOptions, ad as FieldAuthorization, ae as FieldOperationAccess, af as Filter, ag as FilterOperator, ah as FindAccess, ai as FindArgs, aj as FindByIdArgs, ak as FindByIdOptions, al as FindOneArgs, am as FindOneOptions, an as FindOptions, ao as GlobalOptions, ap as GlobalPermissionValue, aq as GuardHook, ar as HydrationMode, as as IdentifierHook, at as Include, au as InputFieldAuthorization, av as InputFieldPath, aw as IoTsContextEntryLike, ax as IoTsDecodeErrorLike, ay as IoTsDecoderLike, az as JoiSchemaLike, aA as JoiValidationErrorDetailLike, aB as KeyValueProjection, aC as LegacyInclude, aD as ListQueryInput, aE as ListResult, aF as MIDDLEWARE, aG as MaybePromise, aH as ModelBaseFilterHook, aI as ModelChangeHook, aJ as ModelDeleteHook, aK as ModelDocPermissionsHook, aL as ModelDocument, aM as ModelDocumentHook, aN as ModelHook, aO as ModelHookContext, aP as ModelHydrationOptions, aQ as ModelIdentifierHook, aR as ModelListHook, aS as ModelOverrideFilterHook, aT as ModelRequest, aU as ModelRouterOptions, aV as ModelValidateHook, aW as ModelVirtualAccess, aX as ModelVirtualAccessRecord, aY as ModelVirtualContext, aZ as ModelVirtualDescriptor, a_ as ModelVirtualDoc, a$ as ModelVirtualGetter, b0 as ModelVirtualLeaf, b1 as ModelVirtualRecordAccess, b2 as ModelVirtuals, b3 as MutationAuthorization, b4 as NewArgs, b5 as NewOptions, b6 as OperationAccess, b7 as OperationAuthorization, b8 as OutputAuthorization, b9 as OutputFieldOptions, ba as OutputFieldPath, bb as OutputPlanningOptions, bc as PERMISSIONS, bd as PERMISSION_KEYS, be as PairedRouteAccess, bf as ParentRef, bg as PathValue, bh as PermissionSchema, bi as Populate, bj as PopulateAccess, bk as PopulatePlanningOptions, bl as PrepareAccess, bm as Projection, bn as PublicCreateArgs, bo as PublicCreateOptions, bp as PublicErrorResult, bq as PublicListArgs, br as PublicListOptions, bs as PublicListResult, bt as PublicOutput, bu as PublicReadArgs, bv as PublicReadOptions, bw as PublicServiceResult, bx as PublicSingleResult, by as PublicSubdocumentCreateOptions, bz as PublicSubdocumentListOptions, bA as PublicSubdocumentMutationOptions, bB as PublicSubdocumentReadOptions, bC as PublicUpdateArgs, bD as PublicUpdateOptions, bE as PublicUpsertArgs, bF as PublicUpsertOptions, bG as ReadQueryInput, bH as RelatedAuthorization, bI as Request, bJ as RequestSchemaAdapter, bK as RequestSchemaFailure, bL as RequestSchemaIssue, bM as RequestSchemaLike, bN as RequestSchemaOptions, bO as RequestSchemaResult, bP as RequestSchemaSuccess, bQ as RequestSchemaValidator, bR as RequestSchemas, bS as RootDataListQueryEntry, bT as RootDataOperation, bU as RootDataReadByFilterQueryEntry, bV as RootDataReadByIdQueryEntry, bW as RootModelCountQueryEntry, bX as RootModelCreateQueryEntry, bY as RootModelDeleteQueryEntry, bZ as RootModelDistinctQueryEntry, b_ as RootModelListQueryEntry, b$ as RootModelNewQueryEntry, c0 as RootModelOperation, c1 as RootModelReadByFilterQueryEntry, c2 as RootModelReadByIdQueryEntry, c3 as RootModelSubBulkUpdateQueryEntry, c4 as RootModelSubCreateQueryEntry, c5 as RootModelSubDeleteQueryEntry, c6 as RootModelSubListQueryEntry, c7 as RootModelSubReadQueryEntry, c8 as RootModelSubUpdateQueryEntry, c9 as RootModelUpdateQueryEntry, ca as RootModelUpsertQueryEntry, cb as RootOperationResult, cc as RootQueryEntry, cd as RootRouterOptions, ce as RootSubOperation, cf as RootTarget, cg as RouteBaseAccess, ch as RouteGuardAccess, ci as RouteVariant, cj as RouteVariantAccess, ck as RowAuthorization, cl as SelectAccess, cm as SelectedPopulatedPublicOutput, cn as SelectedPublicOutput, co as ServiceAuthorization, cp as ServiceOutputContext, cq as ServiceOutputDecorator, cr as ServiceResult, cs as SingleResult, ct as Sort, cu as SortOrder, cv as StandardSchemaFailure, cw as StandardSchemaInferOutput, cx as StandardSchemaIssue, cy as StandardSchemaPathSegment, cz as StandardSchemaResult, cA as StandardSchemaSuccess, cB as StandardSchemaV1, cC as StatusCodes, cD as SubListBody, cE as SubOperationAccess, cF as SubPopulate, cG as SubQueryEntry, cH as SubReadBody, cI as SubRouteGuardOptions, cJ as SubdocumentBulkRecord, cK as SubdocumentBulkUpdateInput, cL as SubdocumentCreateAuthorization, cM as SubdocumentCreateInput, cN as SubdocumentCreateOptions, cO as SubdocumentCreateVisibilityAuthorization, cP as SubdocumentDeleteAuthorization, cQ as SubdocumentDeleteOptions, cR as SubdocumentGateAuthorization, cS as SubdocumentId, cT as SubdocumentInputAuthorization, cU as SubdocumentListOptions, cV as SubdocumentModel, cW as SubdocumentMutationAuthorization, cX as SubdocumentName, cY as SubdocumentOutputAuthorization, cZ as SubdocumentParentArgs, c_ as SubdocumentParentOptions, c$ as SubdocumentReadAuthorization, d0 as SubdocumentReadOptions, d1 as SubdocumentRecord, d2 as SubdocumentUpdateOptions, d3 as SubdocumentVirtuals, d4 as SubdocumentVisibilityAuthorization, d5 as SuperstructFailureLike, d6 as SuperstructValidateLike, d7 as Task, d8 as TaskType, d9 as TransformAccess, da as TypedFilter, db as UpdateByIdArgs, dc as UpdateByIdOptions, dd as UpdateOneArgs, de as UpdateOneOptions, df as UpdateQueryInput, dg as UpsertArgs, dh as UpsertOptions, di as UpsertQueryInput, dj as ValibotIssueLike, dk as ValibotPathItemLike, dl as ValibotSafeParseLike, dm as ValibotSafeParseResult, dn as ValidateAccess, dp as ValidateRule, dq as Validation, dr as ValidationError, ds as VineValidationErrorLike, dt as VineValidationMessageLike, du as VineValidatorLike, dv as VirtualSubModel, dw as WithVirtuals, dx as YupSchemaLike, dy as YupValidationErrorLike, dz as defineRequestSchema, dA as fromAjv, dB as fromArkType, dC as fromIoTs, dD as fromJoi, dE as fromStandardSchema, dF as fromSuperstruct, dG as fromValibot, dH as fromVine, dI as fromYup, dJ as fromZod, dK as parseBody, dL as parseBodyWithSchema, dM as parseNestedBodyWithSchema, dN as parsePathParam, dO as parseQuery } from './parsers-ZSrF7SNu.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import 'mongoose';
|
|
4
4
|
import 'express';
|
|
@@ -1049,7 +1049,6 @@ declare const rootQuerySchema: z.ZodArray<z.ZodUnion<readonly [z.ZodUnion<readon
|
|
|
1049
1049
|
list: "list";
|
|
1050
1050
|
read: "read";
|
|
1051
1051
|
}>>;
|
|
1052
|
-
lean: z.ZodOptional<z.ZodBoolean>;
|
|
1053
1052
|
}, z.core.$loose>>;
|
|
1054
1053
|
name: z.ZodString;
|
|
1055
1054
|
order: z.ZodOptional<z.ZodNumber>;
|
|
@@ -1228,7 +1227,6 @@ declare const rootQuerySchema: z.ZodArray<z.ZodUnion<readonly [z.ZodUnion<readon
|
|
|
1228
1227
|
list: "list";
|
|
1229
1228
|
read: "read";
|
|
1230
1229
|
}>>;
|
|
1231
|
-
lean: z.ZodOptional<z.ZodBoolean>;
|
|
1232
1230
|
}, z.core.$loose>>;
|
|
1233
1231
|
name: z.ZodString;
|
|
1234
1232
|
order: z.ZodOptional<z.ZodNumber>;
|
|
@@ -1408,7 +1406,6 @@ declare const rootQuerySchema: z.ZodArray<z.ZodUnion<readonly [z.ZodUnion<readon
|
|
|
1408
1406
|
list: "list";
|
|
1409
1407
|
read: "read";
|
|
1410
1408
|
}>>;
|
|
1411
|
-
lean: z.ZodOptional<z.ZodBoolean>;
|
|
1412
1409
|
}, z.core.$loose>>;
|
|
1413
1410
|
name: z.ZodString;
|
|
1414
1411
|
order: z.ZodOptional<z.ZodNumber>;
|
package/advanced.js
CHANGED
|
@@ -194,7 +194,38 @@ function assertPublicAdmission(input, kind = "envelope") {
|
|
|
194
194
|
for (const key of ["filter", "match", "data"]) add(record[key], "data", key);
|
|
195
195
|
}
|
|
196
196
|
}
|
|
197
|
+
function assertHydrationDefaults(defaults) {
|
|
198
|
+
if (defaults && typeof defaults === "object") {
|
|
199
|
+
const record = defaults;
|
|
200
|
+
if ("hydration" in record)
|
|
201
|
+
throw new TypeError("defaults.hydration is unsupported; use model hydration configuration");
|
|
202
|
+
for (const bucket of [
|
|
203
|
+
"publicListOptions",
|
|
204
|
+
"publicReadOptions",
|
|
205
|
+
"findOptions",
|
|
206
|
+
"findOneOptions",
|
|
207
|
+
"findByIdOptions",
|
|
208
|
+
"createOptions",
|
|
209
|
+
"updateOneOptions",
|
|
210
|
+
"updateByIdOptions",
|
|
211
|
+
"upsertOptions",
|
|
212
|
+
"existsOptions",
|
|
213
|
+
"publicCreateOptions",
|
|
214
|
+
"publicUpdateOptions"
|
|
215
|
+
]) {
|
|
216
|
+
const options = record[bucket];
|
|
217
|
+
if (!options || typeof options !== "object" && typeof options !== "function") continue;
|
|
218
|
+
for (const key of ["lean", "hydration"]) {
|
|
219
|
+
if (!(key in options)) continue;
|
|
220
|
+
const method = bucket.slice(0, -"Options".length);
|
|
221
|
+
const migration = ["publicList", "publicRead", "find", "findOne", "findById"].includes(method) ? `use model hydration.${method} ('lean' or 'hydrated')` : "this method has a fixed fetch mode";
|
|
222
|
+
throw new TypeError(`defaults.${bucket}.${key} is unsupported; ${migration}`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
197
227
|
function assertPublicDefaults(defaults) {
|
|
228
|
+
assertHydrationDefaults(defaults);
|
|
198
229
|
assertPublicAdmission(defaults);
|
|
199
230
|
if (defaults && typeof defaults === "object") {
|
|
200
231
|
for (const value of Object.values(defaults)) assertPublicAdmission(value);
|
|
@@ -202,6 +233,31 @@ function assertPublicDefaults(defaults) {
|
|
|
202
233
|
}
|
|
203
234
|
var requestAuthorization = Object.freeze({ outputFields: Object.freeze({ mode: "request" }) });
|
|
204
235
|
|
|
236
|
+
// src/options/hydration.ts
|
|
237
|
+
var methods = ["publicList", "publicRead", "find", "findOne", "findById"];
|
|
238
|
+
function normalizeHydration(value, path = "hydration") {
|
|
239
|
+
if (value === void 0) return void 0;
|
|
240
|
+
if (value === null || typeof value !== "object" || ![Object.prototype, null].includes(Object.getPrototypeOf(value)))
|
|
241
|
+
throw new TypeError(`${path} must be a plain record of model hydration modes`);
|
|
242
|
+
const result = {};
|
|
243
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
244
|
+
if (typeof key !== "string" || !methods.includes(key))
|
|
245
|
+
throw new TypeError(`${path}.${String(key)} is not a supported hydration method`);
|
|
246
|
+
const mode = value[key];
|
|
247
|
+
if (mode !== void 0 && mode !== "lean" && mode !== "hydrated")
|
|
248
|
+
throw new TypeError(`${path}.${key} must be 'lean', 'hydrated', or undefined`);
|
|
249
|
+
result[key] = mode;
|
|
250
|
+
}
|
|
251
|
+
return Object.freeze(result);
|
|
252
|
+
}
|
|
253
|
+
function normalizeHydrationUpdate(current, key, value) {
|
|
254
|
+
if (key === "hydration") return normalizeHydration(value);
|
|
255
|
+
const method = key.slice("hydration.".length);
|
|
256
|
+
if (!methods.includes(method))
|
|
257
|
+
throw new TypeError(`${key} is not a supported hydration method`);
|
|
258
|
+
return normalizeHydration({ ...normalizeHydration(current), [method]: value });
|
|
259
|
+
}
|
|
260
|
+
|
|
205
261
|
// src/runtime.ts
|
|
206
262
|
var import_mongoose_schema_jsonschema = __toESM(require("mongoose-schema-jsonschema"));
|
|
207
263
|
var import_utils10 = require("@web-ts-toolkit/utils");
|
|
@@ -1680,9 +1736,25 @@ var AccessRuntime = class {
|
|
|
1680
1736
|
}
|
|
1681
1737
|
/** Update model starting defaults shallowly; already-stored model values are not broadcast-replaced. */
|
|
1682
1738
|
setDefaultModelOptions(options) {
|
|
1739
|
+
assertPublicDefaults(options.defaults);
|
|
1740
|
+
if ("hydration" in options) options = { ...options, hydration: normalizeHydration(options.hydration) };
|
|
1683
1741
|
this.defaultModelOptions.assign(options);
|
|
1684
1742
|
}
|
|
1685
1743
|
setDefaultModelOption(key, value) {
|
|
1744
|
+
const keyStr = String(key);
|
|
1745
|
+
if (keyStr === "hydration" || keyStr.startsWith("hydration.")) {
|
|
1746
|
+
this.defaultModelOptions.set(
|
|
1747
|
+
"hydration",
|
|
1748
|
+
normalizeHydrationUpdate(this.getDefaultModelOptions().hydration, keyStr, value)
|
|
1749
|
+
);
|
|
1750
|
+
return;
|
|
1751
|
+
}
|
|
1752
|
+
if (keyStr === "defaults") assertPublicDefaults(value);
|
|
1753
|
+
else if (keyStr.startsWith("defaults.")) {
|
|
1754
|
+
const proposed = {};
|
|
1755
|
+
(0, import_utils10.set)(proposed, keyStr.slice("defaults.".length), value);
|
|
1756
|
+
assertPublicDefaults(proposed);
|
|
1757
|
+
}
|
|
1686
1758
|
this.defaultModelOptions.set(key, value);
|
|
1687
1759
|
}
|
|
1688
1760
|
getDefaultModelOptions() {
|
|
@@ -1732,6 +1804,7 @@ var AccessRuntime = class {
|
|
|
1732
1804
|
*/
|
|
1733
1805
|
setModelOptions(modelName, options) {
|
|
1734
1806
|
assertPublicDefaults(options.defaults);
|
|
1807
|
+
if ("hydration" in options) options = { ...options, hydration: normalizeHydration(options.hydration) };
|
|
1735
1808
|
const manager = this.getOrCreateModelOptions(modelName);
|
|
1736
1809
|
const defaultOptions = this.getDefaultModelOptions();
|
|
1737
1810
|
const currentModelOptions = manager.fetch();
|
|
@@ -1742,14 +1815,19 @@ var AccessRuntime = class {
|
|
|
1742
1815
|
manager.assign({ ...defaultOptions, ...currentModelOptions, ...options });
|
|
1743
1816
|
}
|
|
1744
1817
|
setModelOption(modelName, key, value) {
|
|
1745
|
-
const manager = this.getOrCreateModelOptions(modelName);
|
|
1746
1818
|
const keyStr = String(key);
|
|
1819
|
+
if (keyStr === "hydration" || keyStr.startsWith("hydration.")) {
|
|
1820
|
+
const hydration = normalizeHydrationUpdate(this.modelOptions[modelName]?.get("hydration"), keyStr, value);
|
|
1821
|
+
this.getOrCreateModelOptions(modelName).set("hydration", hydration);
|
|
1822
|
+
return;
|
|
1823
|
+
}
|
|
1747
1824
|
if (keyStr === "defaults") assertPublicDefaults(value);
|
|
1748
1825
|
else if (keyStr.startsWith("defaults.")) {
|
|
1749
1826
|
const proposed = {};
|
|
1750
1827
|
(0, import_utils10.set)(proposed, keyStr.slice("defaults.".length), value);
|
|
1751
1828
|
assertPublicDefaults(proposed);
|
|
1752
1829
|
}
|
|
1830
|
+
const manager = this.getOrCreateModelOptions(modelName);
|
|
1753
1831
|
if (keyStr === "virtuals" || keyStr.startsWith("virtuals.") || keyStr === "documentPermissionField") {
|
|
1754
1832
|
const model = this.getModelInstance(modelName);
|
|
1755
1833
|
const currentVirtuals = manager.get("virtuals");
|
|
@@ -3111,8 +3189,7 @@ var rootModelListOptionsSchema = import_zod5.z.object({
|
|
|
3111
3189
|
includePermissions: import_zod5.z.boolean().optional(),
|
|
3112
3190
|
includeFieldPermissions: import_zod5.z.boolean().optional(),
|
|
3113
3191
|
includeCount: import_zod5.z.boolean().optional(),
|
|
3114
|
-
populateAccess: populateAccessSchema.optional()
|
|
3115
|
-
lean: import_zod5.z.boolean().optional()
|
|
3192
|
+
populateAccess: populateAccessSchema.optional()
|
|
3116
3193
|
}).passthrough();
|
|
3117
3194
|
var rootModelReadArgsSchema = import_zod5.z.object({
|
|
3118
3195
|
select: projectionSchema.optional(),
|
|
@@ -3128,8 +3205,7 @@ var rootModelReadOptionsSchema = import_zod5.z.object({
|
|
|
3128
3205
|
includePermissions: import_zod5.z.boolean().optional(),
|
|
3129
3206
|
includeFieldPermissions: import_zod5.z.boolean().optional(),
|
|
3130
3207
|
tryList: import_zod5.z.boolean().optional(),
|
|
3131
|
-
populateAccess: populateAccessSchema.optional()
|
|
3132
|
-
lean: import_zod5.z.boolean().optional()
|
|
3208
|
+
populateAccess: populateAccessSchema.optional()
|
|
3133
3209
|
}).passthrough();
|
|
3134
3210
|
var rootModelCreateArgsSchema = import_zod5.z.object({
|
|
3135
3211
|
select: projectionSchema.optional(),
|