@simtlix/simfinity-core 3.14.0 → 3.16.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 +31 -4
- package/package.json +12 -2
- package/src/after-commit.js +83 -0
- package/src/auth/index.js +97 -36
- package/src/auth/operation-entries.js +111 -0
- package/src/const/QLOperator.js +2 -0
- package/src/execution-state.js +71 -0
- package/src/introspection-config.js +17 -0
- package/src/introspection-state.js +10 -0
- package/src/introspection.js +5 -3
- package/src/mutation-limits.js +37 -7
- package/src/operation-input.js +345 -0
- package/src/query-frames.js +42 -7
- package/src/query-operators.js +90 -6
- package/src/query-plan.js +15 -4
- package/src/runtime.js +722 -55
- package/src/schema-registrations.js +23 -0
- package/src/transaction-callbacks.js +34 -0
- package/src/transaction-references.js +259 -0
- package/src/transaction-schema.js +163 -0
- package/types/index.d.ts +186 -17
- package/types/introspection.d.ts +4 -0
package/types/index.d.ts
CHANGED
|
@@ -56,11 +56,18 @@ export const MAX_RECORD_VERSION: number;
|
|
|
56
56
|
* missing; constructs that middleware and scopes add read stored data. With any other adapter they
|
|
57
57
|
* fail with `UNSUPPORTED_QUERY`. A term or group condition without a path tests the field itself, except that every term
|
|
58
58
|
* of a quantified relation filter needs a non-empty element-relative path.
|
|
59
|
+
*
|
|
60
|
+
* `IIN` is `IN` ignoring case: an array of non-null strings without U+0000, possibly empty, on a `String` field or
|
|
61
|
+
* `String` list by its effective scalar; it matches where `IEQ` matches one of them, and `[]` matches nothing.
|
|
62
|
+
* `CONTAINS_ALL` takes a non-empty array of non-null scalars, cast like `IN` elements; it applies to a scalar list or a
|
|
63
|
+
* field reached through embedded lists, where it holds when every value is among the values of all items, and fails
|
|
64
|
+
* with `INVALID_FILTER_OPERATOR` on other leaves and with `INVALID_FILTER_PATH` through a collection or a reference
|
|
65
|
+
* inside an embedded list. Neither has a negated form.
|
|
59
66
|
*/
|
|
60
67
|
export type QueryOperator =
|
|
61
68
|
| 'EQ' | 'NE' | 'LT' | 'LTE' | 'GT' | 'GTE' | 'BTW' | 'IN' | 'NIN' | 'LIKE'
|
|
62
69
|
| 'ILIKE' | 'STARTS_WITH' | 'ISTARTS_WITH' | 'ENDS_WITH' | 'IENDS_WITH' | 'IEQ'
|
|
63
|
-
| 'IS_EMPTY' | 'IS_NOT_EMPTY';
|
|
70
|
+
| 'IS_EMPTY' | 'IS_NOT_EMPTY' | 'CONTAINS_ALL' | 'IIN';
|
|
64
71
|
|
|
65
72
|
/** The quantifier applied to the elements visible in a collection or reference frame. */
|
|
66
73
|
export type QueryQuantifier = 'ANY' | 'ALL' | 'NONE';
|
|
@@ -333,7 +340,27 @@ export class InternalServerError extends SimfinityError {
|
|
|
333
340
|
*/
|
|
334
341
|
export function buildErrorFormatter(callback?: (error: SimfinityError) => Error | void): (error: unknown) => GraphQLError;
|
|
335
342
|
|
|
336
|
-
export interface
|
|
343
|
+
export interface AfterCommitErrorDetails {
|
|
344
|
+
committed: true;
|
|
345
|
+
typeName: string;
|
|
346
|
+
operation: 'save' | 'update' | 'delete' | 'state_changed';
|
|
347
|
+
callbackName: 'onSaveCommitted' | 'onUpdateCommitted' | 'onDeleteCommitted' | 'onTransitionCommitted';
|
|
348
|
+
context: any;
|
|
349
|
+
}
|
|
350
|
+
export interface AfterCommitOptions {
|
|
351
|
+
/** Operational reporting only. Rejections are caught and never fail the committed write. */
|
|
352
|
+
onError?: (error: unknown, details: AfterCommitErrorDetails) => void | Promise<void>;
|
|
353
|
+
}
|
|
354
|
+
export interface CommittedControllerCallbacks {
|
|
355
|
+
/** After the owning transaction commits; a detached result and the successful attempt's input. */
|
|
356
|
+
onSaveCommitted?(record: any, args: any, context: any): void | Promise<void>;
|
|
357
|
+
onUpdateCommitted?(record: any, context: any): void | Promise<void>;
|
|
358
|
+
/** Called only when a record was actually deleted. */
|
|
359
|
+
onDeleteCommitted?(record: any, context: any): void | Promise<void>;
|
|
360
|
+
/** Exclusive notification for a state action; action is its registered name. */
|
|
361
|
+
onTransitionCommitted?(record: any, action: string, context: any): void | Promise<void>;
|
|
362
|
+
}
|
|
363
|
+
export interface EntityController<Session = any> extends CommittedControllerCallbacks {
|
|
337
364
|
onSaving?(record: any, args: any, session: Session | undefined, context: any): void | Promise<void>;
|
|
338
365
|
onSaved?(record: any, args: any, session: Session | undefined, context: any): void | Promise<void>;
|
|
339
366
|
onUpdating?(id: any, update: any, session: Session | undefined, context: any): void | Promise<void>;
|
|
@@ -407,16 +434,24 @@ export interface ConcurrencyDeclaration {
|
|
|
407
434
|
}
|
|
408
435
|
|
|
409
436
|
/**
|
|
410
|
-
* Process-wide limits for generated
|
|
411
|
-
* such as a misspelled
|
|
437
|
+
* Process-wide limits for generated mutations. Each call replaces both values: an omitted or
|
|
438
|
+
* `undefined` option restores its default. Any other option, such as a misspelled
|
|
439
|
+
* `maxNestedOperation`, throws `INVALID_MUTATION_LIMITS` (400) and keeps the current limits.
|
|
412
440
|
*/
|
|
413
441
|
export interface MutationLimitsOptions {
|
|
414
442
|
/**
|
|
415
443
|
* Maximum number of `added`, `updated` and `deleted` entries across every nested level of
|
|
416
444
|
* non-embedded collection fields in one generated mutation. A non-negative safe integer;
|
|
417
|
-
* `null` or omitted means unlimited (the default).
|
|
445
|
+
* `null` or omitted means unlimited (the default). The helpers `updateObject` and
|
|
446
|
+
* `transitionObject` apply it to their `input` as the generated mutations do.
|
|
418
447
|
*/
|
|
419
448
|
maxNestedOperations?: number | null;
|
|
449
|
+
/**
|
|
450
|
+
* Maximum number of operations in one generated transaction mutation. A positive safe integer;
|
|
451
|
+
* omitted means 100 (the default). `null`, `0`, a negative number or a non-integer throws
|
|
452
|
+
* `INVALID_MUTATION_LIMITS` (400).
|
|
453
|
+
*/
|
|
454
|
+
maxTransactionOperations?: number;
|
|
420
455
|
}
|
|
421
456
|
|
|
422
457
|
/**
|
|
@@ -429,6 +464,21 @@ export interface CreateSchemaOptions {
|
|
|
429
464
|
* `[]` includes none, and names that are not registered are ignored.
|
|
430
465
|
*/
|
|
431
466
|
includedCustomQueries?: string[] | null;
|
|
467
|
+
/**
|
|
468
|
+
* Adds one mutation field that runs a list of generated mutations in order in one database
|
|
469
|
+
* transaction. `null` or omission adds none. `name` defaults to `transaction` and must be a GraphQL
|
|
470
|
+
* name that does not start with `__`; it names the field and its types (for `transaction`:
|
|
471
|
+
* `TransactionOperation`, a `@oneOf` input keyed by operation, `TransactionResult` and, for deletes
|
|
472
|
+
* of types without optimistic concurrency, `TransactionDeleteInput`). The operations are the
|
|
473
|
+
* generated add, update, delete and state machine action mutations of `types` that this schema
|
|
474
|
+
* includes; registered mutations never are. `types` is a non-empty array of distinct types registered
|
|
475
|
+
* in this runtime. An invalid option throws `INVALID_SCHEMA_OPTIONS` (500) before models are prepared,
|
|
476
|
+
* or once the generated mutations are built when the field name or a derived type name is taken or
|
|
477
|
+
* no operation remains; a type bound to another runtime throws `TYPE_BOUND_TO_OTHER_RUNTIME` (409),
|
|
478
|
+
* and an adapter without `assertTransactionModels` throws `TRANSACTION_UNSUPPORTED` (500). A failed
|
|
479
|
+
* `createSchema()` keeps no transaction field or type.
|
|
480
|
+
*/
|
|
481
|
+
transaction?: { name?: string; types: GraphQLObjectType[] } | null;
|
|
432
482
|
}
|
|
433
483
|
|
|
434
484
|
export interface QueryLimitsOptions {
|
|
@@ -485,13 +535,17 @@ export interface ViewOptions {
|
|
|
485
535
|
}
|
|
486
536
|
|
|
487
537
|
export interface Runtime<Model = any, Session = any> {
|
|
538
|
+
/** Per runtime. No arguments resets to safe default logging; invalid options leave it unchanged. */
|
|
539
|
+
configureAfterCommit(options?: AfterCommitOptions): void;
|
|
488
540
|
/** The same process-wide setting as the root `configureQueryLimits`. */
|
|
489
541
|
configureQueryLimits(options?: QueryLimitsOptions): void;
|
|
490
542
|
/**
|
|
491
|
-
* Process-wide; calling it without options restores
|
|
492
|
-
*
|
|
493
|
-
*
|
|
494
|
-
* `NESTED_OPERATIONS_EXCEEDED` (400) before its
|
|
543
|
+
* Process-wide; calling it without options restores both defaults (`maxNestedOperations`
|
|
544
|
+
* unlimited, `maxTransactionOperations` 100). Invalid options, including unknown or misspelled
|
|
545
|
+
* option keys, throw `INVALID_MUTATION_LIMITS` (400) and keep the current limits. A generated
|
|
546
|
+
* mutation over the nested limit fails with `NESTED_OPERATIONS_EXCEEDED` (400) before its
|
|
547
|
+
* transaction starts. `updateObject` and `transitionObject` apply `maxNestedOperations` to their
|
|
548
|
+
* `input` in the same way (`null` = no limit).
|
|
495
549
|
*/
|
|
496
550
|
configureMutationLimits(options?: MutationLimitsOptions): void;
|
|
497
551
|
/**
|
|
@@ -539,7 +593,8 @@ export interface Runtime<Model = any, Session = any> {
|
|
|
539
593
|
*
|
|
540
594
|
* `options.includedCustomQueries` selects custom queries by name (see {@link CreateSchemaOptions});
|
|
541
595
|
* an included custom query named like an included generated query throws `QUERY_NAME_CONFLICT`
|
|
542
|
-
* (500).
|
|
596
|
+
* (500). `options.transaction` adds the generated transaction field (see {@link CreateSchemaOptions}).
|
|
597
|
+
* A schema without mutation fields has no `Mutation` root.
|
|
543
598
|
*/
|
|
544
599
|
createSchema(includedQueryTypes?: GraphQLObjectType[] | null, includedMutationTypes?: GraphQLObjectType[] | null, includedCustomMutations?: string[] | null, options?: CreateSchemaOptions): GraphQLSchema;
|
|
545
600
|
getModel(type: GraphQLObjectType | { name: string }): Model | null | undefined;
|
|
@@ -580,6 +635,64 @@ export interface Runtime<Model = any, Session = any> {
|
|
|
580
635
|
registerView(name: string, options: ViewOptions): void;
|
|
581
636
|
/** Owns the full workflow transaction unless an active caller session is supplied. */
|
|
582
637
|
saveObject(typeName: string, args: Record<string, any>, session?: Session, context?: any): Promise<any>;
|
|
638
|
+
/**
|
|
639
|
+
* Runs the lifecycle of the generated update mutation from code: validators, controller hooks,
|
|
640
|
+
* optimistic concurrency and the nested `added`, `updated` and `deleted` entries, in one transaction.
|
|
641
|
+
* `typeName` names a type registered in this runtime that stores records and has its update input
|
|
642
|
+
* prepared by `createSchema()`, with an `id` field. Whether a schema exposes the mutation does not
|
|
643
|
+
* matter: the helper is not an authorization boundary. Any other `typeName` rejects with
|
|
644
|
+
* `INVALID_OPERATION_TARGET` (500), before the input is read.
|
|
645
|
+
*
|
|
646
|
+
* `input` has the shape of the type's generated update input, `version` included on a type with
|
|
647
|
+
* optimistic concurrency. It is checked structurally and copied before anything runs, and the
|
|
648
|
+
* caller's object is never written to. It is not coerced like a GraphQL input: enum fields take
|
|
649
|
+
* their internal values, scalars are not parsed, a reference is its record key as a string, such as
|
|
650
|
+
* `{ id: String(record._id) }`, and the `state` of a type with a state machine changes only through
|
|
651
|
+
* `transitionObject`. A scalar field takes a primitive, a `Date` or plain data (objects and arrays,
|
|
652
|
+
* copied deeply, at most 256 levels deep); class instances such as `ObjectId`, `Buffer` or `Map` are
|
|
653
|
+
* rejected with `INVALID_INPUT`. An own `undefined` counts as omitted, and a bare value is never
|
|
654
|
+
* wrapped into a list. A missing `input`, `id` or value for a non-null field rejects with
|
|
655
|
+
* `REQUIRED_VALUE` (400); any other violation, such as an unknown field, an object that is not plain
|
|
656
|
+
* or a list that is not dense, rejects with `INVALID_INPUT` (400). The message names the path, such
|
|
657
|
+
* as `input.lines.added[1].price`, and never a value. More nested entries than `maxNestedOperations`
|
|
658
|
+
* from `configureMutationLimits()` (`null` = no limit) reject with `NESTED_OPERATIONS_EXCEEDED` (400)
|
|
659
|
+
* before the transaction starts.
|
|
660
|
+
*
|
|
661
|
+
* Without `session`, the adapter owns the transaction and its retries. A supplied `session` must have
|
|
662
|
+
* an active transaction, and the helper itself never commits, retries, aborts or cleans up a supplied
|
|
663
|
+
* session; an adapter may still abort it on a write error (for example MongoDB with transactional
|
|
664
|
+
* reference integrity). Like `saveObject`, it skips the global middleware of the record itself; nested entries keep theirs and
|
|
665
|
+
* receive `context`, which may be `undefined`.
|
|
666
|
+
*
|
|
667
|
+
* Resolves to the updated record, as the generated mutation returns it. An `id` that has no record
|
|
668
|
+
* rejects with `NOT_VALID_ID` (404), and a stale `version` with `VERSION_CONFLICT` (409).
|
|
669
|
+
*/
|
|
670
|
+
updateObject(typeName: string, input: Record<string, any>, session?: Session, context?: any): Promise<any>;
|
|
671
|
+
/**
|
|
672
|
+
* Runs the lifecycle of the generated delete mutation from code. `target` is `{ id }`, the record key
|
|
673
|
+
* as a string, plus `version`, the version read, on a type with optimistic concurrency; on any other
|
|
674
|
+
* type `version` is an unknown field. The type is checked as in {@link Runtime.updateObject}, except
|
|
675
|
+
* that it needs no update input of its own; the type must still be a stored record type, which only
|
|
676
|
+
* `createSchema()` establishes. The target is checked before anything runs: a missing
|
|
677
|
+
* target, `id` or required `version` rejects with `REQUIRED_VALUE` (400), and any other violation
|
|
678
|
+
* with `INVALID_INPUT` (400). A stale `version` rejects with `VERSION_CONFLICT` (409). Sessions,
|
|
679
|
+
* `context` and middleware work as in `updateObject`.
|
|
680
|
+
*
|
|
681
|
+
* Resolves to the deleted record, or to `null` when no record has that ID.
|
|
682
|
+
*/
|
|
683
|
+
deleteObject(typeName: string, target: { id: string; version?: number }, session?: Session, context?: any): Promise<any>;
|
|
684
|
+
/**
|
|
685
|
+
* Runs the state machine action `actionName` of `typeName` from code, with the lifecycle of the
|
|
686
|
+
* generated action mutation: the check of the current state, the action's callback, the update and the
|
|
687
|
+
* controller hooks, in one transaction. An `actionName` that is not an own action of the type's state
|
|
688
|
+
* machine, or a type without one, rejects with `UNKNOWN_ACTION` (500). The type, the checks of `input`,
|
|
689
|
+
* the session, `context`, the middleware and the errors are as in {@link Runtime.updateObject}. `input` has
|
|
690
|
+
* the shape of the update input and does not carry `state`. An action that does not start from the
|
|
691
|
+
* record's state rejects with `BAD_REQUEST` (400).
|
|
692
|
+
*
|
|
693
|
+
* Resolves to the updated record, with `state` set to the action's target state.
|
|
694
|
+
*/
|
|
695
|
+
transitionObject(typeName: string, actionName: string, input: Record<string, any>, session?: Session, context?: any): Promise<any>;
|
|
583
696
|
preventCreatingCollection(prevent: boolean): void;
|
|
584
697
|
}
|
|
585
698
|
|
|
@@ -594,10 +707,17 @@ export interface DatabaseAdapter<Model = any, Session = any> {
|
|
|
594
707
|
* by-ID read through a `get_by_id` scope, whose arguments use a `QLOperator` value the adapter
|
|
595
708
|
* does not support fails with `UNSUPPORTED_QUERY` (400), before middleware runs for the client's
|
|
596
709
|
* arguments and before `find`, `count`, `aggregate`, `findChildren` or `findChildrenBatch` for
|
|
597
|
-
* conditions that middleware, scopes and joined scopes added. Operators outside `QLOperator
|
|
598
|
-
*
|
|
599
|
-
*
|
|
600
|
-
*
|
|
710
|
+
* conditions that middleware, scopes and joined scopes added. Operators outside `QLOperator`, which
|
|
711
|
+
* only trusted code can write, fail with `INVALID_FILTER_OPERATOR` (400) before the adapter is
|
|
712
|
+
* called, except in the forms the compilers ignore: an operator beside the `terms` of an object
|
|
713
|
+
* filter, and the `terms` of a scalar, scalar-list, interface or union field's filter. Those reach
|
|
714
|
+
* the adapter, which ignores them. Declaring `IS_EMPTY` and `IS_NOT_EMPTY` means compiling their
|
|
715
|
+
* semantics on the record's own fields; emptiness through references and collections also needs
|
|
716
|
+
* `referenceEmptiness: true`, and fails with `UNSUPPORTED_QUERY` without it.
|
|
717
|
+
* Declaring `CONTAINS_ALL` means compiling set containment over the leaf's values, including the
|
|
718
|
+
* values of every item of embedded lists, two-valued under negation; declaring `IIN` means
|
|
719
|
+
* compiling case-insensitive membership under the case-folding contract of the text operators.
|
|
720
|
+
* Names that an older version ignored are honored once this version knows them.
|
|
601
721
|
*/
|
|
602
722
|
queryFeatures?: QueryFeatures | null | undefined;
|
|
603
723
|
/**
|
|
@@ -609,6 +729,16 @@ export interface DatabaseAdapter<Model = any, Session = any> {
|
|
|
609
729
|
* contract of `update` and `delete` and to the requirements on `find` below.
|
|
610
730
|
*/
|
|
611
731
|
writeFeatures?: { optimisticConcurrency?: boolean } | null | undefined;
|
|
732
|
+
/**
|
|
733
|
+
* Optional, and required to enable the generated transaction field (see
|
|
734
|
+
* `CreateSchemaOptions.transaction`). Receives the models one transaction of that field may
|
|
735
|
+
* write: those of the types that own its operations and of the referenced collection items their
|
|
736
|
+
* inputs declare, at any depth, without duplicates. Core calls it before each transaction of the
|
|
737
|
+
* field opens, never in `createSchema()`, so a schema can be created before the connection opens.
|
|
738
|
+
* It must be synchronous and never write, and it throws when the models cannot share one session; a
|
|
739
|
+
* returned promise fails the transaction with `TRANSACTION_UNSUPPORTED` (500).
|
|
740
|
+
*/
|
|
741
|
+
assertTransactionModels?(models: Model[]): void;
|
|
612
742
|
bind?(runtime: Pick<Runtime<Model, Session>, 'getModel' | 'getType' | 'getRegistrations'>): void;
|
|
613
743
|
validateRegistration?(registration: RuntimeRegistration<Model, Session>): void;
|
|
614
744
|
/**
|
|
@@ -638,6 +768,15 @@ export interface DatabaseAdapter<Model = any, Session = any> {
|
|
|
638
768
|
castId(value: any): any;
|
|
639
769
|
stateValue?(state: { name: string; value: any }): any;
|
|
640
770
|
withTransaction<T>(session: Session | null | undefined, callback: (session: Session) => Promise<T> | T, model?: Model): Promise<T>;
|
|
771
|
+
/**
|
|
772
|
+
* Optional capability for controller callbacks. Accept only into an active attempt owned by this
|
|
773
|
+
* adapter; false means the supplied session has no owned attempt. A new queue is required per
|
|
774
|
+
* retry, including retries on the same native session. Seal before commit, discard on abort or
|
|
775
|
+
* unresolved uncertainty, and drain once, serially, after confirmed commit and cleanup attempt.
|
|
776
|
+
* Callback failures must never enter transaction retry/rollback paths or fail a committed write.
|
|
777
|
+
* Borrowed operations join the owning attempt; this method does not observe external commits.
|
|
778
|
+
*/
|
|
779
|
+
enqueueAfterCommit?(session: Session, run: () => void | Promise<void>): boolean;
|
|
641
780
|
newRecord(model: Model, data: any, session?: Session): any;
|
|
642
781
|
saveRecord(model: Model, record: any, session?: Session): any;
|
|
643
782
|
toObject(record: any): any;
|
|
@@ -760,6 +899,8 @@ export type QueryJoins = Record<string, QueryPredicate | null>;
|
|
|
760
899
|
|
|
761
900
|
/**
|
|
762
901
|
* `operator` is a {@link QueryOperator}; the value of a text operator is a validated string. For
|
|
902
|
+
* `CONTAINS_ALL` the value is a non-empty array of non-null scalars, validated and not cast; the
|
|
903
|
+
* compiler casts each element as for `IN`. For `IIN` it is an array of strings, possibly empty. For
|
|
763
904
|
* `IS_EMPTY` and `IS_NOT_EMPTY` the value is null, and `path` may end at an embedded object, an
|
|
764
905
|
* embedded list or a scalar list as well as at a scalar; `IS_NOT_EMPTY` is the exact complement,
|
|
765
906
|
* which the compiler builds. With `referenceEmptiness: true`, their `path` may also cross single
|
|
@@ -818,6 +959,22 @@ export interface QueryPlan {
|
|
|
818
959
|
* object fails with `INVALID_FILTER_PATH`, as on MongoDB; a bare object field keeps
|
|
819
960
|
* `MISSING_FILTER_PATH`.
|
|
820
961
|
*
|
|
962
|
+
* `CONTAINS_ALL` and `IIN` are checked in this order: the path (`AMBIGUOUS_FILTER_FIELD`,
|
|
963
|
+
* `INVALID_FILTER_PATH`, `INVALID_FILTER_FIELD`) and the object-end rule above, then an unknown name
|
|
964
|
+
* (`INVALID_FILTER_OPERATOR`) and `operators` (`UNSUPPORTED_QUERY`), then, for `CONTAINS_ALL` only,
|
|
965
|
+
* `INVALID_FILTER_PATH` through a collection, aggregate join prefixes included
|
|
966
|
+
* (`The shorthand excludes them; use an explicit group`), `INVALID_FILTER_PATH` through a reference
|
|
967
|
+
* inside an embedded list, and `INVALID_FILTER_OPERATOR` on a leaf that is neither a scalar list nor
|
|
968
|
+
* a scalar reached through an embedded list, and the values last, with `INVALID_FILTER_VALUE`.
|
|
969
|
+
* `CONTAINS_ALL` takes a non-empty array of non-null scalars, none of them an array or a plain
|
|
970
|
+
* object; `IIN` takes an array of strings without U+0000, possibly empty, on a `String` field or list
|
|
971
|
+
* by its effective scalar. A hole of a sparse array fails for both, while `IN`, `NIN` and `BTW` keep
|
|
972
|
+
* skipping holes.
|
|
973
|
+
* Both plan `{ kind: 'predicate', path, operator, value }` with the array as validated, neither cast
|
|
974
|
+
* nor deduplicated. `IIN` through a collection plans as `IN` does: an implicit `ANY` frame with
|
|
975
|
+
* `quantifiers`, a row filter on an aggregate's join prefix, a legacy join otherwise. `CONTAINS_ALL`
|
|
976
|
+
* is never cut into a frame.
|
|
977
|
+
*
|
|
821
978
|
* `referenceEmptiness` defaults to true when `operators` is omitted and to false when it is given.
|
|
822
979
|
* When it is false, an emptiness condition that crosses or ends at a reference or a collection, or
|
|
823
980
|
* reads a reference or collection member, fails with `UNSUPPORTED_QUERY` where the order above has
|
|
@@ -826,8 +983,17 @@ export interface QueryPlan {
|
|
|
826
983
|
* becomes the predicate's `scopes`. `quantifiers` has the same default rule and requires reference
|
|
827
984
|
* emptiness; enabled collection filters emit quantified nodes, with per-group/prefix correlation,
|
|
828
985
|
* element-relative scopes/joins and aggregate anchors beyond legacy J joins. `__scope`, `__implicit`
|
|
829
|
-
* and `__anchor` are reserved internal input metadata. A
|
|
830
|
-
*
|
|
986
|
+
* and `__anchor` are reserved internal input metadata. A group that trusted code writes with
|
|
987
|
+
* `__implicit: true` must, after its `__anchor`, end at a collection, or at a reference without
|
|
988
|
+
* crossing a list, and its `__anchor`, when present, must have exactly the shape the collection
|
|
989
|
+
* shorthand writes: in an aggregate, on a group at the root, a non-empty array of field names without
|
|
990
|
+
* dots that crosses at least one collection, each a join prefix, followed by a `path` of one
|
|
991
|
+
* collection. Otherwise the group fails with `INVALID_FILTER_PATH` (400), whatever operators it holds
|
|
992
|
+
* and before its conditions are checked, with the message
|
|
993
|
+
* `An implicit quantified path must end at a collection, or at a reference without crossing a list` or
|
|
994
|
+
* `An implicit quantified anchor must name the aggregate's join prefixes`; the anchor's form is
|
|
995
|
+
* checked before the path rule, the rest after it.
|
|
996
|
+
* A marker not filled for every path fails with `DETACHED_CLIENT_FILTER` (500).
|
|
831
997
|
*/
|
|
832
998
|
export function createQueryPlan(models: ModelDescription, entityName: string, input?: Record<string, any>, options?: { mode?: QueryPlan['mode']; operators?: Iterable<string>; referenceEmptiness?: boolean; quantifiers?: boolean }): QueryPlan;
|
|
833
999
|
export function resolveModelPath(models: ModelDescription, entityName: string, path: string | string[]): FieldDescription[];
|
|
@@ -843,7 +1009,7 @@ export function resolveModelPath(models: ModelDescription, entityName: string, p
|
|
|
843
1009
|
export function configureQueryLimits(options?: QueryLimitsOptions): void;
|
|
844
1010
|
/**
|
|
845
1011
|
* Same process-wide setting as `Runtime.configureMutationLimits`. Unknown or misspelled options
|
|
846
|
-
* throw `INVALID_MUTATION_LIMITS` (400) and keep the current
|
|
1012
|
+
* throw `INVALID_MUTATION_LIMITS` (400) and keep the current limits.
|
|
847
1013
|
*/
|
|
848
1014
|
export function configureMutationLimits(options?: MutationLimitsOptions): void;
|
|
849
1015
|
export function paginationStages(pagination: { page: number; size: number } | null | undefined, withDefault: boolean): Array<{ $skip: number } | { $limit: number }>;
|
|
@@ -1093,3 +1259,6 @@ export const plugins: {
|
|
|
1093
1259
|
};
|
|
1094
1260
|
};
|
|
1095
1261
|
};
|
|
1262
|
+
|
|
1263
|
+
/** Early opt-out. Import its function from /introspection before loading the runtime. */
|
|
1264
|
+
export interface IntrospectionOptions { fieldExtensions: false; }
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { IntrospectionOptions } from './index.js';
|
|
2
|
+
export type { IntrospectionOptions } from './index.js';
|
|
3
|
+
/** Must run before importing the runtime/facades. Never removes installed metadata. */
|
|
4
|
+
export function configureIntrospection(options: IntrospectionOptions): void;
|