@inixiative/json-rules 2.27.0 → 3.0.1
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 +291 -72
- package/dist/index.cjs +4 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +321 -454
- package/dist/index.d.ts +321 -454
- package/dist/index.js +4 -8
- package/dist/index.js.map +1 -1
- package/package.json +18 -7
package/dist/index.d.ts
CHANGED
|
@@ -18,7 +18,9 @@ declare const Operator: {
|
|
|
18
18
|
readonly exists: "exists";
|
|
19
19
|
readonly notExists: "notExists";
|
|
20
20
|
readonly startsWith: "startsWith";
|
|
21
|
+
readonly notStartsWith: "notStartsWith";
|
|
21
22
|
readonly endsWith: "endsWith";
|
|
23
|
+
readonly notEndsWith: "notEndsWith";
|
|
22
24
|
};
|
|
23
25
|
type Operator = (typeof Operator)[keyof typeof Operator];
|
|
24
26
|
declare const ArrayOperator: {
|
|
@@ -48,12 +50,95 @@ declare const DateOperator: {
|
|
|
48
50
|
};
|
|
49
51
|
type DateOperator = (typeof DateOperator)[keyof typeof DateOperator];
|
|
50
52
|
|
|
53
|
+
/** A selectable option — the standard `<select>` shape: a value with an optional display
|
|
54
|
+
* label, plus the partition keys (index-aligned with the source's `groupBy` axes)
|
|
55
|
+
* when the source is grouped. */
|
|
56
|
+
type SourceOption = {
|
|
57
|
+
value: string;
|
|
58
|
+
label?: string;
|
|
59
|
+
groups?: string[];
|
|
60
|
+
};
|
|
61
|
+
type FieldMapEntry = {
|
|
62
|
+
kind: 'scalar' | 'object' | 'enum' | 'bridge';
|
|
63
|
+
type: string;
|
|
64
|
+
isList?: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Whether the column is NOT NULL. `toPrisma` reads this to decide if a negated
|
|
67
|
+
* operator needs an explicit `equals: null` arm (Prisma's `not`/`notIn` follow SQL
|
|
68
|
+
* three-valued logic and drop NULL rows); absent = unknown = no arm.
|
|
69
|
+
*/
|
|
70
|
+
isRequired?: boolean;
|
|
71
|
+
fromFields?: string[];
|
|
72
|
+
toFields?: string[];
|
|
73
|
+
relationName?: string;
|
|
74
|
+
/**
|
|
75
|
+
* Per-field allowed values, primarily for enum fields. Takes precedence over
|
|
76
|
+
* `FieldMap.enums[type]` if both are set. Pass-through from codegen
|
|
77
|
+
* (e.g. prisma-map's `EnumField.values`). Consumed by `validateRuleInLens`.
|
|
78
|
+
*/
|
|
79
|
+
values?: readonly string[];
|
|
80
|
+
/**
|
|
81
|
+
* A field's selectable option set as `{ value, label? }` pairs — the display
|
|
82
|
+
* shape a picker consumes. On projection/surface output this is populated for
|
|
83
|
+
* every value-gated field (enum members normalized to `{ value, label: value }`)
|
|
84
|
+
* and for sourced fields (the fetched pairs from a materialized `SourceValues`).
|
|
85
|
+
*/
|
|
86
|
+
options?: readonly SourceOption[];
|
|
87
|
+
/**
|
|
88
|
+
* Present on projection/surface output when the field's source partitions its
|
|
89
|
+
* options: the dotted to-one axes (relative to this model) whose values are
|
|
90
|
+
* each option's `groups`, index-aligned.
|
|
91
|
+
*/
|
|
92
|
+
groupBy?: readonly string[];
|
|
93
|
+
};
|
|
94
|
+
type ModelEntry = {
|
|
95
|
+
dbName?: string | null;
|
|
96
|
+
fields: Record<string, FieldMapEntry>;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* A schema map: models keyed by name, plus an optional enum registry scoped to
|
|
100
|
+
* this source. In multi-source setups (Prisma + Salesforce + CRM) each FieldMap
|
|
101
|
+
* carries its own enums so namespaces don't collide across sources.
|
|
102
|
+
*/
|
|
103
|
+
type FieldMap = {
|
|
104
|
+
models: Record<string, ModelEntry>;
|
|
105
|
+
/** Enum name → allowed values, e.g. `{ UserRole: ['ADMIN', 'USER'] }`. */
|
|
106
|
+
enums?: Record<string, readonly string[]>;
|
|
107
|
+
};
|
|
108
|
+
type BridgeEndpoint = {
|
|
109
|
+
fieldMap: string;
|
|
110
|
+
model: string;
|
|
111
|
+
on: string;
|
|
112
|
+
};
|
|
113
|
+
type BridgeCardinality = 'oneToOne' | 'oneToMany';
|
|
114
|
+
/**
|
|
115
|
+
* A cross-source edge between two endpoints.
|
|
116
|
+
*
|
|
117
|
+
* Endpoint ordering convention for `oneToMany`:
|
|
118
|
+
* - `endpoints[0]` is the "one" side — its `on` field must be unique per row
|
|
119
|
+
* (typically a primary key).
|
|
120
|
+
* - `endpoints[1]` is the "many" side — its `on` field may repeat across rows
|
|
121
|
+
* (typically a foreign key).
|
|
122
|
+
*
|
|
123
|
+
* Mis-ordering produces wrong `isList` flags during stitching and silent
|
|
124
|
+
* row-dedup when building bridge dictionaries. `indexBridges` throws
|
|
125
|
+
* at runtime if endpoint[0]'s data has duplicate `on` values to catch this.
|
|
126
|
+
*
|
|
127
|
+
* For `oneToOne`, both `on` fields must be unique; endpoint order is symmetric.
|
|
128
|
+
*/
|
|
129
|
+
type Bridge = {
|
|
130
|
+
endpoints: [BridgeEndpoint, BridgeEndpoint];
|
|
131
|
+
cardinality: BridgeCardinality;
|
|
132
|
+
};
|
|
133
|
+
type FieldMapSet = {
|
|
134
|
+
maps: Record<string, FieldMap>;
|
|
135
|
+
bridges?: Bridge[];
|
|
136
|
+
};
|
|
137
|
+
|
|
51
138
|
type FuzzyConfig = {
|
|
52
139
|
maxDistance?: number;
|
|
53
140
|
maxRatio?: number;
|
|
54
141
|
};
|
|
55
|
-
declare const maxFuzzyDistance: (length: number) => number;
|
|
56
|
-
declare const fuzzyContains: (haystack: string, query: string, config?: FuzzyConfig) => boolean;
|
|
57
142
|
|
|
58
143
|
declare const FieldKind: {
|
|
59
144
|
readonly String: "String";
|
|
@@ -69,11 +154,7 @@ declare const FieldKind: {
|
|
|
69
154
|
};
|
|
70
155
|
type FieldKind = (typeof FieldKind)[keyof typeof FieldKind];
|
|
71
156
|
declare const NUMERIC_KINDS: readonly FieldKind[];
|
|
72
|
-
declare const ORDERABLE_KINDS: readonly FieldKind[];
|
|
73
|
-
declare const STRINGY_KINDS: readonly FieldKind[];
|
|
74
|
-
declare const EQUATABLE_KINDS: readonly FieldKind[];
|
|
75
157
|
declare const ALL_KINDS: readonly FieldKind[];
|
|
76
|
-
declare const NULLABLE_KINDS: readonly FieldKind[];
|
|
77
158
|
declare const RuleTarget: {
|
|
78
159
|
readonly check: "check";
|
|
79
160
|
readonly toPrisma: "toPrisma";
|
|
@@ -96,139 +177,15 @@ declare const ValueShape: {
|
|
|
96
177
|
readonly predicate: "predicate";
|
|
97
178
|
};
|
|
98
179
|
type ValueShape = (typeof ValueShape)[keyof typeof ValueShape];
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
valueShape: ValueShape;
|
|
103
|
-
acceptsExpr?: boolean;
|
|
104
|
-
};
|
|
105
|
-
declare const FIELD_OPERATOR_CATALOG: Record<Operator, CatalogEntry>;
|
|
106
|
-
declare const DATE_OPERATOR_CATALOG: Record<DateOperator, CatalogEntry>;
|
|
107
|
-
type ArrayCatalogEntry = {
|
|
108
|
-
targets: readonly RuleTarget[];
|
|
109
|
-
valueShape: ValueShape;
|
|
110
|
-
};
|
|
111
|
-
declare const ARRAY_OPERATOR_CATALOG: Record<ArrayOperator, ArrayCatalogEntry>;
|
|
112
|
-
declare const WindowSupport: {
|
|
113
|
-
readonly full: "full";
|
|
114
|
-
readonly extremal: "extremal";
|
|
115
|
-
readonly none: "none";
|
|
116
|
-
};
|
|
117
|
-
type WindowSupport = (typeof WindowSupport)[keyof typeof WindowSupport];
|
|
118
|
-
declare const WINDOW_SELECTOR: {
|
|
119
|
-
readonly fields: readonly ["filter", "orderBy", "take", "skip"];
|
|
120
|
-
readonly sortDirs: readonly ["asc", "desc"];
|
|
121
|
-
readonly support: {
|
|
122
|
-
readonly array: {
|
|
123
|
-
readonly check: "full";
|
|
124
|
-
readonly toPrisma: "extremal";
|
|
125
|
-
readonly toSql: "none";
|
|
126
|
-
};
|
|
127
|
-
readonly aggregate: {
|
|
128
|
-
readonly check: "full";
|
|
129
|
-
readonly toPrisma: "none";
|
|
130
|
-
readonly toSql: "none";
|
|
131
|
-
};
|
|
132
|
-
};
|
|
133
|
-
};
|
|
134
|
-
type WindowRuleType = keyof typeof WINDOW_SELECTOR.support;
|
|
135
|
-
declare const getWindowSupport: (ruleType: WindowRuleType, target: RuleTarget) => WindowSupport;
|
|
136
|
-
declare const AGGREGATE_OPERATORS: readonly Operator[];
|
|
137
|
-
/** The aggregate threshold comparisons `target` can compile — all of them when no
|
|
138
|
-
* target is given. The one source for both the validator's rejection and a builder's
|
|
139
|
-
* threshold picker, so neither has to restate which target drops which operator. */
|
|
140
|
-
declare const getAggregateOperators: (target?: RuleTarget) => readonly Operator[];
|
|
141
|
-
declare const isAggregateSingleOperator: (operator: Operator) => boolean;
|
|
142
|
-
declare const isAggregateRangeOperator: (operator: Operator) => boolean;
|
|
143
|
-
declare const getValueShape: (operator: Operator | DateOperator | ArrayOperator) => ValueShape;
|
|
144
|
-
declare const isOperatorSupportedForTarget: (operator: Operator | DateOperator | ArrayOperator, target: RuleTarget) => boolean;
|
|
180
|
+
/** Which catalog an operator belongs to — `between` is both a field and a date operator. */
|
|
181
|
+
type OperatorFamily = 'field' | 'date' | 'array';
|
|
182
|
+
declare const getValueShape: (operator: string, family: OperatorFamily) => ValueShape;
|
|
145
183
|
declare const getOperatorsForKind: (kind: FieldKind, target?: RuleTarget) => {
|
|
146
184
|
field: Operator[];
|
|
147
185
|
date: DateOperator[];
|
|
148
186
|
};
|
|
149
187
|
declare const getArrayOperators: (target?: RuleTarget) => ArrayOperator[];
|
|
150
|
-
|
|
151
|
-
declare const NO_VALUE_OPERATORS: readonly string[];
|
|
152
|
-
/** Field comparisons with an order: `<`, `<=`, `>`, `>=`. */
|
|
153
|
-
declare const ORDERED_OPERATORS: readonly string[];
|
|
154
|
-
/** A window expression (`within`), not a pair. */
|
|
155
|
-
declare const WINDOW_OPERATORS: readonly string[];
|
|
156
|
-
/** Operators that compare against two ends. */
|
|
157
|
-
declare const RANGE_OPERATORS: readonly string[];
|
|
158
|
-
/** Operators with a point to move: the comparisons and both ends of a pair. */
|
|
159
|
-
declare const OFFSET_OPERATORS: readonly string[];
|
|
160
|
-
/** The negations: each is the complement of its positive form and keeps NULL fields
|
|
161
|
-
* (the 2.19.0 ruling). */
|
|
162
|
-
declare const NEGATED_OPERATORS: readonly string[];
|
|
163
|
-
/** Negations of a two-ended range. */
|
|
164
|
-
declare const NEGATED_RANGE_OPERATORS: string[];
|
|
165
|
-
/** Negated comparisons an offset can move; with nothing to compare against they still keep a
|
|
166
|
-
* null field. */
|
|
167
|
-
declare const NEGATED_COMPARISON_OPERATORS: string[];
|
|
168
|
-
/** Negations of one literal (`notEquals`, `notContains`). */
|
|
169
|
-
declare const NEGATED_SINGLE_VALUE_OPERATORS: string[];
|
|
170
|
-
/** Comparisons that bound a field from above / below — what a window's extremal rewrite reads. */
|
|
171
|
-
declare const UPPER_BOUND_OPERATORS: readonly string[];
|
|
172
|
-
declare const LOWER_BOUND_OPERATORS: readonly string[];
|
|
173
|
-
/** Kinds a calendar unit amount can read: whole numbers. */
|
|
174
|
-
declare const INTEGER_KINDS: readonly FieldKind[];
|
|
175
|
-
/** Kinds check() coerces a literal to (see coerceScalar in src/field.ts). */
|
|
176
|
-
declare const COERCIBLE_KINDS: readonly FieldKind[];
|
|
177
|
-
/** Kinds whose literal the compilers coerce exactly as check() does — Prisma rejects a string on
|
|
178
|
-
* Int/Float/Boolean; BigInt compares as Int. Decimal keeps its literal: Prisma and Postgres take
|
|
179
|
-
* the numeric string losslessly, and a JS number would not. */
|
|
180
|
-
declare const COMPILE_COERCED_KINDS: readonly FieldKind[];
|
|
181
|
-
/** Value shapes that take one literal. */
|
|
182
|
-
declare const SINGLE_VALUE_SHAPES: readonly ValueShape[];
|
|
183
|
-
/** Each relative unit: the Postgres interval field it adds to, its size there, and whether it is
|
|
184
|
-
* a calendar unit (whole steps). Applied months, then days, then time, as Postgres does. */
|
|
185
|
-
declare const RELATIVE_UNITS: {
|
|
186
|
-
readonly years: {
|
|
187
|
-
readonly interval: "months";
|
|
188
|
-
readonly factor: 12;
|
|
189
|
-
readonly calendar: true;
|
|
190
|
-
};
|
|
191
|
-
readonly quarters: {
|
|
192
|
-
readonly interval: "months";
|
|
193
|
-
readonly factor: 3;
|
|
194
|
-
readonly calendar: true;
|
|
195
|
-
};
|
|
196
|
-
readonly months: {
|
|
197
|
-
readonly interval: "months";
|
|
198
|
-
readonly factor: 1;
|
|
199
|
-
readonly calendar: true;
|
|
200
|
-
};
|
|
201
|
-
readonly weeks: {
|
|
202
|
-
readonly interval: "days";
|
|
203
|
-
readonly factor: 7;
|
|
204
|
-
readonly calendar: true;
|
|
205
|
-
};
|
|
206
|
-
readonly days: {
|
|
207
|
-
readonly interval: "days";
|
|
208
|
-
readonly factor: 1;
|
|
209
|
-
readonly calendar: true;
|
|
210
|
-
};
|
|
211
|
-
readonly hours: {
|
|
212
|
-
readonly interval: "secs";
|
|
213
|
-
readonly factor: 3600;
|
|
214
|
-
readonly calendar: false;
|
|
215
|
-
};
|
|
216
|
-
readonly minutes: {
|
|
217
|
-
readonly interval: "secs";
|
|
218
|
-
readonly factor: 60;
|
|
219
|
-
readonly calendar: false;
|
|
220
|
-
};
|
|
221
|
-
readonly seconds: {
|
|
222
|
-
readonly interval: "secs";
|
|
223
|
-
readonly factor: 1;
|
|
224
|
-
readonly calendar: false;
|
|
225
|
-
};
|
|
226
|
-
};
|
|
227
|
-
type RelativeUnit = keyof typeof RELATIVE_UNITS;
|
|
228
|
-
declare const INTERVAL_FIELDS: readonly ["months", "days", "secs"];
|
|
229
|
-
declare const isRelativeUnit: (unit: string) => unit is RelativeUnit;
|
|
230
|
-
declare const isCalendarUnit: (unit: string) => boolean;
|
|
231
|
-
declare const PERIOD_UNITS: readonly string[];
|
|
188
|
+
declare const getAggregateOperators: () => readonly Operator[];
|
|
232
189
|
|
|
233
190
|
type OperatorValues = typeof Operator;
|
|
234
191
|
type ArrayOperatorValues = typeof ArrayOperator;
|
|
@@ -313,7 +270,7 @@ type StrictOrderedComparisonRule = (RuleBase<OperatorValues['lessThan']> & Value
|
|
|
313
270
|
type StrictMembershipRule<TValue = RuleValue> = (RuleBase<OperatorValues['in']> & ValueSource<TValue[]>) | (RuleBase<OperatorValues['notIn']> & ValueSource<TValue[]>);
|
|
314
271
|
type StrictContainsRule<TValue = RuleValue> = (RuleBase<OperatorValues['contains']> & ValueSource<TValue>) | (RuleBase<OperatorValues['notContains']> & ValueSource<TValue>);
|
|
315
272
|
type StrictPatternRule = (RuleBase<OperatorValues['matches']> & ValueSource<RegExp | string>) | (RuleBase<OperatorValues['notMatches']> & ValueSource<RegExp | string>);
|
|
316
|
-
type StrictStringBoundaryRule = (RuleBase<OperatorValues['startsWith']> & ValueSource<string>) | (RuleBase<OperatorValues['endsWith']> & ValueSource<string>);
|
|
273
|
+
type StrictStringBoundaryRule = (RuleBase<OperatorValues['startsWith']> & ValueSource<string>) | (RuleBase<OperatorValues['notStartsWith']> & ValueSource<string>) | (RuleBase<OperatorValues['endsWith']> & ValueSource<string>) | (RuleBase<OperatorValues['notEndsWith']> & ValueSource<string>);
|
|
317
274
|
type StrictRangeRule = (RuleBase<OperatorValues['between']> & ValueSource<[OrderedRuleValue, OrderedRuleValue], NumberOffset>) | (RuleBase<OperatorValues['notBetween']> & ValueSource<[OrderedRuleValue, OrderedRuleValue], NumberOffset>);
|
|
318
275
|
type StrictPresenceRule = (RuleBase<OperatorValues['isEmpty']> & NoValueSource) | (RuleBase<OperatorValues['notEmpty']> & NoValueSource) | (RuleBase<OperatorValues['exists']> & NoValueSource) | (RuleBase<OperatorValues['notExists']> & NoValueSource);
|
|
319
276
|
type StrictRule<TValue = RuleValue> = StrictEqualityRule<TValue> | StrictOrderedComparisonRule | StrictMembershipRule<TValue> | StrictContainsRule<TValue> | StrictPatternRule | StrictStringBoundaryRule | StrictRangeRule | StrictPresenceRule;
|
|
@@ -443,45 +400,36 @@ type StrictIfThenElse<TRuleValue = RuleValue, TDateValue = DateRuleValue> = {
|
|
|
443
400
|
error?: string;
|
|
444
401
|
};
|
|
445
402
|
type StrictCondition<TRuleValue = RuleValue, TDateValue = DateRuleValue> = StrictRule<TRuleValue> | StrictAggregateRule<TRuleValue, TDateValue> | StrictArrayRule<TRuleValue, TDateValue> | StrictDateRule | StrictAll<TRuleValue, TDateValue> | StrictAny<TRuleValue, TDateValue> | StrictIfThenElse<TRuleValue, TDateValue> | boolean;
|
|
403
|
+
/** A row as a rule reads it: a record of fields. */
|
|
404
|
+
type Row = Record<string, unknown>;
|
|
405
|
+
/** What both compilers take: the schema (a FieldMap, or a FieldMapSet with `mapName`), the
|
|
406
|
+
* model the rule reads, the context `$` refs read, and the clock. */
|
|
407
|
+
type CompileOptions = {
|
|
408
|
+
map?: FieldMap | FieldMapSet;
|
|
409
|
+
mapName?: string;
|
|
410
|
+
model?: string;
|
|
411
|
+
context?: Row;
|
|
412
|
+
} & DateConfig;
|
|
413
|
+
/** What check() evaluates: one row, or a root array of them. */
|
|
414
|
+
type CheckData = Row | unknown[];
|
|
446
415
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
416
|
+
/** `required`: leave out the names an optional bind (`bindOptional`) may go unsupplied. */
|
|
417
|
+
type ListBindingsOptions = {
|
|
418
|
+
required?: boolean;
|
|
450
419
|
};
|
|
451
|
-
declare const parseScopeRef: (ref: string) => ScopeRef | null;
|
|
452
|
-
type ScopedRef<S> = {
|
|
453
|
-
scope: S;
|
|
454
|
-
path: string;
|
|
455
|
-
};
|
|
456
|
-
type ScopeOutOfBounds = {
|
|
457
|
-
outOfBounds: string;
|
|
458
|
-
};
|
|
459
|
-
declare const resolveScopeRef: <S>(ref: string, scopes: readonly S[]) => ScopedRef<S> | ScopeOutOfBounds;
|
|
460
|
-
|
|
461
|
-
/**
|
|
462
|
-
* The value of one `{ bind }` at evaluation. Key presence is the contract: an unsupplied
|
|
463
|
-
* binding is a caller bug (a forgotten scope must never silently run) unless the source marks
|
|
464
|
-
* it `bindOptional`, which reads as null. A supplied-but-undefined binding is null.
|
|
465
|
-
*/
|
|
466
|
-
declare const readBinding: (name: string, optional: boolean | undefined, bindings: Record<string, RuleValue> | undefined) => RuleValue;
|
|
467
|
-
|
|
468
|
-
/** Names of every `{ bind }` token in the tree, optional or not — what a lens declares. */
|
|
469
|
-
declare const bindingNames: (condition: Condition) => Set<string>;
|
|
470
420
|
/**
|
|
471
|
-
*
|
|
472
|
-
*
|
|
473
|
-
*
|
|
421
|
+
* The bind names a rule reads, sorted. With `required`, only those a bindings map must cover —
|
|
422
|
+
* not `bindOptional` (unsupplied, it reads null); a name optional at one leaf and required at
|
|
423
|
+
* another is required.
|
|
474
424
|
*/
|
|
475
|
-
declare const
|
|
425
|
+
declare const listBindings: (condition: Condition, { required }?: ListBindingsOptions) => string[];
|
|
476
426
|
/**
|
|
477
427
|
* Substitute covered binds with their values; uncovered tokens stay in place (partial
|
|
478
428
|
* resolution). A supplied-but-undefined binding becomes null to stay serializable.
|
|
479
429
|
* Non-mutating.
|
|
480
430
|
*/
|
|
481
|
-
declare const
|
|
431
|
+
declare const bindRule: (condition: Condition, bindings: Record<string, RuleValue>) => Condition;
|
|
482
432
|
|
|
483
|
-
type Row$3 = Record<string, unknown>;
|
|
484
|
-
type CheckData = Row$3 | unknown[];
|
|
485
433
|
type CheckOptions = {
|
|
486
434
|
context?: CheckData;
|
|
487
435
|
bindings?: Record<string, RuleValue>;
|
|
@@ -498,6 +446,9 @@ type EngineGlobalsState = {
|
|
|
498
446
|
datasource: {
|
|
499
447
|
provider: PrismaProvider;
|
|
500
448
|
};
|
|
449
|
+
/** Prisma's `AnyNull` — matches a DB NULL, a JSON null and an absent Json path. Defaults to
|
|
450
|
+
* your installed @prisma/client's; set it only to use another. */
|
|
451
|
+
anyNull?: unknown;
|
|
501
452
|
};
|
|
502
453
|
};
|
|
503
454
|
type DeepPartial<T> = {
|
|
@@ -509,137 +460,33 @@ declare const engineGlobals: {
|
|
|
509
460
|
reset: () => void;
|
|
510
461
|
with: <T>(partial: DeepPartial<EngineGlobalsState>, fn: () => T) => T;
|
|
511
462
|
};
|
|
512
|
-
declare const supportsQueryMode: (provider: PrismaProvider) => boolean;
|
|
513
|
-
declare const resolveCaseInsensitive: (ruleFlag?: boolean) => boolean;
|
|
514
|
-
declare const resolveFuzzy: (ruleFlag?: boolean | FuzzyConfig) => FuzzyConfig | false;
|
|
515
|
-
|
|
516
|
-
type PrismaWhere = Record<string, unknown>;
|
|
517
|
-
/** A selectable option — the standard `<select>` shape: a value with an optional display
|
|
518
|
-
* label, plus the partition keys (index-aligned with the source's `groupBy` axes)
|
|
519
|
-
* when the source is grouped. */
|
|
520
|
-
type SourceOption = {
|
|
521
|
-
value: string;
|
|
522
|
-
label?: string;
|
|
523
|
-
groups?: string[];
|
|
524
|
-
};
|
|
525
|
-
type FieldMapEntry = {
|
|
526
|
-
kind: 'scalar' | 'object' | 'enum' | 'bridge';
|
|
527
|
-
type: string;
|
|
528
|
-
isList?: boolean;
|
|
529
|
-
/**
|
|
530
|
-
* Whether the column is NOT NULL. `toPrisma` reads this to decide if a negated
|
|
531
|
-
* operator needs an explicit `equals: null` arm (Prisma's `not`/`notIn` follow SQL
|
|
532
|
-
* three-valued logic and drop NULL rows); absent = unknown = no arm.
|
|
533
|
-
*/
|
|
534
|
-
isRequired?: boolean;
|
|
535
|
-
fromFields?: string[];
|
|
536
|
-
toFields?: string[];
|
|
537
|
-
relationName?: string;
|
|
538
|
-
/**
|
|
539
|
-
* Per-field allowed values, primarily for enum fields. Takes precedence over
|
|
540
|
-
* `FieldMap.enums[type]` if both are set. Pass-through from codegen
|
|
541
|
-
* (e.g. prisma-map's `EnumField.values`). Consumed by `checkRuleAgainstLens`.
|
|
542
|
-
*/
|
|
543
|
-
values?: readonly string[];
|
|
544
|
-
/**
|
|
545
|
-
* A field's selectable option set as `{ value, label? }` pairs — the display
|
|
546
|
-
* shape a picker consumes. On projection/surface output this is populated for
|
|
547
|
-
* every value-gated field (enum members normalized to `{ value, label: value }`)
|
|
548
|
-
* and for sourced fields (the fetched pairs from a materialized `SourceValues`).
|
|
549
|
-
*/
|
|
550
|
-
options?: readonly SourceOption[];
|
|
551
|
-
/**
|
|
552
|
-
* Present on projection/surface output when the field's source partitions its
|
|
553
|
-
* options: the dotted to-one axes (relative to this model) whose values are
|
|
554
|
-
* each option's `groups`, index-aligned.
|
|
555
|
-
*/
|
|
556
|
-
groupBy?: readonly string[];
|
|
557
|
-
};
|
|
558
|
-
type ModelEntry = {
|
|
559
|
-
dbName?: string | null;
|
|
560
|
-
fields: Record<string, FieldMapEntry>;
|
|
561
|
-
};
|
|
562
|
-
/**
|
|
563
|
-
* A schema map: models keyed by name, plus an optional enum registry scoped to
|
|
564
|
-
* this source. In multi-source setups (Prisma + Salesforce + CRM) each FieldMap
|
|
565
|
-
* carries its own enums so namespaces don't collide across sources.
|
|
566
|
-
*/
|
|
567
|
-
type FieldMap = {
|
|
568
|
-
models: Record<string, ModelEntry>;
|
|
569
|
-
/** Enum name → allowed values, e.g. `{ UserRole: ['ADMIN', 'USER'] }`. */
|
|
570
|
-
enums?: Record<string, readonly string[]>;
|
|
571
|
-
};
|
|
572
|
-
type StepRef = {
|
|
573
|
-
__step: number;
|
|
574
|
-
};
|
|
575
|
-
type GroupByStep = {
|
|
576
|
-
operation: 'groupBy';
|
|
577
|
-
model: string;
|
|
578
|
-
args: {
|
|
579
|
-
by: string[];
|
|
580
|
-
where: Record<string, unknown>;
|
|
581
|
-
having: Record<string, unknown>;
|
|
582
|
-
};
|
|
583
|
-
extract: string;
|
|
584
|
-
};
|
|
585
|
-
type WhereStep = {
|
|
586
|
-
operation: 'where';
|
|
587
|
-
where: Record<string, unknown>;
|
|
588
|
-
};
|
|
589
|
-
type PrismaStep = GroupByStep | WhereStep;
|
|
590
|
-
type ToPrismaResult = {
|
|
591
|
-
steps: PrismaStep[];
|
|
592
|
-
};
|
|
593
|
-
type BuildOptions = {
|
|
594
|
-
map?: FieldMap | FieldMapSet;
|
|
595
|
-
mapName?: string;
|
|
596
|
-
model?: string;
|
|
597
|
-
context?: Record<string, unknown>;
|
|
598
|
-
datasource?: {
|
|
599
|
-
provider?: PrismaProvider;
|
|
600
|
-
};
|
|
601
|
-
} & DateConfig;
|
|
602
|
-
|
|
603
|
-
type BridgeEndpoint = {
|
|
604
|
-
fieldMap: string;
|
|
605
|
-
model: string;
|
|
606
|
-
on: string;
|
|
607
|
-
};
|
|
608
|
-
type BridgeCardinality = 'oneToOne' | 'oneToMany';
|
|
609
|
-
/**
|
|
610
|
-
* A cross-source edge between two endpoints.
|
|
611
|
-
*
|
|
612
|
-
* Endpoint ordering convention for `oneToMany`:
|
|
613
|
-
* - `endpoints[0]` is the "one" side — its `on` field must be unique per row
|
|
614
|
-
* (typically a primary key).
|
|
615
|
-
* - `endpoints[1]` is the "many" side — its `on` field may repeat across rows
|
|
616
|
-
* (typically a foreign key).
|
|
617
|
-
*
|
|
618
|
-
* Mis-ordering produces wrong `isList` flags during stitching and silent
|
|
619
|
-
* row-dedup when building bridge dictionaries. `buildBridgeDictionary` throws
|
|
620
|
-
* at runtime if endpoint[0]'s data has duplicate `on` values to catch this.
|
|
621
|
-
*
|
|
622
|
-
* For `oneToOne`, both `on` fields must be unique; endpoint order is symmetric.
|
|
623
|
-
*/
|
|
624
|
-
type Bridge = {
|
|
625
|
-
endpoints: [BridgeEndpoint, BridgeEndpoint];
|
|
626
|
-
cardinality: BridgeCardinality;
|
|
627
|
-
};
|
|
628
|
-
type FieldMapSet = {
|
|
629
|
-
maps: Record<string, FieldMap>;
|
|
630
|
-
bridges?: Bridge[];
|
|
631
|
-
};
|
|
632
463
|
|
|
633
|
-
type Row$2 = Record<string, unknown>;
|
|
634
464
|
type BridgeDictionary = Record<string, // map name
|
|
635
465
|
Record<string, // model name
|
|
636
|
-
Record<string, Record<string, Row
|
|
637
|
-
declare const
|
|
466
|
+
Record<string, Record<string, Row | Row[]>>>>;
|
|
467
|
+
declare const indexBridges: (set: FieldMapSet, rawData: Record<string, Row[]>) => BridgeDictionary;
|
|
638
468
|
|
|
639
469
|
declare const stitchFieldMaps: (set: FieldMapSet) => FieldMapSet;
|
|
640
470
|
|
|
641
|
-
|
|
642
|
-
|
|
471
|
+
type ValidationIssue = {
|
|
472
|
+
path: string;
|
|
473
|
+
message: string;
|
|
474
|
+
code: string;
|
|
475
|
+
};
|
|
476
|
+
type ValidationResult = {
|
|
477
|
+
ok: boolean;
|
|
478
|
+
errors: ValidationIssue[];
|
|
479
|
+
};
|
|
480
|
+
/** Which engine a rule must compile for; `check` (the default) accepts every rule. */
|
|
481
|
+
type ValidateRuleOptions = {
|
|
482
|
+
target?: RuleTarget;
|
|
483
|
+
};
|
|
484
|
+
declare const validateRule: (condition: unknown, options?: ValidateRuleOptions) => ValidationResult;
|
|
485
|
+
declare const assertValidRule: (condition: unknown, options?: ValidateRuleOptions) => asserts condition is Condition;
|
|
486
|
+
|
|
487
|
+
/** Field names are plain identifiers: `.` walks a path and `:` names a bridge target. */
|
|
488
|
+
declare const validateFieldMaps: (set: FieldMapSet) => ValidationResult;
|
|
489
|
+
declare const assertValidFieldMaps: (set: FieldMapSet) => void;
|
|
643
490
|
|
|
644
491
|
type Lens = FieldMapSet & {
|
|
645
492
|
mapName: string;
|
|
@@ -653,8 +500,8 @@ type Lens = FieldMapSet & {
|
|
|
653
500
|
* - SCHEMA narrowing (picks/omits/enumPicks/enumOmits): controls what's visible
|
|
654
501
|
* in the type surface. AI/SDK consumers can't see narrowed-away fields.
|
|
655
502
|
* - DATA narrowing (where): controls which ROWS are in scope. Filter-first
|
|
656
|
-
* semantic, anchored to the model. Under arrayOperator: 'all',
|
|
657
|
-
*
|
|
503
|
+
* semantic, anchored to the model. Under arrayOperator: 'all', it becomes the window filter
|
|
504
|
+
* (filter-first) — see narrowRule.
|
|
658
505
|
*/
|
|
659
506
|
type ModelDefaultNarrowing = {
|
|
660
507
|
picks?: string[];
|
|
@@ -677,7 +524,7 @@ type ModelDefaultNarrowing = {
|
|
|
677
524
|
* model that path resolves to. The `where` composes AND-only across layers (general
|
|
678
525
|
* via `mapDefaults`, path-specific via `root`/`relations`); a later layer's `label` wins.
|
|
679
526
|
*/
|
|
680
|
-
sources?: Record<string,
|
|
527
|
+
sources?: Record<string, SourceEntry>;
|
|
681
528
|
};
|
|
682
529
|
/**
|
|
683
530
|
* A sourced field's eligibility `where` plus an optional display-label column — a
|
|
@@ -701,7 +548,7 @@ type SourceSpec = {
|
|
|
701
548
|
groupBy: string | string[];
|
|
702
549
|
};
|
|
703
550
|
/** A `sources` entry: a bare eligibility `Condition`, or a richer `SourceSpec`. */
|
|
704
|
-
type
|
|
551
|
+
type SourceEntry = Condition | SourceSpec;
|
|
705
552
|
/** Narrowing for a model at a specific traversal path. Adds relations to the default shape. */
|
|
706
553
|
type ModelNarrowing = ModelDefaultNarrowing & {
|
|
707
554
|
relations?: Record<string, ModelNarrowing>;
|
|
@@ -730,8 +577,6 @@ type LensNarrowing = {
|
|
|
730
577
|
mapDefaults?: Record<string, NarrowingDefaults>;
|
|
731
578
|
};
|
|
732
579
|
|
|
733
|
-
declare const applyLens: (rule: Condition, lensOrNarrowing: Lens | LensNarrowing) => Condition;
|
|
734
|
-
|
|
735
580
|
/**
|
|
736
581
|
* Every bind name a lens (its whole narrowing chain) needs supplied to execute —
|
|
737
582
|
* `bindOptional` tokens are not required (unsupplied, they resolve to null).
|
|
@@ -740,29 +585,74 @@ declare const applyLens: (rule: Condition, lensOrNarrowing: Lens | LensNarrowing
|
|
|
740
585
|
* this lens require" answer; pass `narrowing.parent` to see the names a child must
|
|
741
586
|
* not collide with.
|
|
742
587
|
*/
|
|
743
|
-
declare const
|
|
588
|
+
declare const listLensBindings: (lensOrNarrowing: Lens | LensNarrowing) => string[];
|
|
744
589
|
/**
|
|
745
590
|
* Preprocess a lens: resolve every `{ bind }` token the map covers in the chain's
|
|
746
591
|
* `where`/`sources`, returning a structurally-new lens with concrete conditions.
|
|
747
592
|
* Partial — uncovered tokens stay, so stages bind progressively. Once resolved,
|
|
748
|
-
* `
|
|
593
|
+
* `narrowRule` / `toPrisma` / `toSql` / `toSourceQueries` / `projectPaths` consume the
|
|
749
594
|
* lens unchanged: a bind needs nothing new downstream. `parent:name` draws the same
|
|
750
595
|
* value as the ancestor's `name`. Does not mutate the input.
|
|
751
596
|
*/
|
|
752
|
-
declare const
|
|
597
|
+
declare const bindLens: (lensOrNarrowing: Lens | LensNarrowing, bindings: Record<string, RuleValue>) => Lens | LensNarrowing;
|
|
598
|
+
|
|
599
|
+
declare const coerceRule: (condition: Condition, lensOrNarrowing: Lens | LensNarrowing) => Condition;
|
|
600
|
+
|
|
601
|
+
/** A lens over field maps, its bridges stitched into the maps as fields. */
|
|
602
|
+
declare const createLens: ({ maps, bridges, mapName, model }: Lens) => Lens;
|
|
603
|
+
|
|
604
|
+
type RuleDescription = {
|
|
605
|
+
sources: string[];
|
|
606
|
+
bridgesCrossed: boolean;
|
|
607
|
+
supportedTargets: RuleTarget[];
|
|
608
|
+
/** What the lens refuses in the rule — validateRuleInLens's issues. */
|
|
609
|
+
errors: ValidationIssue[];
|
|
610
|
+
};
|
|
611
|
+
declare const describeRule: (rule: Condition, lensOrNarrowing: Lens | LensNarrowing) => RuleDescription;
|
|
612
|
+
|
|
753
613
|
/**
|
|
754
|
-
*
|
|
755
|
-
*
|
|
756
|
-
*
|
|
757
|
-
*
|
|
614
|
+
* The values one rule compares at one declared source — keyed the way `projectPaths`
|
|
615
|
+
* keys a source (`path` + `field`), so the caller can join it back to the source's
|
|
616
|
+
* model without spelling a path of its own. A `mapDefaults`-declared source resolves
|
|
617
|
+
* wherever its model appears, so `path` may name a relation chain the narrowing never
|
|
618
|
+
* spelled under `root.relations`; the dotted format is the same.
|
|
758
619
|
*/
|
|
759
|
-
|
|
620
|
+
type RuleSourceDescription = {
|
|
621
|
+
path: string;
|
|
622
|
+
mapName: string;
|
|
623
|
+
model: string;
|
|
624
|
+
field: string;
|
|
625
|
+
/** Every literal a leaf at this source named; list operators flattened, deduped by content. */
|
|
626
|
+
values: RuleValue[];
|
|
627
|
+
/**
|
|
628
|
+
* The set of values cannot be enumerated from literals: a leaf read a value at evaluation
|
|
629
|
+
* (a `path` / `bind` on its comparison value, an offset or an amount) or moved it by an offset, used an operator that describes values without naming them
|
|
630
|
+
* (substring, pattern, range, date window), or used an operator the catalog does not
|
|
631
|
+
* know. A caller deciding anything from `values` must fail closed.
|
|
632
|
+
*/
|
|
633
|
+
dynamic: boolean;
|
|
634
|
+
};
|
|
635
|
+
/**
|
|
636
|
+
* Which values a rule names at each source the lens declares — the lens owns the
|
|
637
|
+
* vocabulary, so it answers questions about it; callers never spell a path. A leaf reaches a
|
|
638
|
+
* source by its absolute path through the lens: nested (`{ field: 'orders', arrayOperator,
|
|
639
|
+
* condition: { field: 'sku' } }`) and dotted (`{ field: 'orders.sku' }`) spellings are one path,
|
|
640
|
+
* resolved by `lensPathEnd` — visibility, `mapDefaults`, and the Json boundary all apply, so a
|
|
641
|
+
* source declared in `mapDefaults` answers wherever its model appears. Quantifier-blind on
|
|
642
|
+
* purpose — a `none` relation names its value as much as an `any` one, `notIn` as much as `in` —
|
|
643
|
+
* but shape-aware via the operator catalog: only literal-naming shapes contribute `values`;
|
|
644
|
+
* substring / pattern / range / window operators, and operators the catalog does not know, mark
|
|
645
|
+
* the source `dynamic` instead of inventing values. A relation node's own comparison (an
|
|
646
|
+
* aggregate's threshold, an array `count`) belongs to the node, not to a source. Paths invisible
|
|
647
|
+
* under the lens, unmapped segments, and sub-paths beneath a Json column are silent.
|
|
648
|
+
*/
|
|
649
|
+
declare const describeRuleSources: (rule: Condition, lensOrNarrowing: Lens | LensNarrowing) => RuleSourceDescription[];
|
|
760
650
|
|
|
761
651
|
type LensPathHop = {
|
|
762
652
|
field: string;
|
|
763
653
|
entry: FieldMapEntry;
|
|
764
654
|
mapName: string;
|
|
765
|
-
|
|
655
|
+
model: string;
|
|
766
656
|
/** The relation path from the lens anchor to the model this hop reads. */
|
|
767
657
|
relPath: string[];
|
|
768
658
|
};
|
|
@@ -783,35 +673,9 @@ type LensPathResolution = {
|
|
|
783
673
|
hops: LensPathHop[];
|
|
784
674
|
};
|
|
785
675
|
|
|
786
|
-
type RuleLensViolation = {
|
|
787
|
-
path: string;
|
|
788
|
-
reason: string;
|
|
789
|
-
};
|
|
790
|
-
type RuleLensCheck = {
|
|
791
|
-
ok: boolean;
|
|
792
|
-
violations: RuleLensViolation[];
|
|
793
|
-
};
|
|
794
|
-
declare const checkRuleAgainstLens: (rule: Condition, lensOrNarrowing: Lens | LensNarrowing) => RuleLensCheck;
|
|
795
|
-
|
|
796
|
-
type CreateLensInput = {
|
|
797
|
-
maps: Record<string, FieldMap>;
|
|
798
|
-
bridges?: Bridge[];
|
|
799
|
-
mapName: string;
|
|
800
|
-
model: string;
|
|
801
|
-
};
|
|
802
|
-
declare const createLens: (input: CreateLensInput) => Lens;
|
|
803
|
-
|
|
804
|
-
type RuleDescription = {
|
|
805
|
-
sources: string[];
|
|
806
|
-
bridgesCrossed: boolean;
|
|
807
|
-
supportedTargets: RuleTarget[];
|
|
808
|
-
violations: string[];
|
|
809
|
-
};
|
|
810
|
-
declare const describeRule: (rule: Condition, lensOrNarrowing: Lens | LensNarrowing) => RuleDescription;
|
|
811
|
-
|
|
812
676
|
type ProjectedVisit = {
|
|
813
677
|
mapName: string;
|
|
814
|
-
|
|
678
|
+
model: string;
|
|
815
679
|
fields: Record<string, FieldMapEntry>;
|
|
816
680
|
whereClauses: Condition[];
|
|
817
681
|
/** Per-field source eligibility wheres, composed across layers (general + path). */
|
|
@@ -822,12 +686,13 @@ type ProjectedVisit = {
|
|
|
822
686
|
/** Per-field option-partition axes for a sourced field (from a SourceSpec's `groupBy`). */
|
|
823
687
|
sourceGroupBys: Record<string, string[]>;
|
|
824
688
|
};
|
|
825
|
-
|
|
689
|
+
/** Each declared path's projected visit, keyed by dotted path from the lens model. */
|
|
690
|
+
type PathProjection = Record<string, ProjectedVisit>;
|
|
826
691
|
/**
|
|
827
692
|
* The materialized option set for one sourced field — the fetched companion to a
|
|
828
693
|
* serializable lens. Its `options` are `{ value, label? }` pairs (the standard
|
|
829
|
-
* `<select>` shape); it feeds both projections: `
|
|
830
|
-
* `path`+`field` (exact), `
|
|
694
|
+
* `<select>` shape); it feeds both projections: `projectPaths` keys by
|
|
695
|
+
* `path`+`field` (exact), `projectModels` by `mapName`+`model`+`field` (union).
|
|
831
696
|
*/
|
|
832
697
|
type SourceValues = {
|
|
833
698
|
path: string;
|
|
@@ -836,61 +701,37 @@ type SourceValues = {
|
|
|
836
701
|
field: string;
|
|
837
702
|
options: readonly SourceOption[];
|
|
838
703
|
};
|
|
839
|
-
type
|
|
704
|
+
type ProjectLensOptions = {
|
|
840
705
|
sourceValues?: readonly SourceValues[];
|
|
841
706
|
};
|
|
842
|
-
declare const projectByPath: (lensOrNarrowing: Lens | LensNarrowing, opts?: ProjectOptions) => PathProjection;
|
|
843
|
-
|
|
844
|
-
declare const exposedSurface: (lensOrNarrowing: Lens | LensNarrowing, opts?: ProjectOptions) => Lens;
|
|
845
707
|
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
* `checkRuleAgainstLens` gates a rule's field with, exposed for consumers that resolve paths of their
|
|
853
|
-
* own (template tokens, loop bindings, presence guards).
|
|
854
|
-
*/
|
|
855
|
-
declare const resolveLensPath: (lensOrNarrowing: Lens | LensNarrowing, path: string) => LensPathResolution;
|
|
856
|
-
|
|
857
|
-
/**
|
|
858
|
-
* The values one rule compares at one declared source — keyed the way `projectByPath`
|
|
859
|
-
* keys a source (`path` + `field`), so the caller can join it back to the source's
|
|
860
|
-
* model without spelling a path of its own. A `mapDefaults`-declared source resolves
|
|
861
|
-
* wherever its model appears, so `path` may name a relation chain the narrowing never
|
|
862
|
-
* spelled under `root.relations`; the dotted format is the same.
|
|
863
|
-
*/
|
|
864
|
-
type RuleSourceValues = {
|
|
865
|
-
path: string;
|
|
866
|
-
mapName: string;
|
|
708
|
+
type PrismaWhere = Record<string, unknown>;
|
|
709
|
+
type StepRef = {
|
|
710
|
+
__step: number;
|
|
711
|
+
};
|
|
712
|
+
type GroupByStep = {
|
|
713
|
+
operation: 'groupBy';
|
|
867
714
|
model: string;
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
715
|
+
args: {
|
|
716
|
+
by: string[];
|
|
717
|
+
where: Record<string, unknown>;
|
|
718
|
+
having: Record<string, unknown>;
|
|
719
|
+
};
|
|
720
|
+
extract: string;
|
|
721
|
+
};
|
|
722
|
+
type WhereStep = {
|
|
723
|
+
operation: 'where';
|
|
724
|
+
where: Record<string, unknown>;
|
|
725
|
+
};
|
|
726
|
+
type PrismaStep = GroupByStep | WhereStep;
|
|
727
|
+
type ToPrismaResult = {
|
|
728
|
+
steps: PrismaStep[];
|
|
729
|
+
};
|
|
730
|
+
type ToPrismaOptions = CompileOptions & {
|
|
731
|
+
datasource?: {
|
|
732
|
+
provider?: PrismaProvider;
|
|
733
|
+
};
|
|
878
734
|
};
|
|
879
|
-
/**
|
|
880
|
-
* Which values a rule names at each source the lens declares — the lens owns the
|
|
881
|
-
* vocabulary, so it answers questions about it; callers never spell a path. A leaf reaches a
|
|
882
|
-
* source by its absolute path through the lens: nested (`{ field: 'orders', arrayOperator,
|
|
883
|
-
* condition: { field: 'sku' } }`) and dotted (`{ field: 'orders.sku' }`) spellings are one path,
|
|
884
|
-
* resolved by `walkLensPath` — visibility, `mapDefaults`, and the Json boundary all apply, so a
|
|
885
|
-
* source declared in `mapDefaults` answers wherever its model appears. Quantifier-blind on
|
|
886
|
-
* purpose — a `none` relation names its value as much as an `any` one, `notIn` as much as `in` —
|
|
887
|
-
* but shape-aware via the operator catalog: only literal-naming shapes contribute `values`;
|
|
888
|
-
* substring / pattern / range / window operators, and operators the catalog does not know, mark
|
|
889
|
-
* the source `dynamic` instead of inventing values. A relation node's own comparison (an
|
|
890
|
-
* aggregate's threshold, an array `count`) belongs to the node, not to a source. Paths invisible
|
|
891
|
-
* under the lens, unmapped segments, and sub-paths beneath a Json column are silent.
|
|
892
|
-
*/
|
|
893
|
-
declare const ruleSourceValues: (lensOrNarrowing: Lens | LensNarrowing, rule: Condition) => RuleSourceValues[];
|
|
894
735
|
|
|
895
736
|
/** Prisma `select` shape — nested for a grouped source's relation path. */
|
|
896
737
|
type SourceSelect = {
|
|
@@ -901,11 +742,11 @@ type SourceSelect = {
|
|
|
901
742
|
type SourcePrismaQuery = {
|
|
902
743
|
model: string;
|
|
903
744
|
/** Absent for grouped sources — DISTINCT on the value column alone would collapse
|
|
904
|
-
* same-value rows across groups; dedup happens in `
|
|
745
|
+
* same-value rows across groups; dedup happens in `materializeSourceQuery`. */
|
|
905
746
|
distinct?: string[];
|
|
906
747
|
select: SourceSelect;
|
|
907
748
|
where: PrismaWhere;
|
|
908
|
-
/** Present only if the composed where used count operators (run via
|
|
749
|
+
/** Present only if the composed where used count operators (run via executePrismaPlan). */
|
|
909
750
|
steps?: PrismaStep[];
|
|
910
751
|
};
|
|
911
752
|
/** `sql` is null when the composed where uses a predicate SQL can't express
|
|
@@ -937,41 +778,103 @@ type SourceQuery = {
|
|
|
937
778
|
* the projected lens. The WHERE is the field's composed eligibility: the model's
|
|
938
779
|
* own narrowing at that path AND its source where(s). The app runs these (with
|
|
939
780
|
* its own client) to materialize each field's option set — feed the fetched rows
|
|
940
|
-
* to `
|
|
781
|
+
* to `materializeSourceQuery`.
|
|
941
782
|
*/
|
|
942
|
-
declare const
|
|
783
|
+
declare const toSourceQueries: (lensOrNarrowing: Lens | LensNarrowing) => SourceQuery[];
|
|
943
784
|
|
|
944
|
-
type Row$1 = Record<string, unknown>;
|
|
945
785
|
/** Which executor produced the rows — the caller always knows; never guessed. */
|
|
946
786
|
type SourceRowShape = 'prisma' | 'sql';
|
|
947
787
|
/**
|
|
948
788
|
* Materialize one compiled `SourceQuery`'s fetched rows into its `SourceValues` —
|
|
949
|
-
* the executor-side counterpart of `
|
|
789
|
+
* the executor-side counterpart of `toSourceQueries`, so apps never hand-map rows.
|
|
950
790
|
* `rowShape` names the wire format: prisma rows (default) nest each `groupBy` axis
|
|
951
791
|
* (and a dotted `label`) as related objects; sql rows carry them flat under the
|
|
952
792
|
* statement's `__group_i` / `__label` aliases. Grouped queries fetch without
|
|
953
793
|
* DISTINCT, so dedup per (groups, value) happens here.
|
|
954
794
|
*/
|
|
955
|
-
|
|
795
|
+
/** `rowShape`: how the rows came back — nested Prisma rows (the default) or flat SQL rows. */
|
|
796
|
+
type MaterializeSourceQueryOptions = {
|
|
956
797
|
rowShape?: SourceRowShape;
|
|
957
|
-
}
|
|
798
|
+
};
|
|
799
|
+
declare const materializeSourceQuery: (query: SourceQuery, rows: readonly Row[], opts?: MaterializeSourceQueryOptions) => SourceValues;
|
|
958
800
|
|
|
959
|
-
type Row = Record<string, unknown>;
|
|
960
801
|
/**
|
|
961
802
|
* Materialize each sourced field's option set from an already-fetched collection —
|
|
962
|
-
* the in-memory executor of `sources` declarations, alongside `
|
|
803
|
+
* the in-memory executor of `sources` declarations, alongside `toSourceQueries`
|
|
963
804
|
* (which compiles the same declarations to DISTINCT queries for a DB). Rows are
|
|
964
|
-
* the collection fetched
|
|
965
|
-
*
|
|
966
|
-
*
|
|
805
|
+
* the collection fetched under the lens (relations inline). Each row must meet the field's
|
|
806
|
+
* eligibility as `toSourceQueries` composes it — its source `where`, the grants above it, the
|
|
807
|
+
* guards of the relations it crosses and any allowed values — evaluated with `check()`
|
|
808
|
+
* (`options` feeds `{bind}` clauses). Scalar-list fields contribute one
|
|
967
809
|
* option per element, labels take the first non-null value of the label column
|
|
968
810
|
* (a sibling, or a dotted to-one path read through the nested rows), and sorting is
|
|
969
|
-
* numeric-aware in a fixed locale. Feed the result to `
|
|
970
|
-
|
|
811
|
+
* numeric-aware in a fixed locale. Feed the result to `projectLens` as `{ sourceValues }`.
|
|
812
|
+
*/
|
|
813
|
+
declare const materializeSources: (lensOrNarrowing: Lens | LensNarrowing, rows: readonly Row[], options?: CheckOptions) => SourceValues[];
|
|
814
|
+
|
|
815
|
+
declare const validateNarrowing: (narrowing: LensNarrowing) => ValidationResult;
|
|
816
|
+
declare const assertValidNarrowing: (narrowing: LensNarrowing) => void;
|
|
817
|
+
|
|
818
|
+
declare const narrowRule: (rule: Condition, lensOrNarrowing: Lens | LensNarrowing) => Condition;
|
|
819
|
+
|
|
820
|
+
/**
|
|
821
|
+
* What a narrowed lens exposes. `by: 'path'` (the default) projects each declared path — its
|
|
822
|
+
* visible fields, `where` clauses and sources — keyed by dotted path. `by: 'model'` flattens the
|
|
823
|
+
* whole surface into a Lens: every model a path or relation reaches, each field the union of its
|
|
824
|
+
* visits, bridges kept only where an exposed field crosses them.
|
|
825
|
+
*/
|
|
826
|
+
declare function projectLens(lensOrNarrowing: Lens | LensNarrowing, options?: ProjectLensOptions & {
|
|
827
|
+
by?: 'path';
|
|
828
|
+
}): PathProjection;
|
|
829
|
+
declare function projectLens(lensOrNarrowing: Lens | LensNarrowing, options: ProjectLensOptions & {
|
|
830
|
+
by: 'model';
|
|
831
|
+
}): Lens;
|
|
832
|
+
|
|
833
|
+
/**
|
|
834
|
+
* A lens as stored, one record per layer: its `id`, the ids of every layer it composes with —
|
|
835
|
+
* the base lens first, the nearest parent last — and its own part. The base lens is the
|
|
836
|
+
* root-most layer: the lens itself, with no parents.
|
|
837
|
+
*/
|
|
838
|
+
type StoredLens = {
|
|
839
|
+
id: string;
|
|
840
|
+
parents: string[];
|
|
841
|
+
} & (Lens | Omit<LensNarrowing, 'parent'>);
|
|
842
|
+
/**
|
|
843
|
+
* The composed lens a stored layer resolves to: its parents, read from `records`, nested from
|
|
844
|
+
* the base down, each layer validated against the ones above it. Fails closed on a missing
|
|
845
|
+
* record, a base that isn't first, or a parent whose own parents disagree with the list.
|
|
846
|
+
*/
|
|
847
|
+
declare const composeLens: (id: string, records: Record<string, StoredLens>) => Lens | LensNarrowing;
|
|
848
|
+
/** A composed lens as the records `composeLens` reads back: one per layer, the base first,
|
|
849
|
+
* named by `ids` in the same order. */
|
|
850
|
+
declare const storeLens: (lens: Lens | LensNarrowing, ids: readonly string[]) => StoredLens[];
|
|
851
|
+
|
|
852
|
+
/** Gate a rule against a lens: every field and value-side ref resolves through it, and every
|
|
853
|
+
* operator, value and amount fits the field it reaches. */
|
|
854
|
+
declare const validateRuleInLens: (rule: Condition, lensOrNarrowing: Lens | LensNarrowing) => ValidationResult;
|
|
855
|
+
|
|
856
|
+
/**
|
|
857
|
+
* Resolve one dotted path through a lens, hop by hop, verifying as it walks: every hop is checked
|
|
858
|
+
* against the narrowing at that visit, so a relation the narrowing dropped is `hidden`, a column the
|
|
859
|
+
* model lacks is `missing`, and a segment past a scalar is `pastScalar`. This is the walk
|
|
860
|
+
* `validateRuleInLens` gates a rule's field with, exposed for consumers that resolve paths of their
|
|
861
|
+
* own (template tokens, loop bindings, presence guards).
|
|
971
862
|
*/
|
|
972
|
-
declare const
|
|
863
|
+
declare const walkLensPath: (lensOrNarrowing: Lens | LensNarrowing, path: string) => LensPathResolution;
|
|
973
864
|
|
|
974
|
-
|
|
865
|
+
type ScopeRef = {
|
|
866
|
+
depth: number;
|
|
867
|
+
path: string;
|
|
868
|
+
};
|
|
869
|
+
declare const parseScopeRef: (ref: string) => ScopeRef | null;
|
|
870
|
+
type ScopedRef<S> = {
|
|
871
|
+
scope: S;
|
|
872
|
+
path: string;
|
|
873
|
+
};
|
|
874
|
+
type ScopeOutOfBounds = {
|
|
875
|
+
outOfBounds: string;
|
|
876
|
+
};
|
|
877
|
+
declare const readScopeRef: <S>(ref: string, scopes: readonly S[]) => ScopedRef<S> | ScopeOutOfBounds;
|
|
975
878
|
|
|
976
879
|
/**
|
|
977
880
|
* Execute a Prisma query plan produced by toPrisma().
|
|
@@ -987,75 +890,39 @@ declare const stampCoercions: (condition: Condition, lensOrNarrowing: Lens | Len
|
|
|
987
890
|
*
|
|
988
891
|
* @example
|
|
989
892
|
* const plan = toPrisma(condition, { map, model: 'User' });
|
|
990
|
-
* const where = await
|
|
893
|
+
* const where = await executePrismaPlan(plan, { post: prisma.post });
|
|
991
894
|
* await prisma.user.findMany({ where });
|
|
992
895
|
*/
|
|
993
|
-
declare const
|
|
896
|
+
declare const executePrismaPlan: (plan: ToPrismaResult, prismaDelegate: Record<string, Record<string, (...args: unknown[]) => unknown>>) => Promise<Record<string, unknown>>;
|
|
994
897
|
|
|
995
898
|
/**
|
|
996
|
-
*
|
|
997
|
-
*
|
|
998
|
-
*
|
|
999
|
-
*
|
|
1000
|
-
* - `steps` – optional array of groupBy steps for count-based relation filters
|
|
1001
|
-
* (only present when `atLeast`/`atMost`/`exactly` operators are used with a map)
|
|
1002
|
-
*
|
|
1003
|
-
* When `steps` is present, pass the result to `executePrismaQueryPlan` to
|
|
1004
|
-
* resolve step refs before using `where` in a Prisma query.
|
|
1005
|
-
*
|
|
1006
|
-
* @param condition - The rule condition to convert
|
|
1007
|
-
* @param options - Optional map, model, and context
|
|
899
|
+
* Compile a condition to a Prisma query plan: `steps`, any groupBy steps (counts and relation
|
|
900
|
+
* aggregates, which need `{ map, model }`) and then the final `where`. Run a plan with
|
|
901
|
+
* `executePrismaPlan(plan, client)` to resolve step refs; a single-step plan's `where` is its
|
|
902
|
+
* last step's.
|
|
1008
903
|
*
|
|
1009
904
|
* @example
|
|
1010
905
|
* ```typescript
|
|
1011
|
-
*
|
|
1012
|
-
*
|
|
1013
|
-
* // → { where: { status: { equals: 'active' } } }
|
|
1014
|
-
*
|
|
1015
|
-
* // JSON field detection (map required)
|
|
1016
|
-
* toPrisma({ field: 'metadata.theme', operator: Operator.equals, value: 'dark' }, { map, model: 'User' })
|
|
1017
|
-
* // → { where: { metadata: { path: ['theme'], equals: 'dark' } } }
|
|
906
|
+
* toPrisma({ field: 'status', operator: Operator.equals, value: 'active' }).steps
|
|
907
|
+
* // → [{ operation: 'where', where: { status: { equals: 'active' } } }]
|
|
1018
908
|
*
|
|
1019
|
-
*
|
|
1020
|
-
*
|
|
1021
|
-
* // → { where: { userId: { equals: '123' } } }
|
|
1022
|
-
*
|
|
1023
|
-
* // Multi-step (map required)
|
|
1024
|
-
* const plan = toPrisma({ field: 'posts', arrayOperator: 'atLeast', count: 3, condition: {...} }, { map, model: 'User' });
|
|
1025
|
-
* const where = await executePrismaQueryPlan(plan, { post: prisma.post });
|
|
909
|
+
* const plan = toPrisma({ field: 'posts', arrayOperator: 'atLeast', count: 3, condition }, { map, model: 'User' });
|
|
910
|
+
* const where = await executePrismaPlan(plan, prisma);
|
|
1026
911
|
* await prisma.user.findMany({ where });
|
|
1027
912
|
* ```
|
|
1028
913
|
*/
|
|
1029
|
-
declare const toPrisma: (condition: Condition, options?:
|
|
914
|
+
declare const toPrisma: (condition: Condition, options?: ToPrismaOptions) => ToPrismaResult;
|
|
1030
915
|
|
|
1031
|
-
type
|
|
916
|
+
type ToSqlResult = {
|
|
1032
917
|
sql: string;
|
|
1033
918
|
params: unknown[];
|
|
1034
919
|
joins: string[];
|
|
1035
920
|
};
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
map?: FieldMap;
|
|
1039
|
-
model?: string;
|
|
921
|
+
type ToSqlOptions = CompileOptions & {
|
|
922
|
+
/** The root table alias; `t0` when a map is given. */
|
|
1040
923
|
alias?: string;
|
|
1041
|
-
context?: Record<string, unknown>;
|
|
1042
|
-
} & DateConfig;
|
|
1043
|
-
declare const toSql: (condition: Condition, options?: SqlBuildOptions) => SqlResult;
|
|
1044
|
-
|
|
1045
|
-
type ValidationIssue = {
|
|
1046
|
-
path: string;
|
|
1047
|
-
message: string;
|
|
1048
|
-
code: string;
|
|
1049
924
|
};
|
|
1050
|
-
type ValidationResult = {
|
|
1051
|
-
ok: boolean;
|
|
1052
|
-
errors: ValidationIssue[];
|
|
1053
|
-
};
|
|
1054
|
-
declare const validateRule: (condition: unknown, options?: {
|
|
1055
|
-
target?: RuleTarget;
|
|
1056
|
-
}) => ValidationResult;
|
|
1057
|
-
declare const assertValidRule: (condition: unknown, options?: {
|
|
1058
|
-
target?: RuleTarget;
|
|
1059
|
-
}) => asserts condition is Condition;
|
|
1060
925
|
|
|
1061
|
-
|
|
926
|
+
declare const toSql: (condition: Condition, options?: ToSqlOptions) => ToSqlResult;
|
|
927
|
+
|
|
928
|
+
export { ALL_KINDS, type AggregateMode, type AggregateRule, type All, type Any, ArrayOperator, type ArrayRule, type Bridge, type BridgeCardinality, type BridgeDictionary, type BridgeEndpoint, type CheckData, type CheckOptions, type CompileOptions, type Condition, type DateConfig, type DateExpr, type DateInputOrExpr, type DateInputValue, type DateOffset, DateOperator, type DateRule, type DateRuleValue, type EdgeExpr, type EngineGlobalsState, type EnumNarrowing, FieldKind, type FieldMap, type FieldMapEntry, type FieldMapSet, type FuzzyConfig, type GroupByStep, type IfThenElse, type Lens, type LensNarrowing, type LensPathHop, type LensPathResolution, type ListBindingsOptions, type Magnitude, type MaterializeSourceQueryOptions, type ModelDefaultNarrowing, type ModelEntry, type ModelNarrowing, NUMERIC_KINDS, type NarrowingDefaults, type NumberOffset, Operator, type OperatorFamily, type OrderBy, type OrderedRuleValue, type PathProjection, type PeriodExpr, type PeriodUnit, type PrismaProvider, type PrismaStep, type PrismaWhere, type ProjectLensOptions, type ProjectedVisit, type RelativeUnits, type RollingExpr, type Row, type Rule, type RuleDescription, type RuleScalar, type RuleSourceDescription, RuleTarget, type RuleValue, type ScopeOutOfBounds, type ScopeRef, type ScopedRef, type SortDir, type SourceEntry, type SourceOption, type SourcePrismaQuery, type SourceQuery, type SourceRowShape, type SourceSelect, type SourceSpec, type SourceSqlQuery, type SourceValues, type StepRef, type StoredLens, type StrictAggregateRule, type StrictAll, type StrictAny, type StrictArrayCountRule, type StrictArrayPredicateRule, type StrictArrayPresenceRule, type StrictArrayRule, type StrictCondition, type StrictContainsRule, type StrictDateComparisonRule, type StrictDateDayRule, type StrictDateRangeRule, type StrictDateRule, type StrictEqualityRule, type StrictIfThenElse, type StrictMembershipRule, type StrictOrderedComparisonRule, type StrictPatternRule, type StrictPresenceRule, type StrictRangeRule, type StrictRule, type StrictStringBoundaryRule, type TimeZoneConfig, type ToPrismaOptions, type ToPrismaResult, type ToSqlOptions, type ToSqlResult, type ValidateRuleOptions, type ValidationIssue, type ValidationResult, ValueShape, type ValueSourceFields, type ValueSourceOf, type WeekStart, type WhereStep, type WindowFields, assertValidFieldMaps, assertValidNarrowing, assertValidRule, bindLens, bindRule, check, coerceRule, composeLens, createLens, describeRule, describeRuleSources, engineGlobals, executePrismaPlan, getAggregateOperators, getArrayOperators, getOperatorsForKind, getValueShape, indexBridges, listBindings, listLensBindings, materializeSourceQuery, materializeSources, narrowRule, parseScopeRef, projectLens, readScopeRef, stitchFieldMaps, storeLens, toPrisma, toSourceQueries, toSql, validateFieldMaps, validateNarrowing, validateRule, validateRuleInLens, walkLensPath };
|