@nxgt/graphql-validation 0.7.0 → 0.8.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 +8 -3
- package/dist/index.js +100 -69
- package/dist/index.js.map +12 -9
- package/dist/limits/cost-context.d.ts +7 -7
- package/dist/limits/cost-context.d.ts.map +1 -1
- package/dist/limits/describe.d.ts +4 -0
- package/dist/limits/describe.d.ts.map +1 -1
- package/dist/limits/fragments.d.ts +19 -0
- package/dist/limits/fragments.d.ts.map +1 -0
- package/dist/limits/list-size.d.ts +2 -0
- package/dist/limits/list-size.d.ts.map +1 -1
- package/dist/limits/max-depth.d.ts.map +1 -1
- package/dist/limits/max-fields.d.ts.map +1 -1
- package/dist/limits/max-list-cost-options.d.ts +38 -0
- package/dist/limits/max-list-cost-options.d.ts.map +1 -0
- package/dist/limits/max-list-cost.d.ts +11 -29
- package/dist/limits/max-list-cost.d.ts.map +1 -1
- package/dist/limits/size-reading.d.ts +22 -0
- package/dist/limits/size-reading.d.ts.map +1 -0
- package/docs/guide/query-limits.md +46 -13
- package/docs/roadmap.md +6 -0
- package/docs/troubleshooting.md +26 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -279,8 +279,13 @@ One `GraphQLError` per operation: `extensions: { code: 'QUERY_TOO_DEEP', depth,
|
|
|
279
279
|
limit }`, `{ code: 'QUERY_TOO_COSTLY', cost, limit }` or `{ code: 'QUERY_TOO_WIDE',
|
|
280
280
|
fields, limit }`. `maxFields` counts every field selection in the document, aliases and
|
|
281
281
|
`__typename` included, at each spread of a fragment. A list field is sized by
|
|
282
|
-
its `first`, `last` or `limit` argument
|
|
283
|
-
|
|
282
|
+
its `first`, `last` or `limit` argument. An argument not given says its SDL
|
|
283
|
+
default; with no argument and no default the size is `defaultFirst`. A variable
|
|
284
|
+
or an unusable literal (a negative number) counts as the largest of that
|
|
285
|
+
default (else `defaultFirst`), the argument's declared `@constraint(max)` or
|
|
286
|
+
`exclusiveMax`, and `variableSize` where some definition declares no bound; the
|
|
287
|
+
operation's own variable default is ignored. A code-first argument has no SDL
|
|
288
|
+
node, so only `variableSize` applies to it. A size is an
|
|
284
289
|
Int, a canonical-integer string or an integral Float; the largest of several
|
|
285
290
|
size arguments wins. On a Relay connection the `first` on the object field
|
|
286
291
|
sizes the `edges` and `nodes` lists directly under it (not lists further down,
|
|
@@ -349,7 +354,7 @@ the directive declared is this package's. Both at once throw
|
|
|
349
354
|
| `FieldIssue`, `FieldError`, `IssueParams`, `Translate`, `InvalidInputOptions`, `FieldsErrorOptions` | their types: an issue you write, a `fields` entry, its params, your translator, the options |
|
|
350
355
|
| `ValidationIssue`, `ConstraintValue`, `BadUserInputExtensions` | the types of `extensions.issues`, of an issue's `value`, and of `extensions` |
|
|
351
356
|
| `maxDepth({ depth, ignoreIntrospection? })` | a graphql-js validation rule refusing an operation nested deeper than `depth` fields, `extensions.code` `QUERY_TOO_DEEP`; introspection counts (the standard query is 15 levels) unless `ignoreIntrospection` |
|
|
352
|
-
| `maxListCost({ budget, defaultFirst, sizeArguments?, ignoreIntrospection? })` | a graphql-js validation rule refusing an operation whose list-weighted cost is over `budget`, `extensions.code` `QUERY_TOO_COSTLY`; `sizeArguments` names the arguments sizing a list (default `first`, `last`, `limit`, the largest wins); `ignoreIntrospection` skips `__schema` and `__type` |
|
|
357
|
+
| `maxListCost({ budget, defaultFirst, sizeArguments?, ignoreIntrospection?, variableSize? })` | a graphql-js validation rule refusing an operation whose list-weighted cost is over `budget`, `extensions.code` `QUERY_TOO_COSTLY`; `sizeArguments` names the arguments sizing a list (default `first`, `last`, `limit`, the largest wins); `ignoreIntrospection` skips `__schema` and `__type`; `variableSize` is the size assumed for any size argument (`first`, `last`, `limit`, custom `sizeArguments`) sent as a variable or an unusable literal; see [Variables](docs/guide/query-limits.md#variables) for how a declared bound and `variableSize` combine |
|
|
353
358
|
| `maxFields({ limit, ignoreIntrospection? })` | a graphql-js validation rule refusing an operation that selects more than `limit` fields (aliases, `__typename` and every fragment spread counted, `@skip`/`@include` not evaluated), `extensions.code` `QUERY_TOO_WIDE`; introspection counts (the standard query selects 220 fields) unless `ignoreIntrospection` |
|
|
354
359
|
| `MaxDepthOptions`, `MaxListCostOptions`, `MaxFieldsOptions` | their options |
|
|
355
360
|
| `ConstraintArgument` | the type of `issues[].constraint`: `'minLength' \| 'format' \| ...` |
|
package/dist/index.js
CHANGED
|
@@ -137,15 +137,42 @@ import {
|
|
|
137
137
|
} from "graphql";
|
|
138
138
|
|
|
139
139
|
// src/limits/describe.ts
|
|
140
|
+
var CEILING = Number.MAX_SAFE_INTEGER;
|
|
141
|
+
var add = (a, b) => Math.min(CEILING, a + b);
|
|
140
142
|
function operationLabel(operation) {
|
|
141
143
|
return operation.name ? `Operation "${operation.name.value}"` : "Operation";
|
|
142
144
|
}
|
|
143
|
-
function assertInteger(option, value, min, max =
|
|
145
|
+
function assertInteger(option, value, min, max = CEILING) {
|
|
144
146
|
if (!Number.isInteger(value) || value < min || value >= max) {
|
|
145
147
|
throw new RangeError(`${option} must be an integer from ${min} to ${max - 1}.`);
|
|
146
148
|
}
|
|
147
149
|
}
|
|
148
150
|
|
|
151
|
+
// src/limits/fragments.ts
|
|
152
|
+
var NO_KEY = -1;
|
|
153
|
+
function newFragmentWalk(getFragment) {
|
|
154
|
+
return { getFragment, values: new Map, visiting: new Set };
|
|
155
|
+
}
|
|
156
|
+
function fragmentValue(walk, name, key, compute) {
|
|
157
|
+
let known = walk.values.get(name);
|
|
158
|
+
if (!known) {
|
|
159
|
+
known = new Map;
|
|
160
|
+
walk.values.set(name, known);
|
|
161
|
+
}
|
|
162
|
+
const at = typeof key === "number" ? key : key(known);
|
|
163
|
+
const memo = known.get(at);
|
|
164
|
+
if (memo !== undefined)
|
|
165
|
+
return memo;
|
|
166
|
+
const fragment = walk.getFragment(name);
|
|
167
|
+
if (!fragment || walk.visiting.has(name))
|
|
168
|
+
return 0;
|
|
169
|
+
walk.visiting.add(name);
|
|
170
|
+
const result = compute(fragment, at);
|
|
171
|
+
walk.visiting.delete(name);
|
|
172
|
+
known.set(at, result);
|
|
173
|
+
return result;
|
|
174
|
+
}
|
|
175
|
+
|
|
149
176
|
// src/limits/introspection.ts
|
|
150
177
|
import {
|
|
151
178
|
isEnumType,
|
|
@@ -230,26 +257,14 @@ function depthOf(depth, selectionSet) {
|
|
|
230
257
|
return deepest;
|
|
231
258
|
}
|
|
232
259
|
function fragmentDepth(depth, name) {
|
|
233
|
-
|
|
234
|
-
if (known !== undefined)
|
|
235
|
-
return known;
|
|
236
|
-
const fragment = depth.getFragment(name);
|
|
237
|
-
if (!fragment || depth.measuring.has(name))
|
|
238
|
-
return 0;
|
|
239
|
-
depth.measuring.add(name);
|
|
240
|
-
const result = depthOf(depth, fragment.selectionSet);
|
|
241
|
-
depth.measuring.delete(name);
|
|
242
|
-
depth.fragmentDepths.set(name, result);
|
|
243
|
-
return result;
|
|
260
|
+
return fragmentValue(depth, name, NO_KEY, (fragment) => depthOf(depth, fragment.selectionSet));
|
|
244
261
|
}
|
|
245
262
|
function maxDepth(options) {
|
|
246
263
|
const limit = options.depth;
|
|
247
264
|
assertInteger("maxDepth: depth", limit, 1);
|
|
248
265
|
return (context) => {
|
|
249
266
|
const walk = {
|
|
250
|
-
|
|
251
|
-
fragmentDepths: new Map,
|
|
252
|
-
measuring: new Set,
|
|
267
|
+
...newFragmentWalk((name) => context.getFragment(name)),
|
|
253
268
|
ignoreIntrospection: options.ignoreIntrospection ?? false
|
|
254
269
|
};
|
|
255
270
|
return {
|
|
@@ -270,9 +285,6 @@ function maxDepth(options) {
|
|
|
270
285
|
import {
|
|
271
286
|
GraphQLError as GraphQLError4
|
|
272
287
|
} from "graphql";
|
|
273
|
-
function add(a, b) {
|
|
274
|
-
return Math.min(a + b, Number.MAX_SAFE_INTEGER);
|
|
275
|
-
}
|
|
276
288
|
function countOf(walk, selectionSet) {
|
|
277
289
|
let total = 0;
|
|
278
290
|
for (const selection of selectionSet.selections) {
|
|
@@ -291,26 +303,14 @@ function countOf(walk, selectionSet) {
|
|
|
291
303
|
return total;
|
|
292
304
|
}
|
|
293
305
|
function fragmentCount(walk, name) {
|
|
294
|
-
|
|
295
|
-
if (known !== undefined)
|
|
296
|
-
return known;
|
|
297
|
-
const fragment = walk.getFragment(name);
|
|
298
|
-
if (!fragment || walk.counting.has(name))
|
|
299
|
-
return 0;
|
|
300
|
-
walk.counting.add(name);
|
|
301
|
-
const result = countOf(walk, fragment.selectionSet);
|
|
302
|
-
walk.counting.delete(name);
|
|
303
|
-
walk.fragmentCounts.set(name, result);
|
|
304
|
-
return result;
|
|
306
|
+
return fragmentValue(walk, name, NO_KEY, (fragment) => countOf(walk, fragment.selectionSet));
|
|
305
307
|
}
|
|
306
308
|
function maxFields(options) {
|
|
307
309
|
const limit = options.limit;
|
|
308
310
|
assertInteger("maxFields: limit", limit, 1);
|
|
309
311
|
return (context) => {
|
|
310
312
|
const walk = {
|
|
311
|
-
|
|
312
|
-
fragmentCounts: new Map,
|
|
313
|
-
counting: new Set,
|
|
313
|
+
...newFragmentWalk((name) => context.getFragment(name)),
|
|
314
314
|
ignoreIntrospection: options.ignoreIntrospection ?? false
|
|
315
315
|
};
|
|
316
316
|
return {
|
|
@@ -340,8 +340,6 @@ import {
|
|
|
340
340
|
isInterfaceType as isInterfaceType2,
|
|
341
341
|
isObjectType as isObjectType2
|
|
342
342
|
} from "graphql";
|
|
343
|
-
var CEILING = Number.MAX_SAFE_INTEGER;
|
|
344
|
-
var add2 = (a, b) => Math.min(CEILING, a + b);
|
|
345
343
|
var multiply = (a, b) => Math.min(CEILING, a * b);
|
|
346
344
|
function fieldOf(cost, parent, name) {
|
|
347
345
|
if (parent === cost.schema.getQueryType() && isIntrospectionRoot(name)) {
|
|
@@ -354,7 +352,7 @@ function rootType(schema, operation) {
|
|
|
354
352
|
return type ?? undefined;
|
|
355
353
|
}
|
|
356
354
|
var EXACT_SIZES = 8;
|
|
357
|
-
var NO_PENDING =
|
|
355
|
+
var NO_PENDING = NO_KEY;
|
|
358
356
|
function memoSize(known, pending) {
|
|
359
357
|
if (pending === undefined || known.has(pending) || known.size < EXACT_SIZES) {
|
|
360
358
|
return pending;
|
|
@@ -369,16 +367,17 @@ function memoSize(known, pending) {
|
|
|
369
367
|
import {
|
|
370
368
|
isAbstractType
|
|
371
369
|
} from "graphql";
|
|
372
|
-
|
|
370
|
+
|
|
371
|
+
// src/limits/size-reading.ts
|
|
373
372
|
var CANONICAL_INTEGER = /^(0|[1-9]\d*)$/;
|
|
374
373
|
function sizeOf(value) {
|
|
375
374
|
if (typeof value === "string") {
|
|
376
|
-
return CANONICAL_INTEGER.test(value) ? Math.min(Number(value),
|
|
375
|
+
return CANONICAL_INTEGER.test(value) ? Math.min(Number(value), CEILING) : undefined;
|
|
377
376
|
}
|
|
378
377
|
if (typeof value === "bigint") {
|
|
379
|
-
return value >= 0n ? Math.min(Number(value),
|
|
378
|
+
return value >= 0n ? Math.min(Number(value), CEILING) : undefined;
|
|
380
379
|
}
|
|
381
|
-
return typeof value === "number" && Number.isInteger(value) && value >= 0 ? Math.min(value,
|
|
380
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 0 ? Math.min(value, CEILING) : undefined;
|
|
382
381
|
}
|
|
383
382
|
function literalSize(value) {
|
|
384
383
|
if (value.kind === "IntValue" || value.kind === "FloatValue") {
|
|
@@ -407,6 +406,30 @@ function defaultSizeOf(argument) {
|
|
|
407
406
|
}
|
|
408
407
|
return;
|
|
409
408
|
}
|
|
409
|
+
function boundOf(value) {
|
|
410
|
+
if (value.kind === "StringValue")
|
|
411
|
+
return literalSize(value);
|
|
412
|
+
if (value.kind !== "IntValue" && value.kind !== "FloatValue")
|
|
413
|
+
return;
|
|
414
|
+
const number = Number(value.value);
|
|
415
|
+
return Number.isFinite(number) && number >= 0 ? Math.min(Math.ceil(number), CEILING) : undefined;
|
|
416
|
+
}
|
|
417
|
+
function constraintMaxOf(argument) {
|
|
418
|
+
const directive = argument?.astNode?.directives?.find((node) => node.name.value === "constraint");
|
|
419
|
+
let largest;
|
|
420
|
+
for (const node of directive?.arguments ?? []) {
|
|
421
|
+
if (node.name.value !== "max" && node.name.value !== "exclusiveMax") {
|
|
422
|
+
continue;
|
|
423
|
+
}
|
|
424
|
+
const bound = boundOf(node.value);
|
|
425
|
+
if (bound !== undefined && (largest === undefined || bound > largest)) {
|
|
426
|
+
largest = bound;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
return largest;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// src/limits/list-size.ts
|
|
410
433
|
var profiles = new WeakMap;
|
|
411
434
|
function profileOf(cost, parent, definition) {
|
|
412
435
|
let bySizes = profiles.get(cost.schema);
|
|
@@ -435,6 +458,10 @@ function profileOf(cost, parent, definition) {
|
|
|
435
458
|
largest: cost.sizeArguments.map(() => {
|
|
436
459
|
return;
|
|
437
460
|
}),
|
|
461
|
+
maxima: cost.sizeArguments.map(() => {
|
|
462
|
+
return;
|
|
463
|
+
}),
|
|
464
|
+
someNoMax: cost.sizeArguments.map(() => false),
|
|
438
465
|
someLack: cost.sizeArguments.map(() => false),
|
|
439
466
|
someBare: false,
|
|
440
467
|
declares: false,
|
|
@@ -443,7 +470,13 @@ function profileOf(cost, parent, definition) {
|
|
|
443
470
|
for (const field of definitions) {
|
|
444
471
|
let any = false;
|
|
445
472
|
cost.sizeArguments.forEach((name, index) => {
|
|
446
|
-
const
|
|
473
|
+
const argument = field.args.find((arg) => arg.name === name);
|
|
474
|
+
const max = constraintMaxOf(argument);
|
|
475
|
+
if (max === undefined)
|
|
476
|
+
profile.someNoMax[index] = true;
|
|
477
|
+
else
|
|
478
|
+
profile.maxima[index] = Math.max(profile.maxima[index] ?? 0, max);
|
|
479
|
+
const size = defaultSizeOf(argument);
|
|
447
480
|
if (size === undefined) {
|
|
448
481
|
profile.someLack[index] = true;
|
|
449
482
|
return;
|
|
@@ -469,7 +502,16 @@ function argumentSize(cost, profile, index, node) {
|
|
|
469
502
|
const literal = literalSize(node.value);
|
|
470
503
|
if (literal !== undefined)
|
|
471
504
|
return literal;
|
|
472
|
-
|
|
505
|
+
const today = profile.someLack[index] ? Math.max(largest ?? 0, cost.defaultFirst) : largest;
|
|
506
|
+
const bound = unusableBound(cost, profile, index);
|
|
507
|
+
return bound === undefined ? today : Math.max(today ?? 0, bound);
|
|
508
|
+
}
|
|
509
|
+
function unusableBound(cost, profile, index) {
|
|
510
|
+
const assumed = profile.someNoMax[index] ? cost.variableSize : undefined;
|
|
511
|
+
const declared = profile.maxima[index];
|
|
512
|
+
if (assumed === undefined)
|
|
513
|
+
return declared;
|
|
514
|
+
return Math.max(declared ?? 0, assumed);
|
|
473
515
|
}
|
|
474
516
|
function statedSize(cost, parent, definition, args) {
|
|
475
517
|
const profile = profileOf(cost, parent, definition);
|
|
@@ -495,6 +537,9 @@ function declaration(cost, parent, definition) {
|
|
|
495
537
|
return someUndeclared ? "some" : "all";
|
|
496
538
|
}
|
|
497
539
|
|
|
540
|
+
// src/limits/max-list-cost-options.ts
|
|
541
|
+
var DEFAULT_SIZE_ARGUMENTS = ["first", "last", "limit"];
|
|
542
|
+
|
|
498
543
|
// src/limits/pending-size.ts
|
|
499
544
|
function listSizeUnder(cost, parent, definition, args, pending) {
|
|
500
545
|
const own = () => statedSize(cost, parent, definition, args) ?? cost.defaultFirst;
|
|
@@ -509,7 +554,6 @@ function listSizeUnder(cost, parent, definition, args, pending) {
|
|
|
509
554
|
}
|
|
510
555
|
|
|
511
556
|
// src/limits/max-list-cost.ts
|
|
512
|
-
var DEFAULT_SIZE_ARGUMENTS = ["first", "last", "limit"];
|
|
513
557
|
function fieldCost(cost, parent, selection, definition, pending) {
|
|
514
558
|
if (!selection.selectionSet)
|
|
515
559
|
return 1;
|
|
@@ -518,11 +562,11 @@ function fieldCost(cost, parent, selection, definition, pending) {
|
|
|
518
562
|
if (!isListType(getNullableType(definition.type))) {
|
|
519
563
|
const stated = statedSize(cost, parent, definition, selection.arguments);
|
|
520
564
|
const inner = costOf(cost, selection.selectionSet, type, stated);
|
|
521
|
-
return
|
|
565
|
+
return add(1, inner);
|
|
522
566
|
}
|
|
523
567
|
const inner = costOf(cost, selection.selectionSet, type, undefined);
|
|
524
568
|
const size = parent?.name.startsWith("__") ? introspectionSize(cost.schema, name) : listSizeUnder(cost, parent, definition, selection.arguments, pending);
|
|
525
|
-
return
|
|
569
|
+
return add(1, multiply(inner, size));
|
|
526
570
|
}
|
|
527
571
|
function costOf(cost, selectionSet, parent, pending) {
|
|
528
572
|
let total = 0;
|
|
@@ -536,35 +580,19 @@ function costOf(cost, selectionSet, parent, pending) {
|
|
|
536
580
|
const definition = fieldOf(cost, parent, name);
|
|
537
581
|
if (!definition)
|
|
538
582
|
continue;
|
|
539
|
-
total =
|
|
583
|
+
total = add(total, fieldCost(cost, parent, selection, definition, pending));
|
|
540
584
|
} else if (selection.kind === "InlineFragment") {
|
|
541
585
|
const condition = selection.typeCondition ? cost.schema.getType(selection.typeCondition.name.value) : parent;
|
|
542
|
-
total =
|
|
586
|
+
total = add(total, costOf(cost, selection.selectionSet, condition, pending));
|
|
543
587
|
} else {
|
|
544
|
-
total =
|
|
588
|
+
total = add(total, fragmentCost(cost, selection.name.value, pending));
|
|
545
589
|
}
|
|
546
590
|
}
|
|
547
591
|
return total;
|
|
548
592
|
}
|
|
549
593
|
function fragmentCost(cost, name, pending) {
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
known = new Map;
|
|
553
|
-
cost.fragmentCosts.set(name, known);
|
|
554
|
-
}
|
|
555
|
-
const size = memoSize(known, pending);
|
|
556
|
-
const key = size ?? NO_PENDING;
|
|
557
|
-
const memo = known.get(key);
|
|
558
|
-
if (memo !== undefined)
|
|
559
|
-
return memo;
|
|
560
|
-
const fragment = cost.getFragment(name);
|
|
561
|
-
if (!fragment || cost.costing.has(name))
|
|
562
|
-
return 0;
|
|
563
|
-
cost.costing.add(name);
|
|
564
|
-
const result = costOf(cost, fragment.selectionSet, cost.schema.getType(fragment.typeCondition.name.value), size);
|
|
565
|
-
cost.costing.delete(name);
|
|
566
|
-
known.set(key, result);
|
|
567
|
-
return result;
|
|
594
|
+
const key = (known) => memoSize(known, pending) ?? NO_PENDING;
|
|
595
|
+
return fragmentValue(cost, name, key, (fragment, at) => costOf(cost, fragment.selectionSet, cost.schema.getType(fragment.typeCondition.name.value), at === NO_PENDING ? undefined : at));
|
|
568
596
|
}
|
|
569
597
|
function maxListCost(options) {
|
|
570
598
|
const { budget, defaultFirst } = options;
|
|
@@ -573,16 +601,19 @@ function maxListCost(options) {
|
|
|
573
601
|
]);
|
|
574
602
|
assertInteger("maxListCost: budget", budget, 0);
|
|
575
603
|
assertInteger("maxListCost: defaultFirst", defaultFirst, 0);
|
|
604
|
+
const { variableSize } = options;
|
|
605
|
+
if (variableSize !== undefined) {
|
|
606
|
+
assertInteger("maxListCost: variableSize", variableSize, 0);
|
|
607
|
+
}
|
|
576
608
|
return (context) => {
|
|
577
609
|
const schema = context.getSchema();
|
|
578
610
|
const cost = {
|
|
579
611
|
schema,
|
|
580
612
|
sizeArguments,
|
|
581
613
|
defaultFirst,
|
|
614
|
+
variableSize,
|
|
582
615
|
ignoreIntrospection: options.ignoreIntrospection ?? false,
|
|
583
|
-
|
|
584
|
-
fragmentCosts: new Map,
|
|
585
|
-
costing: new Set
|
|
616
|
+
...newFragmentWalk((name) => context.getFragment(name))
|
|
586
617
|
};
|
|
587
618
|
return {
|
|
588
619
|
OperationDefinition(operation) {
|
|
@@ -683,5 +714,5 @@ export {
|
|
|
683
714
|
withValidation
|
|
684
715
|
};
|
|
685
716
|
|
|
686
|
-
//# debugId=
|
|
717
|
+
//# debugId=B1856E23719B140164756E2164756E21
|
|
687
718
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1,22 +1,25 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/bad-user-input.ts", "../src/invalid-input.ts", "../src/field-issue-of.ts", "../src/limits/max-depth.ts", "../src/limits/describe.ts", "../src/limits/introspection.ts", "../src/limits/max-fields.ts", "../src/limits/max-list-cost.ts", "../src/limits/cost-context.ts", "../src/limits/list-size.ts", "../src/limits/pending-size.ts", "../src/validated.ts", "../src/with-validation.ts"],
|
|
3
|
+
"sources": ["../src/bad-user-input.ts", "../src/invalid-input.ts", "../src/field-issue-of.ts", "../src/limits/max-depth.ts", "../src/limits/describe.ts", "../src/limits/fragments.ts", "../src/limits/introspection.ts", "../src/limits/max-fields.ts", "../src/limits/max-list-cost.ts", "../src/limits/cost-context.ts", "../src/limits/list-size.ts", "../src/limits/size-reading.ts", "../src/limits/max-list-cost-options.ts", "../src/limits/pending-size.ts", "../src/validated.ts", "../src/with-validation.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"import { GraphQLError } from 'graphql';\nimport type { z } from 'zod';\nimport type { ConstraintArgument } from './rules';\n\n/** One reason an input was refused, at its path inside the arguments. */\nexport interface ValidationIssue {\n\t/** `['input', 'address', 'zip']`: the argument, then the input fields. */\n\treadonly path: readonly (string | number)[];\n\treadonly message: string;\n\t/** Zod's issue code: `too_small`, `invalid_format`, `custom`, ... */\n\treadonly code: string;\n\t/**\n\t * The `@constraint` argument that refused (`minLength`, `format`), when a\n\t * directive did: stable across Zod versions, unlike `code`. Absent for a\n\t * refusal of `validated()`'s own schema.\n\t */\n\treadonly constraint?: ConstraintArgument;\n\t/**\n\t * What that `@constraint` argument was declared with, exactly as written\n\t * (`100` for `maxLength: 100`, `\"email\"` for `format: \"email\"`), so a\n\t * client can say \"at most 100 characters\" without parsing `message`.\n\t * Present exactly when `constraint` is.\n\t */\n\treadonly value?: ConstraintValue;\n}\n\n/** What a `@constraint` argument is declared with: a number or a string. */\nexport type ConstraintValue = string | number;\n\n/** The `extensions` of the error an invalid input becomes. */\nexport type BadUserInputExtensions = {\n\treadonly code: 'BAD_USER_INPUT';\n\treadonly issues: readonly ValidationIssue[];\n};\n\n/**\n * Names the `@constraint` argument behind an issue, and what it was declared\n * with, when there is one.\n */\nexport type ConstraintOf = (\n\tissue: z.core.$ZodIssue,\n) => { argument: ConstraintArgument; value: ConstraintValue } | undefined;\n\nfunction issuesOf(\n\terror: z.ZodError,\n\tconstraintOf?: ConstraintOf,\n): ValidationIssue[] {\n\treturn error.issues.map((issue) => {\n\t\tconst path = issue.path.map((key) =>\n\t\t\ttypeof key === 'number' ? key : String(key),\n\t\t);\n\t\tconst constraint = constraintOf?.(issue);\n\t\treturn constraint\n\t\t\t? {\n\t\t\t\t\tpath,\n\t\t\t\t\tmessage: issue.message,\n\t\t\t\t\tcode: issue.code,\n\t\t\t\t\tconstraint: constraint.argument,\n\t\t\t\t\tvalue: constraint.value,\n\t\t\t\t}\n\t\t\t: { path, message: issue.message, code: issue.code };\n\t});\n}\n\nfunction errorOf(where: string, issues: ValidationIssue[]): GraphQLError {\n\tconst [first] = issues;\n\tconst reason = first\n\t\t? `${first.path.join('.') || 'arguments'}: ${first.message}`\n\t\t: 'refused';\n\tconst extensions: BadUserInputExtensions = { code: 'BAD_USER_INPUT', issues };\n\treturn new GraphQLError(`Invalid arguments for ${where}. ${reason}`, {\n\t\textensions,\n\t});\n}\n\n/**\n * The one error an invalid input becomes: `extensions.code` is\n * `BAD_USER_INPUT`, the code Apollo and most clients already read, and\n * `extensions.issues` lists every reason with its path, so a form can show\n * each one beside its field. The message names the field and the first\n * reason, for a log line.\n */\nexport function badUserInput(where: string, error: z.ZodError): GraphQLError {\n\treturn errorOf(where, issuesOf(error));\n}\n\n/** The parsed arguments, or the error above, its issues named by `constraintOf`. */\nexport async function parseArgs(\n\tschema: z.ZodType,\n\targs: unknown,\n\twhere: string,\n\tconstraintOf?: ConstraintOf,\n): Promise<unknown> {\n\tconst result = await schema.safeParseAsync(args);\n\tif (!result.success)\n\t\tthrow errorOf(where, issuesOf(result.error, constraintOf));\n\treturn result.data;\n}\n",
|
|
6
6
|
"import { GraphQLError, type GraphQLErrorOptions } from 'graphql';\n\n/** The code of the error `invalidInputError` builds, and its default message. */\nexport const INVALID_INPUT = 'validation.errors.invalid-input';\n\n/** Values a message is built from, such as `{ min: 2 }`. */\nexport type IssueParams = Record<string, string | number>;\n\n/** One field at fault: where it is, why, and what the reason's message needs. */\nexport interface FieldIssue {\n\t/** The field inside the input, dotted: `person.firstName`, `tags.1`. */\n\treadonly path: string;\n\t/** A code your client and your translations know: `validation.errors.too-short`. */\n\treadonly code: string;\n\t/** Values the message needs; an object with no key counts as none. */\n\treadonly params?: IssueParams;\n}\n\n/** One entry of `extensions.fields`: a `FieldIssue` with its message. */\nexport interface FieldError {\n\treadonly path: string;\n\treadonly code: string;\n\t/** `translate(code, params)`, or the code itself without a translator. */\n\treadonly message: string;\n\t/** Present only when the issue had params with at least one key. */\n\treadonly params?: IssueParams;\n}\n\n/** Turns a code (and its params) into the text a person reads. */\nexport type Translate = (code: string, params?: IssueParams) => string;\n\n/** The options of `invalidInputError`: GraphQL's own, and a translator. */\nexport type InvalidInputOptions = GraphQLErrorOptions & {\n\treadonly translate?: Translate;\n};\n\n/** The options of `fieldsError`: also an HTTP status and the error's own params. */\nexport type FieldsErrorOptions = InvalidInputOptions & {\n\t/** `extensions.http.status`, for a server that reads it (409, ...). */\n\treadonly status?: number;\n\treadonly params?: IssueParams;\n};\n\n/** `params` itself, or `undefined` when it holds no key: never `{}`. */\nfunction paramsOf(params: IssueParams | undefined): IssueParams | undefined {\n\treturn params && Object.keys(params).length > 0 ? params : undefined;\n}\n\nfunction messageOf(\n\tcode: string,\n\tparams: IssueParams | undefined,\n\ttranslate: Translate | undefined,\n): string {\n\treturn translate?.(code, params) ?? code;\n}\n\nfunction fieldsOf(\n\tissues: readonly FieldIssue[],\n\ttranslate: Translate | undefined,\n): FieldError[] {\n\treturn issues.map(({ path, code, params: given }) => {\n\t\tconst params = paramsOf(given);\n\t\treturn {\n\t\t\tpath,\n\t\t\tcode,\n\t\t\tmessage: messageOf(code, params, translate),\n\t\t\t...(params && { params }),\n\t\t};\n\t});\n}\n\n/**\n * One 400 error listing every field at fault, for an API that answers invalid\n * input this way: `extensions` is `{ code: 'validation.errors.invalid-input',\n * http: { status: 400 }, fields }`, each field with its translated message\n * (the code itself without `translate`), in the order given. GraphQL's\n * options (`originalError`, `path`, `nodes`, ...) are kept; an `extensions`\n * among them is replaced by this one.\n */\nexport function invalidInputError(\n\tissues: readonly FieldIssue[],\n\toptions: InvalidInputOptions = {},\n): GraphQLError {\n\tconst { translate, ...graphql } = options;\n\treturn new GraphQLError(messageOf(INVALID_INPUT, undefined, translate), {\n\t\t...graphql,\n\t\textensions: {\n\t\t\tcode: INVALID_INPUT,\n\t\t\thttp: { status: 400 },\n\t\t\tfields: fieldsOf(issues, translate),\n\t\t},\n\t});\n}\n\n/**\n * A refusal of your own (a 409 conflict, say) that names the fields at\n * fault: `extensions` is `{ code, params?, http?: { status }, fields }`, the\n * fields worded as `invalidInputError` words them, the message\n * `translate(code, params)` or the code. An `extensions` among the options\n * is replaced by this one.\n */\nexport function fieldsError(\n\tcode: string,\n\tissues: readonly FieldIssue[],\n\toptions: FieldsErrorOptions = {},\n): GraphQLError {\n\tconst { translate, status, params: given, ...graphql } = options;\n\tconst params = paramsOf(given);\n\treturn new GraphQLError(messageOf(code, params, translate), {\n\t\t...graphql,\n\t\textensions: {\n\t\t\tcode,\n\t\t\t...(params && { params }),\n\t\t\t...(status && { http: { status } }),\n\t\t\tfields: fieldsOf(issues, translate),\n\t\t},\n\t});\n}\n\n/**\n * A GraphQL or Zod path as a `FieldIssue` path: dotted, without the leading\n * `input` argument when a field follows it, a symbol written as\n * `String(key)`. `['input', 'person', 'firstName']` is `person.firstName`,\n * `['input', 'tags', 1]` is `tags.1`, `['first']` and `['input']` stay as\n * they are.\n */\nexport function inputPath(path: readonly PropertyKey[]): string {\n\tconst [first, ...rest] = path;\n\treturn (first === 'input' && rest.length > 0 ? rest : path)\n\t\t.map((key) => String(key))\n\t\t.join('.');\n}\n",
|
|
7
7
|
"import type { z } from 'zod';\nimport { type FieldIssue, inputPath } from './invalid-input';\n\n/**\n * The codes `fieldIssueOf` gives, each under `validation.errors.`: a string's\n * length (`too-short`, `too-long`), a number's or bigint's bound or multiple\n * (`out-of-range`), a list's or set's size (`too-few`, `too-many`), a named\n * format or a pattern (`invalid-format`), anything else (`invalid`).\n */\nexport const FIELD_CODES = {\n\ttooShort: 'validation.errors.too-short',\n\ttooLong: 'validation.errors.too-long',\n\toutOfRange: 'validation.errors.out-of-range',\n\ttooFew: 'validation.errors.too-few',\n\ttooMany: 'validation.errors.too-many',\n\tinvalidFormat: 'validation.errors.invalid-format',\n\tinvalid: 'validation.errors.invalid',\n} as const;\n\n/** The string checks Zod reports as `invalid_format` that are not a format. */\nconst TEXT_CHECKS: ReadonlySet<string> = new Set([\n\t'starts_with',\n\t'ends_with',\n\t'includes',\n]);\n\n/**\n * A Zod issue as a `FieldIssue`, for `invalidInputError`: its path through\n * `inputPath` (dotted, a leading `input` dropped) and one of `FIELD_CODES`,\n * without params. `too-short` / `too-long` for a string's length,\n * `out-of-range` for a number's or bigint's bound or a multiple, `too-few` /\n * `too-many` for a list's or set's size, `invalid-format` for a named format\n * or a pattern, `invalid` for anything else (a prefix, a suffix or a\n * substring included).\n */\nexport function fieldIssueOf(issue: z.core.$ZodIssue): FieldIssue {\n\treturn { path: inputPath(issue.path), code: codeOf(issue) };\n}\n\nfunction codeOf(issue: z.core.$ZodIssue): string {\n\tswitch (issue.code) {\n\t\tcase 'too_small':\n\t\tcase 'too_big': {\n\t\t\tconst small = issue.code === 'too_small';\n\t\t\tswitch (issue.origin) {\n\t\t\t\tcase 'string':\n\t\t\t\t\treturn small ? FIELD_CODES.tooShort : FIELD_CODES.tooLong;\n\t\t\t\tcase 'number':\n\t\t\t\tcase 'bigint':\n\t\t\t\t\treturn FIELD_CODES.outOfRange;\n\t\t\t\tcase 'array':\n\t\t\t\tcase 'set':\n\t\t\t\t\treturn small ? FIELD_CODES.tooFew : FIELD_CODES.tooMany;\n\t\t\t\tdefault:\n\t\t\t\t\treturn FIELD_CODES.invalid;\n\t\t\t}\n\t\t}\n\t\tcase 'not_multiple_of':\n\t\t\treturn FIELD_CODES.outOfRange;\n\t\tcase 'invalid_format':\n\t\t\t// A prefix, a suffix or a substring is not a format: only a named\n\t\t\t// format (`email`, `uuid`, …) or a pattern is.\n\t\t\treturn TEXT_CHECKS.has(issue.format)\n\t\t\t\t? FIELD_CODES.invalid\n\t\t\t\t: FIELD_CODES.invalidFormat;\n\t\tdefault:\n\t\t\treturn FIELD_CODES.invalid;\n\t}\n}\n",
|
|
8
|
-
"import {\n\
|
|
9
|
-
"import type { OperationDefinitionNode } from 'graphql';\n\n/** `Operation \"Name\"`, or `Operation` for an anonymous one. */\nexport function operationLabel(operation: OperationDefinitionNode): string {\n\treturn operation.name ? `Operation \"${operation.name.value}\"` : 'Operation';\n}\n\n/**\n * Throws a `RangeError` unless `value` is an integer from `min` up to, and\n * excluding, `max` (default: `Number.MAX_SAFE_INTEGER`, where a cost is clamped).\n */\nexport function assertInteger(\n\toption: string,\n\tvalue: number,\n\tmin: number,\n\tmax =
|
|
8
|
+
"import {\n\tGraphQLError,\n\ttype SelectionSetNode,\n\ttype ValidationContext,\n\ttype ValidationRule,\n} from 'graphql';\nimport { assertInteger, operationLabel } from './describe';\nimport {\n\ttype FragmentWalk,\n\tfragmentValue,\n\tNO_KEY,\n\tnewFragmentWalk,\n} from './fragments';\nimport { isIntrospectionRoot } from './introspection';\n\n/** Options of {@link maxDepth}. */\nexport interface MaxDepthOptions {\n\t/** The deepest nesting of field selections an operation may have (at least 1). */\n\tdepth: number;\n\t/**\n\t * Do not count `__schema` and `__type` (default `false`). Only where\n\t * introspection is disabled or the client is trusted, e.g. GraphiQL in\n\t * development: the standard introspection query (`getIntrospectionQuery()`) is 15 levels deep.\n\t */\n\tignoreIntrospection?: boolean;\n}\n\n/** What a walk of one document needs: the options, and what it has measured so far. */\ninterface DepthContext extends FragmentWalk {\n\tignoreIntrospection: boolean;\n}\n\n/** The depth of `selectionSet`: 0 when it selects no field. */\nfunction depthOf(depth: DepthContext, selectionSet: SelectionSetNode): number {\n\tlet deepest = 0;\n\tfor (const selection of selectionSet.selections) {\n\t\tlet here = 0;\n\t\tif (selection.kind === 'Field') {\n\t\t\tconst name = selection.name.value;\n\t\t\tif (name === '__typename') continue;\n\t\t\tif (depth.ignoreIntrospection && isIntrospectionRoot(name)) continue;\n\t\t\there =\n\t\t\t\t1 +\n\t\t\t\t(selection.selectionSet ? depthOf(depth, selection.selectionSet) : 0);\n\t\t} else if (selection.kind === 'InlineFragment') {\n\t\t\there = depthOf(depth, selection.selectionSet);\n\t\t} else {\n\t\t\there = fragmentDepth(depth, selection.name.value);\n\t\t}\n\t\tif (here > deepest) deepest = here;\n\t}\n\treturn deepest;\n}\n\n/** The depth of the named fragment, measured once. */\nfunction fragmentDepth(depth: DepthContext, name: string): number {\n\treturn fragmentValue(depth, name, NO_KEY, (fragment) =>\n\t\tdepthOf(depth, fragment.selectionSet),\n\t);\n}\n\n/**\n * A graphql-js validation rule refusing an operation nested deeper than\n * `depth` fields: a top-level field is depth 1.\n *\n * Named fragments are followed (each measured once), inline fragments add no\n * depth, and `__typename` does not count. One `GraphQLError` per\n * operation, with `extensions: { code: 'QUERY_TOO_DEEP', depth, limit }`,\n * `depth` being the operation's real depth.\n *\n * ```ts\n * validate(schema, document, [...specifiedRules, maxDepth({ depth: 8 })]);\n * // graphql-yoga: onValidate: ({ addValidationRule }) => addValidationRule(maxDepth({ depth: 8 }))\n * ```\n */\nexport function maxDepth(options: MaxDepthOptions): ValidationRule {\n\tconst limit = options.depth;\n\tassertInteger('maxDepth: depth', limit, 1);\n\treturn (context: ValidationContext) => {\n\t\tconst walk: DepthContext = {\n\t\t\t...newFragmentWalk((name) => context.getFragment(name)),\n\t\t\tignoreIntrospection: options.ignoreIntrospection ?? false,\n\t\t};\n\t\treturn {\n\t\t\tOperationDefinition(operation) {\n\t\t\t\tconst depth = depthOf(walk, operation.selectionSet);\n\t\t\t\tif (depth > limit) {\n\t\t\t\t\tcontext.reportError(\n\t\t\t\t\t\tnew GraphQLError(\n\t\t\t\t\t\t\t`${operationLabel(operation)} is ${depth} levels deep, more than the ${limit} allowed`,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tnodes: [operation],\n\t\t\t\t\t\t\t\textensions: { code: 'QUERY_TOO_DEEP', depth, limit },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t},\n\t\t};\n\t};\n}\n",
|
|
9
|
+
"import type { OperationDefinitionNode } from 'graphql';\n\n/** Costs and counts are plain numbers, held below this so a hostile query never reaches `Infinity`. */\nexport const CEILING = Number.MAX_SAFE_INTEGER;\n\n/** `a + b`, clamped where a number stops being exact. */\nexport const add = (a: number, b: number) => Math.min(CEILING, a + b);\n\n/** `Operation \"Name\"`, or `Operation` for an anonymous one. */\nexport function operationLabel(operation: OperationDefinitionNode): string {\n\treturn operation.name ? `Operation \"${operation.name.value}\"` : 'Operation';\n}\n\n/**\n * Throws a `RangeError` unless `value` is an integer from `min` up to, and\n * excluding, `max` (default: `Number.MAX_SAFE_INTEGER`, where a cost is clamped).\n */\nexport function assertInteger(\n\toption: string,\n\tvalue: number,\n\tmin: number,\n\tmax = CEILING,\n): void {\n\tif (!Number.isInteger(value) || value < min || value >= max) {\n\t\tthrow new RangeError(\n\t\t\t`${option} must be an integer from ${min} to ${max - 1}.`,\n\t\t);\n\t}\n}\n",
|
|
10
|
+
"import type { FragmentDefinitionNode } from 'graphql';\n\n/** The key of a fragment whose value does not depend on anything but its name. */\nexport const NO_KEY = -1;\n\n/** What the fragment walk of one document keeps: the fragments, and what each was worth. */\nexport interface FragmentWalk {\n\tgetFragment: (name: string) => FragmentDefinitionNode | null | undefined;\n\tvalues: Map<string, Map<number, number>>;\n\tvisiting: Set<string>;\n}\n\n/** An empty walk over the fragments of one document. */\nexport function newFragmentWalk(\n\tgetFragment: FragmentWalk['getFragment'],\n): FragmentWalk {\n\treturn { getFragment, values: new Map(), visiting: new Set() };\n}\n\n/**\n * The value of the named fragment under `key`, computed once. `key` is a number,\n * or a function of what is already known for this fragment (`maxListCost` rounds\n * its pending size by it). A fragment reached while it is being computed is a\n * cycle, NoFragmentCyclesRule's to report: its back-edge adds nothing (0).\n */\nexport function fragmentValue(\n\twalk: FragmentWalk,\n\tname: string,\n\tkey: number | ((known: ReadonlyMap<number, number>) => number),\n\tcompute: (fragment: FragmentDefinitionNode, key: number) => number,\n): number {\n\tlet known = walk.values.get(name);\n\tif (!known) {\n\t\tknown = new Map();\n\t\twalk.values.set(name, known);\n\t}\n\tconst at = typeof key === 'number' ? key : key(known);\n\tconst memo = known.get(at);\n\tif (memo !== undefined) return memo;\n\tconst fragment = walk.getFragment(name);\n\tif (!fragment || walk.visiting.has(name)) return 0;\n\twalk.visiting.add(name);\n\tconst result = compute(fragment, at);\n\twalk.visiting.delete(name);\n\tknown.set(at, result);\n\treturn result;\n}\n",
|
|
10
11
|
"import {\n\ttype GraphQLField,\n\ttype GraphQLNamedType,\n\ttype GraphQLSchema,\n\tisEnumType,\n\tisInputObjectType,\n\tisInterfaceType,\n\tisObjectType,\n\tisUnionType,\n\tSchemaMetaFieldDef,\n\tTypeMetaFieldDef,\n} from 'graphql';\n\n/** The meta-fields that read the schema; `__typename` is not one. */\nexport function isIntrospectionRoot(name: string): boolean {\n\treturn name === '__schema' || name === '__type';\n}\n\n/** The definition of `__schema` or `__type`, selected on the query root. */\nexport function introspectionRoot(\n\tname: string,\n): GraphQLField<unknown, unknown> | undefined {\n\tif (name === '__schema') return SchemaMetaFieldDef;\n\tif (name === '__type') return TypeMetaFieldDef;\n\treturn undefined;\n}\n\n/** The largest list the introspection types can return for `schema`, by schema. */\nconst largest = new WeakMap<GraphQLSchema, number>();\n\nconst typeCounts = new WeakMap<GraphQLSchema, number>();\n\nfunction typeCount(schema: GraphQLSchema): number {\n\tlet count = typeCounts.get(schema);\n\tif (count === undefined) {\n\t\tcount = Object.keys(schema.getTypeMap()).length;\n\t\ttypeCounts.set(schema, count);\n\t}\n\treturn count;\n}\n\nfunction largestCount(schema: GraphQLSchema): number {\n\tconst known = largest.get(schema);\n\tif (known !== undefined) return known;\n\tlet max = schema.getDirectives().length;\n\tfor (const directive of schema.getDirectives()) {\n\t\tmax = Math.max(max, directive.args.length, directive.locations.length);\n\t}\n\tfor (const type of Object.values(schema.getTypeMap())) {\n\t\tmax = Math.max(max, countsOf(schema, type));\n\t}\n\tlargest.set(schema, max);\n\treturn max;\n}\n\n/** The longest of a type's fields, input fields, enum values, interfaces, possible types and arguments. */\nfunction countsOf(schema: GraphQLSchema, type: GraphQLNamedType): number {\n\tif (isObjectType(type) || isInterfaceType(type)) {\n\t\tconst fields = Object.values(type.getFields());\n\t\treturn Math.max(\n\t\t\tfields.length,\n\t\t\ttype.getInterfaces().length,\n\t\t\tisInterfaceType(type) ? schema.getPossibleTypes(type).length : 0,\n\t\t\t...fields.map((field) => field.args.length),\n\t\t);\n\t}\n\tif (isInputObjectType(type)) return Object.keys(type.getFields()).length;\n\tif (isEnumType(type)) return type.getValues().length;\n\tif (isUnionType(type)) return type.getTypes().length;\n\treturn 0;\n}\n\n/**\n * The most items the introspection list `parent.field` can hold in `schema`:\n * the number of types for `__Schema.types`, else the largest list anywhere in\n * the schema. Not `defaultFirst`: a query asks no size of them.\n */\nexport function introspectionSize(\n\tschema: GraphQLSchema,\n\tfield: string,\n): number {\n\treturn field === 'types' ? typeCount(schema) : largestCount(schema);\n}\n",
|
|
11
|
-
"import {\n\
|
|
12
|
-
"import {\n\ttype FieldNode,\n\tGraphQLError,\n\ttype GraphQLField,\n\ttype GraphQLNamedType,\n\tgetNamedType,\n\tgetNullableType,\n\tisListType,\n\ttype SelectionSetNode,\n\ttype ValidationContext,\n\ttype ValidationRule,\n} from 'graphql';\nimport {\n\
|
|
13
|
-
"import {\n\ttype
|
|
14
|
-
"import {\n\ttype ArgumentNode,\n\ttype GraphQLField,\n\ttype GraphQLNamedType,\n\ttype GraphQLSchema,\n\tisAbstractType,\n
|
|
12
|
+
"import {\n\tGraphQLError,\n\ttype SelectionSetNode,\n\ttype ValidationContext,\n\ttype ValidationRule,\n} from 'graphql';\nimport { add, assertInteger, operationLabel } from './describe';\nimport {\n\ttype FragmentWalk,\n\tfragmentValue,\n\tNO_KEY,\n\tnewFragmentWalk,\n} from './fragments';\nimport { isIntrospectionRoot } from './introspection';\n\n/** Options of {@link maxFields}. */\nexport interface MaxFieldsOptions {\n\t/** The most field selections an operation may have (at least 1). */\n\tlimit: number;\n\t/**\n\t * Do not count `__schema` and `__type` (default `false`). Only where\n\t * introspection is disabled or the client is trusted, e.g. GraphiQL in\n\t * development: the standard introspection query (`getIntrospectionQuery()`)\n\t * selects 220 fields.\n\t */\n\tignoreIntrospection?: boolean;\n}\n\n/** What a walk of one document needs: the options, and what it has counted so far. */\ninterface FieldsContext extends FragmentWalk {\n\tignoreIntrospection: boolean;\n}\n\n/** The field selections of `selectionSet`, nested ones included. */\nfunction countOf(walk: FieldsContext, selectionSet: SelectionSetNode): number {\n\tlet total = 0;\n\tfor (const selection of selectionSet.selections) {\n\t\tif (selection.kind === 'Field') {\n\t\t\tif (walk.ignoreIntrospection && isIntrospectionRoot(selection.name.value))\n\t\t\t\tcontinue;\n\t\t\ttotal = add(total, 1);\n\t\t\tif (selection.selectionSet)\n\t\t\t\ttotal = add(total, countOf(walk, selection.selectionSet));\n\t\t} else if (selection.kind === 'InlineFragment') {\n\t\t\ttotal = add(total, countOf(walk, selection.selectionSet));\n\t\t} else {\n\t\t\ttotal = add(total, fragmentCount(walk, selection.name.value));\n\t\t}\n\t}\n\treturn total;\n}\n\n/** The count of the named fragment, walked once. */\nfunction fragmentCount(walk: FieldsContext, name: string): number {\n\treturn fragmentValue(walk, name, NO_KEY, (fragment) =>\n\t\tcountOf(walk, fragment.selectionSet),\n\t);\n}\n\n/**\n * A graphql-js validation rule refusing an operation that selects more than\n * `limit` fields: neither `maxDepth` nor `maxListCost` bounds breadth, so\n * thousands of aliases of a cheap field (or of `__typename`) pass both.\n *\n * Every field node counts 1, aliases and `__typename` included. A named\n * fragment counts at each spread (walked once), an inline fragment counts its\n * contents, and every branch of a union counts: nothing is pruned by type.\n * `@skip` and `@include` are not evaluated, so the count can be over the\n * document's field count. It counts the document, spreads expanded, not what the\n * executor runs: how often a field runs inside a list is `maxListCost`'s.\n * One `GraphQLError` per operation, with\n * `extensions: { code: 'QUERY_TOO_WIDE', fields, limit }`, `fields` being the\n * operation's real count (clamped at `Number.MAX_SAFE_INTEGER`).\n *\n * ```ts\n * validate(schema, document, [...specifiedRules, maxFields({ limit: 500 })]);\n * // graphql-yoga: onValidate: ({ addValidationRule }) => addValidationRule(maxFields({ limit: 500 }))\n * ```\n */\nexport function maxFields(options: MaxFieldsOptions): ValidationRule {\n\tconst limit = options.limit;\n\tassertInteger('maxFields: limit', limit, 1);\n\treturn (context: ValidationContext) => {\n\t\tconst walk: FieldsContext = {\n\t\t\t...newFragmentWalk((name) => context.getFragment(name)),\n\t\t\tignoreIntrospection: options.ignoreIntrospection ?? false,\n\t\t};\n\t\treturn {\n\t\t\tOperationDefinition(operation) {\n\t\t\t\tconst fields = countOf(walk, operation.selectionSet);\n\t\t\t\tif (fields > limit) {\n\t\t\t\t\tcontext.reportError(\n\t\t\t\t\t\tnew GraphQLError(\n\t\t\t\t\t\t\t`${operationLabel(operation)} selects ${fields} fields, more than the ${limit} allowed`,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tnodes: [operation],\n\t\t\t\t\t\t\t\textensions: { code: 'QUERY_TOO_WIDE', fields, limit },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t},\n\t\t};\n\t};\n}\n",
|
|
13
|
+
"import {\n\ttype FieldNode,\n\tGraphQLError,\n\ttype GraphQLField,\n\ttype GraphQLNamedType,\n\tgetNamedType,\n\tgetNullableType,\n\tisListType,\n\ttype SelectionSetNode,\n\ttype ValidationContext,\n\ttype ValidationRule,\n} from 'graphql';\nimport {\n\ttype CostContext,\n\tfieldOf,\n\tmemoSize,\n\tmultiply,\n\tNO_PENDING,\n\trootType,\n} from './cost-context';\nimport { add, assertInteger, operationLabel } from './describe';\nimport { fragmentValue, newFragmentWalk } from './fragments';\nimport { introspectionSize, isIntrospectionRoot } from './introspection';\nimport { statedSize } from './list-size';\nimport {\n\tDEFAULT_SIZE_ARGUMENTS,\n\ttype MaxListCostOptions,\n} from './max-list-cost-options';\nimport { listSizeUnder } from './pending-size';\n\nexport type { MaxListCostOptions };\n\n/**\n * The cost of one selected field. `pending` is the size of the field whose\n * return type this selection is on: only a list declaring no size argument\n * takes it, and no field passes it on.\n */\nfunction fieldCost(\n\tcost: CostContext,\n\tparent: GraphQLNamedType | undefined,\n\tselection: FieldNode,\n\tdefinition: GraphQLField<unknown, unknown>,\n\tpending: number | undefined,\n): number {\n\tif (!selection.selectionSet) return 1;\n\tconst name = selection.name.value;\n\tconst type = getNamedType(definition.type);\n\tif (!isListType(getNullableType(definition.type))) {\n\t\t// An object field hands its own size, if it states one, to the lists\n\t\t// selected directly on it; the pending size stops here.\n\t\tconst stated = statedSize(cost, parent, definition, selection.arguments);\n\t\tconst inner = costOf(cost, selection.selectionSet, type, stated);\n\t\treturn add(1, inner);\n\t}\n\tconst inner = costOf(cost, selection.selectionSet, type, undefined);\n\tconst size = parent?.name.startsWith('__')\n\t\t? introspectionSize(cost.schema, name)\n\t\t: listSizeUnder(cost, parent, definition, selection.arguments, pending);\n\treturn add(1, multiply(inner, size));\n}\n\n/** The cost of `selectionSet` selected on `parent`, under the `pending` size of the field they are selected on. */\nfunction costOf(\n\tcost: CostContext,\n\tselectionSet: SelectionSetNode,\n\tparent: GraphQLNamedType | undefined,\n\tpending: number | undefined,\n): number {\n\tlet total = 0;\n\tfor (const selection of selectionSet.selections) {\n\t\tif (selection.kind === 'Field') {\n\t\t\tconst name = selection.name.value;\n\t\t\tif (name === '__typename') continue;\n\t\t\tif (isIntrospectionRoot(name) && cost.ignoreIntrospection) continue;\n\t\t\tconst definition = fieldOf(cost, parent, name);\n\t\t\t// An unknown field is another rule's to report.\n\t\t\tif (!definition) continue;\n\t\t\ttotal = add(\n\t\t\t\ttotal,\n\t\t\t\tfieldCost(cost, parent, selection, definition, pending),\n\t\t\t);\n\t\t} else if (selection.kind === 'InlineFragment') {\n\t\t\tconst condition = selection.typeCondition\n\t\t\t\t? cost.schema.getType(selection.typeCondition.name.value)\n\t\t\t\t: parent;\n\t\t\ttotal = add(\n\t\t\t\ttotal,\n\t\t\t\tcostOf(cost, selection.selectionSet, condition, pending),\n\t\t\t);\n\t\t} else {\n\t\t\ttotal = add(total, fragmentCost(cost, selection.name.value, pending));\n\t\t}\n\t}\n\treturn total;\n}\n\n/** The cost of the named fragment spread under `pending`, computed once per size. */\nfunction fragmentCost(\n\tcost: CostContext,\n\tname: string,\n\tpending: number | undefined,\n): number {\n\tconst key = (known: ReadonlyMap<number, number>) =>\n\t\tmemoSize(known, pending) ?? NO_PENDING;\n\treturn fragmentValue(cost, name, key, (fragment, at) =>\n\t\tcostOf(\n\t\t\tcost,\n\t\t\tfragment.selectionSet,\n\t\t\tcost.schema.getType(fragment.typeCondition.name.value),\n\t\t\tat === NO_PENDING ? undefined : at,\n\t\t),\n\t);\n}\n\n/**\n * A graphql-js validation rule refusing an operation whose cost is more than\n * `budget`, to stop a client from exploiting list cycles (`Folder.items`,\n * `Item.folder`, `Folder.items`, …) for a cost growing exponentially.\n *\n * The cost of an operation is the sum, over every selected field, of the\n * product of the sizes of the list fields enclosing it: a field costs 1, and a\n * list field multiplies the cost of its sub-selection by its size.\n * `__typename` costs nothing. `__schema` and `__type` are costed like any\n * field, their lists sized by the schema itself (`__Schema.types` is the number\n * of types, the other lists the longest list anywhere in the schema), unless\n * `ignoreIntrospection` is set.\n *\n * The size of a list field is the largest size its `sizeArguments` (default\n * `first`, `last`, `limit`) say. A literal Int, a String holding a canonical\n * integer (`\"1000\"`) or an integral Float (`1e3`) of at least 0 says that\n * number. Anything else (a negative literal, a variable, since validation has\n * no variable values) says the largest of the argument's SDL default when it\n * has a usable one (`defaultFirst` otherwise), its declared bound\n * (`@constraint(max)` or `exclusiveMax`) and, when some definition declares no\n * bound, `variableSize`; an argument not given says its SDL default, or\n * nothing. When nothing is said the size is `defaultFirst`. On an interface\n * the largest default and bound over its possible types is used. Hence no\n * subtree ever costs less than nothing: a negative `first` on one field cannot\n * cancel the cost of its sibling. A field whose type (once unwrapped from\n * non-null) is a list is one list, nested `[[X]]` included.\n *\n * A Relay connection puts the size on a field returning an object, with the\n * list below it (`items(first: 100) { edges { node { id } } }`). A field that\n * is not a list and states a size (by the same reading) hands it to the lists\n * selected directly on its return type, through inline fragments and fragment\n * spreads on that same selection set, and only to those declaring none of the\n * size arguments (`edges`, `nodes`): such a list takes it instead of\n * `defaultFirst`. A list declaring a size argument (`recent(first: Int)`)\n * reads its own, never the pending size. Crossing any other field (an object\n * field, `pageInfo`, a wrapper) ends it. A connection stating nothing hands\n * down nothing: its lists are sized `defaultFirst`.\n *\n * Named fragments are followed, each costed once per pending size (past eight\n * distinct sizes under one fragment a size is rounded up to a power of two, so\n * the work stays linear in the document and a cost only over-counts). Inline fragments and\n * fragments on an abstract type are summed branch by branch, so the cost of a\n * query on an interface or a union is overestimated, never underestimated.\n *\n * One `GraphQLError` per operation, with\n * `extensions: { code: 'QUERY_TOO_COSTLY', cost, limit }`. `cost` is exact up\n * to `Number.MAX_SAFE_INTEGER`, which it never exceeds.\n *\n * ```ts\n * const rule = maxListCost({ budget: 10_000, defaultFirst: 50 });\n * validate(schema, document, [...specifiedRules, rule]);\n * // graphql-yoga: onValidate: ({ addValidationRule }) => addValidationRule(rule)\n * ```\n */\nexport function maxListCost(options: MaxListCostOptions): ValidationRule {\n\tconst { budget, defaultFirst } = options;\n\t// A copy: a caller changing its array later must not desync the schema\n\t// cache keyed by it.\n\tconst sizeArguments = Object.freeze([\n\t\t...(options.sizeArguments ?? DEFAULT_SIZE_ARGUMENTS),\n\t]);\n\tassertInteger('maxListCost: budget', budget, 0);\n\tassertInteger('maxListCost: defaultFirst', defaultFirst, 0);\n\tconst { variableSize } = options;\n\tif (variableSize !== undefined) {\n\t\tassertInteger('maxListCost: variableSize', variableSize, 0);\n\t}\n\n\treturn (context: ValidationContext) => {\n\t\tconst schema = context.getSchema();\n\t\tconst cost: CostContext = {\n\t\t\tschema,\n\t\t\tsizeArguments,\n\t\t\tdefaultFirst,\n\t\t\tvariableSize,\n\t\t\tignoreIntrospection: options.ignoreIntrospection ?? false,\n\t\t\t...newFragmentWalk((name) => context.getFragment(name)),\n\t\t};\n\t\treturn {\n\t\t\tOperationDefinition(operation) {\n\t\t\t\tconst total = costOf(\n\t\t\t\t\tcost,\n\t\t\t\t\toperation.selectionSet,\n\t\t\t\t\trootType(schema, operation),\n\t\t\t\t\tundefined,\n\t\t\t\t);\n\t\t\t\tif (total > budget) {\n\t\t\t\t\tcontext.reportError(\n\t\t\t\t\t\tnew GraphQLError(\n\t\t\t\t\t\t\t`${operationLabel(operation)} costs ${total}, more than the ${budget} allowed`,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tnodes: [operation],\n\t\t\t\t\t\t\t\textensions: {\n\t\t\t\t\t\t\t\t\tcode: 'QUERY_TOO_COSTLY',\n\t\t\t\t\t\t\t\t\tcost: total,\n\t\t\t\t\t\t\t\t\tlimit: budget,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t},\n\t\t};\n\t};\n}\n",
|
|
14
|
+
"import {\n\ttype GraphQLField,\n\ttype GraphQLNamedType,\n\ttype GraphQLSchema,\n\tisInterfaceType,\n\tisObjectType,\n\ttype OperationDefinitionNode,\n} from 'graphql';\nimport { CEILING } from './describe';\nimport { type FragmentWalk, NO_KEY } from './fragments';\nimport { introspectionRoot, isIntrospectionRoot } from './introspection';\nimport type { SizeContext } from './list-size';\n\nexport const multiply = (a: number, b: number) => Math.min(CEILING, a * b);\n\n/** What a walk of one document needs: the options, and what it has measured so far. */\nexport interface CostContext extends SizeContext, FragmentWalk {\n\tignoreIntrospection: boolean;\n}\n\n/** The definition of the field `name` on `parent`, meta-fields of the query root included. */\nexport function fieldOf(\n\tcost: CostContext,\n\tparent: GraphQLNamedType | undefined,\n\tname: string,\n): GraphQLField<unknown, unknown> | undefined {\n\tif (parent === cost.schema.getQueryType() && isIntrospectionRoot(name)) {\n\t\treturn introspectionRoot(name);\n\t}\n\treturn isObjectType(parent) || isInterfaceType(parent)\n\t\t? parent.getFields()[name]\n\t\t: undefined;\n}\n\n/** The type an operation selects on. */\nexport function rootType(\n\tschema: GraphQLSchema,\n\toperation: OperationDefinitionNode,\n) {\n\tconst type =\n\t\toperation.operation === 'query'\n\t\t\t? schema.getQueryType()\n\t\t\t: operation.operation === 'mutation'\n\t\t\t\t? schema.getMutationType()\n\t\t\t\t: schema.getSubscriptionType();\n\treturn type ?? undefined;\n}\n\n/** Distinct pending sizes costed exactly per fragment; further ones are rounded up. */\nconst EXACT_SIZES = 8;\n\n/**\n * The key a fragment is memoized under when no size is pending: the walk's own\n * \"no key\", which no real size can equal (a size is never negative).\n */\nexport const NO_PENDING = NO_KEY;\n\n/**\n * The pending size a fragment is costed under. A fragment spread under many\n * distinct sizes would be costed once per size, quadratic in a hostile\n * document; past `EXACT_SIZES` of them a new size is rounded up to a power of\n * two (a cost never lowers as a size grows, so it only over-counts, by less\n * than twice), which leaves at most `EXACT_SIZES` + 53 costings per fragment.\n */\nexport function memoSize(\n\tknown: ReadonlyMap<number, number>,\n\tpending: number | undefined,\n): number | undefined {\n\tif (pending === undefined || known.has(pending) || known.size < EXACT_SIZES) {\n\t\treturn pending;\n\t}\n\t// Math.log2 rounds near 2^k + d, so the power is checked, not trusted.\n\tlet rounded = 2 ** Math.ceil(Math.log2(Math.max(pending, 1)));\n\tif (rounded < pending) rounded *= 2;\n\treturn Math.min(CEILING, rounded);\n}\n",
|
|
15
|
+
"import {\n\ttype ArgumentNode,\n\ttype GraphQLField,\n\ttype GraphQLNamedType,\n\ttype GraphQLSchema,\n\tisAbstractType,\n} from 'graphql';\nimport { constraintMaxOf, defaultSizeOf, literalSize } from './size-reading';\n\n/** What sizing a list needs: the schema and the options of the rule. */\nexport interface SizeContext {\n\tschema: GraphQLSchema;\n\tsizeArguments: readonly string[];\n\tdefaultFirst: number;\n\t/** What to assume for a size argument given as a variable where some definition declares no bound. */\n\tvariableSize?: number | undefined;\n}\n\n/**\n * What the schema alone says of one list field and the fields implementing it,\n * per size argument (in `sizeArguments` order): the largest default, whether\n * some definition has none, and whether some definition has no default at all.\n */\ninterface Profile {\n\tlargest: (number | undefined)[];\n\t/** Per size argument, the largest bound (`max` or `exclusiveMax`) over the definitions. */\n\tmaxima: (number | undefined)[];\n\t/** Per size argument, whether some definition declares no bound (`max` or `exclusiveMax`). */\n\tsomeNoMax: boolean[];\n\tsomeLack: boolean[];\n\tsomeBare: boolean;\n\t/** Whether some definition declares any of the size arguments. */\n\tdeclares: boolean;\n\t/** Whether some definition declares none of them. */\n\tsomeUndeclared: boolean;\n}\n\nconst profiles = new WeakMap<\n\tGraphQLSchema,\n\tWeakMap<readonly string[], Map<string, Profile>>\n>();\n\nfunction profileOf(\n\tcost: SizeContext,\n\tparent: GraphQLNamedType | undefined,\n\tdefinition: GraphQLField<unknown, unknown>,\n): Profile {\n\tlet bySizes = profiles.get(cost.schema);\n\tif (!bySizes) {\n\t\tbySizes = new WeakMap();\n\t\tprofiles.set(cost.schema, bySizes);\n\t}\n\tlet byField = bySizes.get(cost.sizeArguments);\n\tif (!byField) {\n\t\tbyField = new Map();\n\t\tbySizes.set(cost.sizeArguments, byField);\n\t}\n\tconst key = `${parent?.name}.${definition.name}`;\n\tconst known = byField.get(key);\n\tif (known) return known;\n\n\t// On an interface the object types' own fields count too: each may\n\t// declare another default, and the query cannot say which comes back.\n\tconst definitions = [definition];\n\tif (isAbstractType(parent)) {\n\t\tfor (const type of cost.schema.getPossibleTypes(parent)) {\n\t\t\tconst implemented = type.getFields()[definition.name];\n\t\t\tif (implemented) definitions.push(implemented);\n\t\t}\n\t}\n\tconst profile: Profile = {\n\t\tlargest: cost.sizeArguments.map(() => undefined),\n\t\tmaxima: cost.sizeArguments.map(() => undefined),\n\t\tsomeNoMax: cost.sizeArguments.map(() => false),\n\t\tsomeLack: cost.sizeArguments.map(() => false),\n\t\tsomeBare: false,\n\t\tdeclares: false,\n\t\tsomeUndeclared: false,\n\t};\n\tfor (const field of definitions) {\n\t\tlet any = false;\n\t\tcost.sizeArguments.forEach((name, index) => {\n\t\t\tconst argument = field.args.find((arg) => arg.name === name);\n\t\t\tconst max = constraintMaxOf(argument);\n\t\t\tif (max === undefined) profile.someNoMax[index] = true;\n\t\t\telse profile.maxima[index] = Math.max(profile.maxima[index] ?? 0, max);\n\t\t\tconst size = defaultSizeOf(argument);\n\t\t\tif (size === undefined) {\n\t\t\t\tprofile.someLack[index] = true;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tany = true;\n\t\t\tprofile.largest[index] = Math.max(profile.largest[index] ?? 0, size);\n\t\t});\n\t\tif (!any) profile.someBare = true;\n\t\tif (field.args.some((arg) => cost.sizeArguments.includes(arg.name))) {\n\t\t\tprofile.declares = true;\n\t\t} else {\n\t\t\tprofile.someUndeclared = true;\n\t\t}\n\t}\n\tbyField.set(key, profile);\n\treturn profile;\n}\n\n/** The size a size argument says, `undefined` when it says nothing. */\nfunction argumentSize(\n\tcost: SizeContext,\n\tprofile: Profile,\n\tindex: number,\n\tnode: ArgumentNode | undefined,\n): number | undefined {\n\tconst largest = profile.largest[index];\n\tif (!node) return largest;\n\tconst literal = literalSize(node.value);\n\tif (literal !== undefined) return literal;\n\t// Given but unusable (a variable, a negative number): the argument's own\n\t// default, else defaultFirst; and no less than the bound the client may send.\n\tconst today = profile.someLack[index]\n\t\t? Math.max(largest ?? 0, cost.defaultFirst)\n\t\t: largest;\n\tconst bound = unusableBound(cost, profile, index);\n\treturn bound === undefined ? today : Math.max(today ?? 0, bound);\n}\n\n/** What an unusable size may be at most: the declared bound (`max` or `exclusiveMax`), and `variableSize` where some definition declares none. */\nfunction unusableBound(\n\tcost: SizeContext,\n\tprofile: Profile,\n\tindex: number,\n): number | undefined {\n\tconst assumed = profile.someNoMax[index] ? cost.variableSize : undefined;\n\tconst declared = profile.maxima[index];\n\tif (assumed === undefined) return declared;\n\treturn Math.max(declared ?? 0, assumed);\n}\n\n/**\n * The size `definition` states on `parent`, as selected by `args`: the largest\n * its size arguments say, `undefined` when none says anything (none given, and\n * none declared with a default). The schema's part is memoized, so a selection\n * costs `sizeArguments.length` steps whatever the number of possible types.\n * A list uses it, and a field returning an object (a Relay connection) hands it\n * to the lists below it.\n */\nexport function statedSize(\n\tcost: SizeContext,\n\tparent: GraphQLNamedType | undefined,\n\tdefinition: GraphQLField<unknown, unknown>,\n\targs: readonly ArgumentNode[] | undefined,\n): number | undefined {\n\tconst profile = profileOf(cost, parent, definition);\n\tlet size: number | undefined;\n\tlet given = false;\n\tcost.sizeArguments.forEach((name, index) => {\n\t\tconst node = args?.find((arg) => arg.name.value === name);\n\t\tif (node) given = true;\n\t\tconst said = argumentSize(cost, profile, index, node);\n\t\tif (said !== undefined) size = Math.max(size ?? 0, said);\n\t});\n\t// Nothing given: a definition without any default is sized defaultFirst.\n\tif (size !== undefined && !given && profile.someBare) {\n\t\treturn Math.max(size, cost.defaultFirst);\n\t}\n\treturn size;\n}\n\n/**\n * Whether `definition` and the fields implementing it declare a size argument:\n * `'all'` of them, `'none'` of them, or `'some'` (an abstract parent whose\n * possible types differ).\n */\nexport function declaration(\n\tcost: SizeContext,\n\tparent: GraphQLNamedType | undefined,\n\tdefinition: GraphQLField<unknown, unknown>,\n): 'all' | 'none' | 'some' {\n\tconst { declares, someUndeclared } = profileOf(cost, parent, definition);\n\tif (!declares) return 'none';\n\treturn someUndeclared ? 'some' : 'all';\n}\n",
|
|
16
|
+
"import type { GraphQLArgument, ValueNode } from 'graphql';\nimport { CEILING } from './describe';\n\nconst CANONICAL_INTEGER = /^(0|[1-9]\\d*)$/;\n\n/**\n * The one reading of a size, wherever it comes from (a literal, a default): a\n * non-negative integral number or bigint, or a canonical-integer string,\n * clamped to the ceiling. Anything else says nothing.\n */\nexport function sizeOf(value: unknown): number | undefined {\n\tif (typeof value === 'string') {\n\t\treturn CANONICAL_INTEGER.test(value)\n\t\t\t? Math.min(Number(value), CEILING)\n\t\t\t: undefined;\n\t}\n\t// A bigint is how a Long scalar's default is held once its real scalar is\n\t// swapped in.\n\tif (typeof value === 'bigint') {\n\t\treturn value >= 0n ? Math.min(Number(value), CEILING) : undefined;\n\t}\n\treturn typeof value === 'number' && Number.isInteger(value) && value >= 0\n\t\t? Math.min(value, CEILING)\n\t\t: undefined;\n}\n\n/** The size a literal gives: an Int, a canonical-integer String or an integral Float (`1e3`). */\nexport function literalSize(value: ValueNode): number | undefined {\n\tif (value.kind === 'IntValue' || value.kind === 'FloatValue') {\n\t\treturn sizeOf(Number(value.value));\n\t}\n\treturn value.kind === 'StringValue' ? sizeOf(value.value) : undefined;\n}\n\n/**\n * An argument's SDL default as a size. graphql 16 holds it as `defaultValue`;\n * graphql 17 as `default`, `{ value }` or `{ literal }`.\n */\nexport function defaultSizeOf(\n\targument: object | undefined,\n): number | undefined {\n\tif (!argument) return undefined;\n\tif ('defaultValue' in argument) {\n\t\tconst size = sizeOf(argument.defaultValue);\n\t\tif (size !== undefined) return size;\n\t}\n\tif (!('default' in argument)) return undefined;\n\tconst fallback = argument.default;\n\tif (typeof fallback !== 'object' || fallback === null) return undefined;\n\tif ('value' in fallback) return sizeOf(fallback.value);\n\tif ('literal' in fallback && typeof fallback.literal === 'object') {\n\t\tconst literal = fallback.literal;\n\t\treturn literal !== null && 'kind' in literal\n\t\t\t? literalSize(literal as ValueNode)\n\t\t\t: undefined;\n\t}\n\treturn undefined;\n}\n\n/** A bound a literal gives: a finite number of at least 0 rounded up, or what `literalSize` reads in a string. */\nfunction boundOf(value: ValueNode): number | undefined {\n\t// Only an invalid schema has a string bound; reading \"100\" as 100 errs high.\n\tif (value.kind === 'StringValue') return literalSize(value);\n\tif (value.kind !== 'IntValue' && value.kind !== 'FloatValue')\n\t\treturn undefined;\n\tconst number = Number(value.value);\n\t// `max: 1e400` overflows to Infinity: an Infinity bound means unbounded.\n\treturn Number.isFinite(number) && number >= 0\n\t\t? Math.min(Math.ceil(number), CEILING)\n\t\t: undefined;\n}\n\n/**\n * The bound of an argument's `@constraint` directive, as a size: what the\n * client may send at most. The largest of `max` and `exclusiveMax` (the value\n * itself, a slight over-count), a fractional one rounded up. Read from the SDL\n * node, so a code-first argument (no `astNode`) declares none.\n */\nexport function constraintMaxOf(\n\targument: GraphQLArgument | undefined,\n): number | undefined {\n\tconst directive = argument?.astNode?.directives?.find(\n\t\t(node) => node.name.value === 'constraint',\n\t);\n\tlet largest: number | undefined;\n\tfor (const node of directive?.arguments ?? []) {\n\t\tif (node.name.value !== 'max' && node.name.value !== 'exclusiveMax') {\n\t\t\tcontinue;\n\t\t}\n\t\tconst bound = boundOf(node.value);\n\t\tif (bound !== undefined && (largest === undefined || bound > largest)) {\n\t\t\tlargest = bound;\n\t\t}\n\t}\n\treturn largest;\n}\n",
|
|
17
|
+
"/** Options of `maxListCost`. */\nexport interface MaxListCostOptions {\n\t/** The most an operation may cost (at least 0). */\n\tbudget: number;\n\t/** The size of a list field whose size cannot be read (an integer of at least 0). */\n\tdefaultFirst: number;\n\t/**\n\t * The argument names that size a list. Each one given, or defaulted in the\n\t * SDL, says a size (an Int, a canonical-integer string or an integral Float)\n\t * and the largest wins. Default `['first', 'last', 'limit']`. One on a\n\t * non-list field also sizes the lists declaring none directly on its return\n\t * type (a Relay connection's `edges` and `nodes`).\n\t */\n\tsizeArguments?: readonly string[];\n\t/**\n\t * Do not cost `__schema` and `__type` (default `false`). Only where\n\t * introspection is disabled or the client is trusted, e.g. GraphiQL in\n\t * development: the standard introspection query is costly (on the order of\n\t * 200,000 on a one-field schema).\n\t */\n\tignoreIntrospection?: boolean;\n\t/**\n\t * What to assume for a size argument the client sends as a variable (or\n\t * writes as an unusable literal): an integer of at least 0. Validation has\n\t * no variable values, and the client may send any value the argument\n\t * accepts, so such a size counts as the largest of its SDL default (else\n\t * `defaultFirst`), its declared bound (`@constraint(max)` or `exclusiveMax`)\n\t * and, where some definition declares no bound, this. It applies to every\n\t * size argument. A declared bound wins over this option only when every\n\t * definition declares one (the interface's field and each possible type's);\n\t * if any lacks one, this applies too and the largest wins. A code-first\n\t * argument has no SDL node, so only this applies to it. The operation's own\n\t * variable default is ignored. Default: none.\n\t */\n\tvariableSize?: number;\n}\n\nexport const DEFAULT_SIZE_ARGUMENTS = ['first', 'last', 'limit'] as const;\n",
|
|
15
18
|
"import type { ArgumentNode, GraphQLField, GraphQLNamedType } from 'graphql';\nimport { declaration, type SizeContext, statedSize } from './list-size';\n\n/**\n * The size of the list `definition` on `parent`. `pending` is the size of the\n * field whose return type this list is selected on (a connection's `first`):\n * a list that declares none of the size arguments takes it, since the size\n * cannot be stated on the list itself. A list that declares one reads its own\n * arguments, else `defaultFirst`, and never the pending size. On an abstract\n * parent some possible types may declare one and others not: the largest of\n * both readings, since the query cannot say which comes back.\n */\nexport function listSizeUnder(\n\tcost: SizeContext,\n\tparent: GraphQLNamedType | undefined,\n\tdefinition: GraphQLField<unknown, unknown>,\n\targs: readonly ArgumentNode[] | undefined,\n\tpending: number | undefined,\n): number {\n\tconst own = () =>\n\t\tstatedSize(cost, parent, definition, args) ?? cost.defaultFirst;\n\tif (pending === undefined) return own();\n\tconst declared = declaration(cost, parent, definition);\n\tif (declared === 'none') return pending;\n\tif (declared === 'all') return own();\n\t// Mixed: a possible type declaring none takes the pending size, another reads its own.\n\treturn Math.max(pending, own());\n}\n",
|
|
16
19
|
"import type { GraphQLFieldResolver, GraphQLResolveInfo } from 'graphql';\nimport { z } from 'zod';\nimport { parseArgs } from './bad-user-input';\n\n/** An object schema of the arguments, or its shape. */\nexport type ArgsSchema = z.ZodType<Record<string, unknown>> | z.ZodRawShape;\n\n/** The schema `ArgsSchema` stands for. */\nexport type SchemaOf<S extends ArgsSchema> = S extends z.ZodType\n\t? S\n\t: S extends z.ZodRawShape\n\t\t? // Mapped, not `S & z.ZodRawShape`: the intersection's index signature\n\t\t\t// would type every argument `unknown`.\n\t\t\tz.ZodObject<{ [K in keyof S]: S[K] }>\n\t\t: never;\n\n/**\n * What `validated` takes: the schema, or a function that builds it for each\n * call from the request's context and the field's `info`, for checks that\n * need them (a uniqueness query in the request's database, a rule that\n * depends on the viewer).\n */\nexport type ArgsSchemaFor<S extends ArgsSchema, TContext = unknown> =\n\t| S\n\t| SchemaFactory<S, TContext>;\n\ntype SchemaFactory<S extends ArgsSchema, TContext> = (\n\tcontext: TContext,\n\tinfo: GraphQLResolveInfo,\n) => S | Promise<S>;\n\n/**\n * A resolver whose arguments are checked by `schema` before it runs, for what\n * a `@constraint` cannot say: a rule across arguments, a business refinement,\n * an async check. It receives the parsed arguments (`z.output`), defaults and\n * transforms applied; an invalid input is the same `BAD_USER_INPUT` error as\n * the directives'.\n *\n * ```ts\n * signUp: validated(\n * z.object({ input: signUpSchema }).refine(({ input }) => input.password !== input.email),\n * (_, { input }) => users.create(input),\n * )\n * ```\n *\n * A check that needs the request takes a function in place of the schema:\n * it is called on each call, with the context and `info`, and returns the\n * schema (or a promise of it). What it throws reaches the client as it is,\n * not as `BAD_USER_INPUT`.\n *\n * ```ts\n * rename: validated(\n * (ctx: Context) => ({\n * name: z.string().refine(async (name) => !(await ctx.db.users.exists({ name })), 'taken'),\n * }),\n * (_, { name }, ctx) => ctx.db.users.rename(ctx.viewer, name),\n * )\n * ```\n */\nexport function validated<\n\tS extends ArgsSchema,\n\tTSource = unknown,\n\tTContext = unknown,\n\tTResult = unknown,\n>(\n\tschema: SchemaFactory<S, TContext>,\n\tresolve: (\n\t\tsource: TSource,\n\t\targs: z.output<SchemaOf<S>>,\n\t\tcontext: TContext,\n\t\tinfo: GraphQLResolveInfo,\n\t) => TResult,\n): GraphQLFieldResolver<\n\tTSource,\n\tTContext,\n\tz.input<SchemaOf<S>>,\n\tPromise<Awaited<TResult>>\n>;\nexport function validated<\n\tS extends ArgsSchema,\n\tTSource = unknown,\n\tTContext = unknown,\n\tTResult = unknown,\n>(\n\tschema: S,\n\tresolve: (\n\t\tsource: TSource,\n\t\targs: z.output<SchemaOf<S>>,\n\t\tcontext: TContext,\n\t\tinfo: GraphQLResolveInfo,\n\t) => TResult,\n): GraphQLFieldResolver<\n\tTSource,\n\tTContext,\n\tz.input<SchemaOf<S>>,\n\tPromise<Awaited<TResult>>\n>;\nexport function validated<\n\tS extends ArgsSchema,\n\tTSource = unknown,\n\tTContext = unknown,\n\tTResult = unknown,\n>(\n\tschema: ArgsSchemaFor<S, TContext>,\n\tresolve: (\n\t\tsource: TSource,\n\t\targs: z.output<SchemaOf<S>>,\n\t\tcontext: TContext,\n\t\tinfo: GraphQLResolveInfo,\n\t) => TResult,\n): GraphQLFieldResolver<\n\tTSource,\n\tTContext,\n\tz.input<SchemaOf<S>>,\n\tPromise<Awaited<TResult>>\n>;\nexport function validated<\n\tS extends ArgsSchema,\n\tTSource = unknown,\n\tTContext = unknown,\n\tTResult = unknown,\n>(\n\tschema: ArgsSchemaFor<S, TContext>,\n\tresolve: (\n\t\tsource: TSource,\n\t\targs: z.output<SchemaOf<S>>,\n\t\tcontext: TContext,\n\t\tinfo: GraphQLResolveInfo,\n\t) => TResult,\n): GraphQLFieldResolver<\n\tTSource,\n\tTContext,\n\tz.input<SchemaOf<S>>,\n\tPromise<Awaited<TResult>>\n> {\n\tconst fixed = typeof schema === 'function' ? undefined : zodOf(schema);\n\treturn async (source, args, context, info): Promise<Awaited<TResult>> => {\n\t\tconst where = `${info.parentType.name}.${info.fieldName}`;\n\t\tconst checked =\n\t\t\tfixed ??\n\t\t\tzodOf(await (schema as SchemaFactory<S, TContext>)(context, info));\n\t\tconst parsed = (await parseArgs(checked, args, where)) as z.output<\n\t\t\tSchemaOf<S>\n\t\t>;\n\t\treturn await resolve(source, parsed, context, info);\n\t};\n}\n\n/** The schema itself, or the object schema of a shape. */\nfunction zodOf(schema: ArgsSchema): z.ZodType {\n\t// `_zod`, not `instanceof`: a schema from another copy of zod is still one.\n\treturn (\n\t\t'_zod' in schema ? schema : z.object(schema as z.ZodRawShape)\n\t) as z.ZodType;\n}\n",
|
|
17
20
|
"import {\n\tdefaultFieldResolver,\n\ttype GraphQLField,\n\ttype GraphQLFieldResolver,\n\ttype GraphQLSchema,\n} from 'graphql';\nimport type { z } from 'zod';\nimport { type ConstraintOf, parseArgs } from './bad-user-input';\nimport { checkConstraints } from './builder/check-constraints';\nimport type { FormatSchemas, OwnFormats } from './formats/registry';\nimport { constraintOf } from './rules';\n\n// Symbol.for: two copies of the package in one tree still wrap a field once.\nconst wrapped = Symbol.for('@nxgt/graphql-validation/wrapped');\n// The formats a schema was wrapped with, kept on the schema itself.\nconst wrappedWith = Symbol.for('@nxgt/graphql-validation/formats');\n\n/** What `withValidation` takes besides the schema. */\nexport interface WithValidationOptions<\n\tF extends FormatSchemas = FormatSchemas,\n> {\n\t/**\n\t * The application's own formats, which `@constraint(format: \"...\")` may\n\t * name beside the built-in ones: one Zod string schema each, keyed by its\n\t * name (lowercase letters, digits and hyphens). A built-in name is a type\n\t * error, and refused at startup.\n\t */\n\treadonly formats?: OwnFormats<F>;\n}\n\ntype Resolver = GraphQLFieldResolver<unknown, unknown> & { [wrapped]?: true };\n\nfunction checking(\n\tschema: z.ZodType,\n\twhere: string,\n\tresolve: Resolver,\n\tconstraintOf: ConstraintOf,\n): Resolver {\n\tconst check: Resolver = async (source, args, context, info) =>\n\t\tawait resolve(\n\t\t\tsource,\n\t\t\tawait parseArgs(schema, args, where, constraintOf),\n\t\t\tcontext,\n\t\t\tinfo,\n\t\t);\n\tcheck[wrapped] = true;\n\treturn check;\n}\n\n/**\n * Wraps a field once. A subscription field is checked in `subscribe`, which\n * runs once per subscription — graphql's default one when the field has none\n * — and its `resolve` runs once per event, with the same arguments, already\n * checked.\n */\nfunction wrap(\n\tfield: GraphQLField<unknown, unknown>,\n\targs: z.ZodType,\n\twhere: string,\n\tsubscription: boolean,\n\tconstraintOf: ConstraintOf,\n): void {\n\tconst subscribe = (field.subscribe ??\n\t\t(subscription ? defaultFieldResolver : undefined)) as Resolver | undefined;\n\tif (subscribe) {\n\t\tif (!subscribe[wrapped])\n\t\t\tfield.subscribe = checking(args, where, subscribe, constraintOf);\n\t\treturn;\n\t}\n\tconst resolve = (field.resolve ?? defaultFieldResolver) as Resolver;\n\tif (!resolve[wrapped])\n\t\tfield.resolve = checking(args, where, resolve, constraintOf);\n}\n\n/**\n * Checks every `@constraint` of `schema` before the resolvers run. Each\n * field with a constrained argument — directly, or anywhere inside an input\n * type it takes — gets its resolver (and its `subscribe`) wrapped: the\n * arguments are parsed by the Zod schema the directives describe, the\n * resolver receives the parsed value, and an invalid input becomes one\n * `BAD_USER_INPUT` error. Fields with nothing to check are left untouched.\n *\n * The schema is built here, once: a constraint that cannot apply (a\n * `minLength` on an `Int`, an unknown format, a bad pattern) throws now, not\n * on the first request. The resolvers are wrapped in place and the same\n * schema is returned, so it goes wherever it went before; calling it twice\n * wraps nothing twice. Call it last, once every resolver is attached: a\n * resolver set on a field afterwards replaces the check.\n *\n * A `@constraint` on an interface's argument must be repeated on each\n * object's field, which is the one that resolves; a field that drops it\n * fails here.\n *\n * The directives are read from the SDL (`astNode`), so a schema built from\n * type definitions — `buildSchema`, `makeExecutableSchema`, Yoga, Apollo —\n * is checked; a code-first schema with no SDL has no `@constraint` to read.\n *\n * `options.formats` adds the application's own formats; wrapping a schema\n * again throws unless the record has the same names, each the very same\n * schema (no formats after some, or some after none, throws too), since its\n * fields are already checked against the first ones.\n */\nexport function withValidation<\n\tS extends GraphQLSchema,\n\t// biome-ignore lint/complexity/noBannedTypes: no formats of its own by default\n\tconst F extends FormatSchemas = {},\n>(schema: S, options: WithValidationOptions<F> = {}): S {\n\tconst formats: FormatSchemas = options.formats ?? {};\n\tconst holder = schema as unknown as { [wrappedWith]?: FormatSchemas };\n\tconst before = holder[wrappedWith];\n\tif (before && !sameFormats(before, formats)) {\n\t\tthrow new Error(\n\t\t\t'withValidation: this schema is already wrapped with other formats. Call withValidation once, with every format.',\n\t\t);\n\t}\n\tconst directive = checkConstraints(\n\t\tschema,\n\t\t(type, field, args, declared) => {\n\t\t\tconst subscription = type === schema.getSubscriptionType();\n\t\t\t// The rule that refused, with the value this field's SDL declares at the path.\n\t\t\tconst named: ConstraintOf = (issue) => {\n\t\t\t\tconst argument = constraintOf(issue);\n\t\t\t\tif (!argument) return undefined;\n\t\t\t\t// Found: the SDL carries the constraints (interfaces repeat theirs,\n\t\t\t\t// assertInterfaceConstraintsKept), so a miss drops `constraint` by design.\n\t\t\t\tconst found = declared(issue.path).find(\n\t\t\t\t\t({ rule }) => rule.argument === argument,\n\t\t\t\t);\n\t\t\t\treturn found && { argument, value: found.value };\n\t\t\t};\n\t\t\twrap(field, args, `${type.name}.${field.name}`, subscription, named);\n\t\t},\n\t\tformats,\n\t);\n\tif (!directive) {\n\t\tthrow new Error(\n\t\t\t'withValidation: this schema declares no @constraint directive. Add constraintTypeDefs to its type definitions.',\n\t\t);\n\t}\n\tif (!before) Object.defineProperty(schema, wrappedWith, { value: formats });\n\treturn schema;\n}\n\n/** The same names, each the very same schema. */\nfunction sameFormats(a: FormatSchemas, b: FormatSchemas): boolean {\n\tconst names = Object.keys(a);\n\treturn (\n\t\tnames.length === Object.keys(b).length &&\n\t\tnames.every((name) => Object.hasOwn(b, name) && a[name] === b[name])\n\t);\n}\n"
|
|
18
21
|
],
|
|
19
|
-
"mappings": "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",
|
|
20
|
-
"debugId": "
|
|
22
|
+
"mappings": ";;;;;;;;;AAAA;AA2CA,SAAS,QAAQ,CAChB,OACA,cACoB;AAAA,EACpB,OAAO,MAAM,OAAO,IAAI,CAAC,UAAU;AAAA,IAClC,MAAM,OAAO,MAAM,KAAK,IAAI,CAAC,QAC5B,OAAO,QAAQ,WAAW,MAAM,OAAO,GAAG,CAC3C;AAAA,IACA,MAAM,aAAa,eAAe,KAAK;AAAA,IACvC,OAAO,aACJ;AAAA,MACA;AAAA,MACA,SAAS,MAAM;AAAA,MACf,MAAM,MAAM;AAAA,MACZ,YAAY,WAAW;AAAA,MACvB,OAAO,WAAW;AAAA,IACnB,IACC,EAAE,MAAM,SAAS,MAAM,SAAS,MAAM,MAAM,KAAK;AAAA,GACpD;AAAA;AAGF,SAAS,OAAO,CAAC,OAAe,QAAyC;AAAA,EACxE,OAAO,SAAS;AAAA,EAChB,MAAM,SAAS,QACZ,GAAG,MAAM,KAAK,KAAK,GAAG,KAAK,gBAAgB,MAAM,YACjD;AAAA,EACH,MAAM,aAAqC,EAAE,MAAM,kBAAkB,OAAO;AAAA,EAC5E,OAAO,IAAI,aAAa,yBAAyB,UAAU,UAAU;AAAA,IACpE;AAAA,EACD,CAAC;AAAA;AAUK,SAAS,YAAY,CAAC,OAAe,OAAiC;AAAA,EAC5E,OAAO,QAAQ,OAAO,SAAS,KAAK,CAAC;AAAA;AAItC,eAAsB,SAAS,CAC9B,QACA,MACA,OACA,cACmB;AAAA,EACnB,MAAM,SAAS,MAAM,OAAO,eAAe,IAAI;AAAA,EAC/C,IAAI,CAAC,OAAO;AAAA,IACX,MAAM,QAAQ,OAAO,SAAS,OAAO,OAAO,YAAY,CAAC;AAAA,EAC1D,OAAO,OAAO;AAAA;;AChGf,yBAAS;AAGF,IAAM,gBAAgB;AAyC7B,SAAS,QAAQ,CAAC,QAA0D;AAAA,EAC3E,OAAO,UAAU,OAAO,KAAK,MAAM,EAAE,SAAS,IAAI,SAAS;AAAA;AAG5D,SAAS,SAAS,CACjB,MACA,QACA,WACS;AAAA,EACT,OAAO,YAAY,MAAM,MAAM,KAAK;AAAA;AAGrC,SAAS,QAAQ,CAChB,QACA,WACe;AAAA,EACf,OAAO,OAAO,IAAI,GAAG,MAAM,MAAM,QAAQ,YAAY;AAAA,IACpD,MAAM,SAAS,SAAS,KAAK;AAAA,IAC7B,OAAO;AAAA,MACN;AAAA,MACA;AAAA,MACA,SAAS,UAAU,MAAM,QAAQ,SAAS;AAAA,SACtC,UAAU,EAAE,OAAO;AAAA,IACxB;AAAA,GACA;AAAA;AAWK,SAAS,iBAAiB,CAChC,QACA,UAA+B,CAAC,GACjB;AAAA,EACf,QAAQ,cAAc,YAAY;AAAA,EAClC,OAAO,IAAI,cAAa,UAAU,eAAe,WAAW,SAAS,GAAG;AAAA,OACpE;AAAA,IACH,YAAY;AAAA,MACX,MAAM;AAAA,MACN,MAAM,EAAE,QAAQ,IAAI;AAAA,MACpB,QAAQ,SAAS,QAAQ,SAAS;AAAA,IACnC;AAAA,EACD,CAAC;AAAA;AAUK,SAAS,WAAW,CAC1B,MACA,QACA,UAA8B,CAAC,GAChB;AAAA,EACf,QAAQ,WAAW,QAAQ,QAAQ,UAAU,YAAY;AAAA,EACzD,MAAM,SAAS,SAAS,KAAK;AAAA,EAC7B,OAAO,IAAI,cAAa,UAAU,MAAM,QAAQ,SAAS,GAAG;AAAA,OACxD;AAAA,IACH,YAAY;AAAA,MACX;AAAA,SACI,UAAU,EAAE,OAAO;AAAA,SACnB,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE;AAAA,MACjC,QAAQ,SAAS,QAAQ,SAAS;AAAA,IACnC;AAAA,EACD,CAAC;AAAA;AAUK,SAAS,SAAS,CAAC,MAAsC;AAAA,EAC/D,OAAO,UAAU,QAAQ;AAAA,EACzB,QAAQ,UAAU,WAAW,KAAK,SAAS,IAAI,OAAO,MACpD,IAAI,CAAC,QAAQ,OAAO,GAAG,CAAC,EACxB,KAAK,GAAG;AAAA;;;ACzHJ,IAAM,cAAc;AAAA,EAC1B,UAAU;AAAA,EACV,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,eAAe;AAAA,EACf,SAAS;AACV;AAGA,IAAM,cAAmC,IAAI,IAAI;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AACD,CAAC;AAWM,SAAS,YAAY,CAAC,OAAqC;AAAA,EACjE,OAAO,EAAE,MAAM,UAAU,MAAM,IAAI,GAAG,MAAM,OAAO,KAAK,EAAE;AAAA;AAG3D,SAAS,MAAM,CAAC,OAAiC;AAAA,EAChD,QAAQ,MAAM;AAAA,SACR;AAAA,SACA,WAAW;AAAA,MACf,MAAM,QAAQ,MAAM,SAAS;AAAA,MAC7B,QAAQ,MAAM;AAAA,aACR;AAAA,UACJ,OAAO,QAAQ,YAAY,WAAW,YAAY;AAAA,aAC9C;AAAA,aACA;AAAA,UACJ,OAAO,YAAY;AAAA,aACf;AAAA,aACA;AAAA,UACJ,OAAO,QAAQ,YAAY,SAAS,YAAY;AAAA;AAAA,UAEhD,OAAO,YAAY;AAAA;AAAA,IAEtB;AAAA,SACK;AAAA,MACJ,OAAO,YAAY;AAAA,SACf;AAAA,MAGJ,OAAO,YAAY,IAAI,MAAM,MAAM,IAChC,YAAY,UACZ,YAAY;AAAA;AAAA,MAEf,OAAO,YAAY;AAAA;AAAA;;AClEtB;AAAA,kBACC;AAAA;;;ACEM,IAAM,UAAU,OAAO;AAGvB,IAAM,MAAM,CAAC,GAAW,MAAc,KAAK,IAAI,SAAS,IAAI,CAAC;AAG7D,SAAS,cAAc,CAAC,WAA4C;AAAA,EAC1E,OAAO,UAAU,OAAO,cAAc,UAAU,KAAK,WAAW;AAAA;AAO1D,SAAS,aAAa,CAC5B,QACA,OACA,KACA,MAAM,SACC;AAAA,EACP,IAAI,CAAC,OAAO,UAAU,KAAK,KAAK,QAAQ,OAAO,SAAS,KAAK;AAAA,IAC5D,MAAM,IAAI,WACT,GAAG,kCAAkC,UAAU,MAAM,IACtD;AAAA,EACD;AAAA;;;ACxBM,IAAM,SAAS;AAUf,SAAS,eAAe,CAC9B,aACe;AAAA,EACf,OAAO,EAAE,aAAa,QAAQ,IAAI,KAAO,UAAU,IAAI,IAAM;AAAA;AASvD,SAAS,aAAa,CAC5B,MACA,MACA,KACA,SACS;AAAA,EACT,IAAI,QAAQ,KAAK,OAAO,IAAI,IAAI;AAAA,EAChC,IAAI,CAAC,OAAO;AAAA,IACX,QAAQ,IAAI;AAAA,IACZ,KAAK,OAAO,IAAI,MAAM,KAAK;AAAA,EAC5B;AAAA,EACA,MAAM,KAAK,OAAO,QAAQ,WAAW,MAAM,IAAI,KAAK;AAAA,EACpD,MAAM,OAAO,MAAM,IAAI,EAAE;AAAA,EACzB,IAAI,SAAS;AAAA,IAAW,OAAO;AAAA,EAC/B,MAAM,WAAW,KAAK,YAAY,IAAI;AAAA,EACtC,IAAI,CAAC,YAAY,KAAK,SAAS,IAAI,IAAI;AAAA,IAAG,OAAO;AAAA,EACjD,KAAK,SAAS,IAAI,IAAI;AAAA,EACtB,MAAM,SAAS,QAAQ,UAAU,EAAE;AAAA,EACnC,KAAK,SAAS,OAAO,IAAI;AAAA,EACzB,MAAM,IAAI,IAAI,MAAM;AAAA,EACpB,OAAO;AAAA;;;AC7CR;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcO,SAAS,mBAAmB,CAAC,MAAuB;AAAA,EAC1D,OAAO,SAAS,cAAc,SAAS;AAAA;AAIjC,SAAS,iBAAiB,CAChC,MAC6C;AAAA,EAC7C,IAAI,SAAS;AAAA,IAAY,OAAO;AAAA,EAChC,IAAI,SAAS;AAAA,IAAU,OAAO;AAAA,EAC9B;AAAA;AAID,IAAM,UAAU,IAAI;AAEpB,IAAM,aAAa,IAAI;AAEvB,SAAS,SAAS,CAAC,QAA+B;AAAA,EACjD,IAAI,QAAQ,WAAW,IAAI,MAAM;AAAA,EACjC,IAAI,UAAU,WAAW;AAAA,IACxB,QAAQ,OAAO,KAAK,OAAO,WAAW,CAAC,EAAE;AAAA,IACzC,WAAW,IAAI,QAAQ,KAAK;AAAA,EAC7B;AAAA,EACA,OAAO;AAAA;AAGR,SAAS,YAAY,CAAC,QAA+B;AAAA,EACpD,MAAM,QAAQ,QAAQ,IAAI,MAAM;AAAA,EAChC,IAAI,UAAU;AAAA,IAAW,OAAO;AAAA,EAChC,IAAI,MAAM,OAAO,cAAc,EAAE;AAAA,EACjC,WAAW,aAAa,OAAO,cAAc,GAAG;AAAA,IAC/C,MAAM,KAAK,IAAI,KAAK,UAAU,KAAK,QAAQ,UAAU,UAAU,MAAM;AAAA,EACtE;AAAA,EACA,WAAW,QAAQ,OAAO,OAAO,OAAO,WAAW,CAAC,GAAG;AAAA,IACtD,MAAM,KAAK,IAAI,KAAK,SAAS,QAAQ,IAAI,CAAC;AAAA,EAC3C;AAAA,EACA,QAAQ,IAAI,QAAQ,GAAG;AAAA,EACvB,OAAO;AAAA;AAIR,SAAS,QAAQ,CAAC,QAAuB,MAAgC;AAAA,EACxE,IAAI,aAAa,IAAI,KAAK,gBAAgB,IAAI,GAAG;AAAA,IAChD,MAAM,SAAS,OAAO,OAAO,KAAK,UAAU,CAAC;AAAA,IAC7C,OAAO,KAAK,IACX,OAAO,QACP,KAAK,cAAc,EAAE,QACrB,gBAAgB,IAAI,IAAI,OAAO,iBAAiB,IAAI,EAAE,SAAS,GAC/D,GAAG,OAAO,IAAI,CAAC,UAAU,MAAM,KAAK,MAAM,CAC3C;AAAA,EACD;AAAA,EACA,IAAI,kBAAkB,IAAI;AAAA,IAAG,OAAO,OAAO,KAAK,KAAK,UAAU,CAAC,EAAE;AAAA,EAClE,IAAI,WAAW,IAAI;AAAA,IAAG,OAAO,KAAK,UAAU,EAAE;AAAA,EAC9C,IAAI,YAAY,IAAI;AAAA,IAAG,OAAO,KAAK,SAAS,EAAE;AAAA,EAC9C,OAAO;AAAA;AAQD,SAAS,iBAAiB,CAChC,QACA,OACS;AAAA,EACT,OAAO,UAAU,UAAU,UAAU,MAAM,IAAI,aAAa,MAAM;AAAA;;;AHhDnE,SAAS,OAAO,CAAC,OAAqB,cAAwC;AAAA,EAC7E,IAAI,UAAU;AAAA,EACd,WAAW,aAAa,aAAa,YAAY;AAAA,IAChD,IAAI,OAAO;AAAA,IACX,IAAI,UAAU,SAAS,SAAS;AAAA,MAC/B,MAAM,OAAO,UAAU,KAAK;AAAA,MAC5B,IAAI,SAAS;AAAA,QAAc;AAAA,MAC3B,IAAI,MAAM,uBAAuB,oBAAoB,IAAI;AAAA,QAAG;AAAA,MAC5D,OACC,KACC,UAAU,eAAe,QAAQ,OAAO,UAAU,YAAY,IAAI;AAAA,IACrE,EAAO,SAAI,UAAU,SAAS,kBAAkB;AAAA,MAC/C,OAAO,QAAQ,OAAO,UAAU,YAAY;AAAA,IAC7C,EAAO;AAAA,MACN,OAAO,cAAc,OAAO,UAAU,KAAK,KAAK;AAAA;AAAA,IAEjD,IAAI,OAAO;AAAA,MAAS,UAAU;AAAA,EAC/B;AAAA,EACA,OAAO;AAAA;AAIR,SAAS,aAAa,CAAC,OAAqB,MAAsB;AAAA,EACjE,OAAO,cAAc,OAAO,MAAM,QAAQ,CAAC,aAC1C,QAAQ,OAAO,SAAS,YAAY,CACrC;AAAA;AAiBM,SAAS,QAAQ,CAAC,SAA0C;AAAA,EAClE,MAAM,QAAQ,QAAQ;AAAA,EACtB,cAAc,mBAAmB,OAAO,CAAC;AAAA,EACzC,OAAO,CAAC,YAA+B;AAAA,IACtC,MAAM,OAAqB;AAAA,SACvB,gBAAgB,CAAC,SAAS,QAAQ,YAAY,IAAI,CAAC;AAAA,MACtD,qBAAqB,QAAQ,uBAAuB;AAAA,IACrD;AAAA,IACA,OAAO;AAAA,MACN,mBAAmB,CAAC,WAAW;AAAA,QAC9B,MAAM,QAAQ,QAAQ,MAAM,UAAU,YAAY;AAAA,QAClD,IAAI,QAAQ,OAAO;AAAA,UAClB,QAAQ,YACP,IAAI,cACH,GAAG,eAAe,SAAS,QAAQ,oCAAoC,iBACvE;AAAA,YACC,OAAO,CAAC,SAAS;AAAA,YACjB,YAAY,EAAE,MAAM,kBAAkB,OAAO,MAAM;AAAA,UACpD,CACD,CACD;AAAA,QACD;AAAA,QACA,OAAO;AAAA;AAAA,IAET;AAAA;AAAA;;AInGF;AAAA,kBACC;AAAA;AAiCD,SAAS,OAAO,CAAC,MAAqB,cAAwC;AAAA,EAC7E,IAAI,QAAQ;AAAA,EACZ,WAAW,aAAa,aAAa,YAAY;AAAA,IAChD,IAAI,UAAU,SAAS,SAAS;AAAA,MAC/B,IAAI,KAAK,uBAAuB,oBAAoB,UAAU,KAAK,KAAK;AAAA,QACvE;AAAA,MACD,QAAQ,IAAI,OAAO,CAAC;AAAA,MACpB,IAAI,UAAU;AAAA,QACb,QAAQ,IAAI,OAAO,QAAQ,MAAM,UAAU,YAAY,CAAC;AAAA,IAC1D,EAAO,SAAI,UAAU,SAAS,kBAAkB;AAAA,MAC/C,QAAQ,IAAI,OAAO,QAAQ,MAAM,UAAU,YAAY,CAAC;AAAA,IACzD,EAAO;AAAA,MACN,QAAQ,IAAI,OAAO,cAAc,MAAM,UAAU,KAAK,KAAK,CAAC;AAAA;AAAA,EAE9D;AAAA,EACA,OAAO;AAAA;AAIR,SAAS,aAAa,CAAC,MAAqB,MAAsB;AAAA,EACjE,OAAO,cAAc,MAAM,MAAM,QAAQ,CAAC,aACzC,QAAQ,MAAM,SAAS,YAAY,CACpC;AAAA;AAuBM,SAAS,SAAS,CAAC,SAA2C;AAAA,EACpE,MAAM,QAAQ,QAAQ;AAAA,EACtB,cAAc,oBAAoB,OAAO,CAAC;AAAA,EAC1C,OAAO,CAAC,YAA+B;AAAA,IACtC,MAAM,OAAsB;AAAA,SACxB,gBAAgB,CAAC,SAAS,QAAQ,YAAY,IAAI,CAAC;AAAA,MACtD,qBAAqB,QAAQ,uBAAuB;AAAA,IACrD;AAAA,IACA,OAAO;AAAA,MACN,mBAAmB,CAAC,WAAW;AAAA,QAC9B,MAAM,SAAS,QAAQ,MAAM,UAAU,YAAY;AAAA,QACnD,IAAI,SAAS,OAAO;AAAA,UACnB,QAAQ,YACP,IAAI,cACH,GAAG,eAAe,SAAS,aAAa,gCAAgC,iBACxE;AAAA,YACC,OAAO,CAAC,SAAS;AAAA,YACjB,YAAY,EAAE,MAAM,kBAAkB,QAAQ,MAAM;AAAA,UACrD,CACD,CACD;AAAA,QACD;AAAA,QACA,OAAO;AAAA;AAAA,IAET;AAAA;AAAA;;ACvGF;AAAA,kBAEC;AAAA;AAAA;AAAA;AAAA;;;ACFD;AAAA,qBAIC;AAAA,kBACA;AAAA;AAQM,IAAM,WAAW,CAAC,GAAW,MAAc,KAAK,IAAI,SAAS,IAAI,CAAC;AAQlE,SAAS,OAAO,CACtB,MACA,QACA,MAC6C;AAAA,EAC7C,IAAI,WAAW,KAAK,OAAO,aAAa,KAAK,oBAAoB,IAAI,GAAG;AAAA,IACvE,OAAO,kBAAkB,IAAI;AAAA,EAC9B;AAAA,EACA,OAAO,cAAa,MAAM,KAAK,iBAAgB,MAAM,IAClD,OAAO,UAAU,EAAE,QACnB;AAAA;AAIG,SAAS,QAAQ,CACvB,QACA,WACC;AAAA,EACD,MAAM,OACL,UAAU,cAAc,UACrB,OAAO,aAAa,IACpB,UAAU,cAAc,aACvB,OAAO,gBAAgB,IACvB,OAAO,oBAAoB;AAAA,EAChC,OAAO,QAAQ;AAAA;AAIhB,IAAM,cAAc;AAMb,IAAM,aAAa;AASnB,SAAS,QAAQ,CACvB,OACA,SACqB;AAAA,EACrB,IAAI,YAAY,aAAa,MAAM,IAAI,OAAO,KAAK,MAAM,OAAO,aAAa;AAAA,IAC5E,OAAO;AAAA,EACR;AAAA,EAEA,IAAI,UAAU,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,IAAI,SAAS,CAAC,CAAC,CAAC;AAAA,EAC5D,IAAI,UAAU;AAAA,IAAS,WAAW;AAAA,EAClC,OAAO,KAAK,IAAI,SAAS,OAAO;AAAA;;;AC1EjC;AAAA;AAAA;;;ACGA,IAAM,oBAAoB;AAOnB,SAAS,MAAM,CAAC,OAAoC;AAAA,EAC1D,IAAI,OAAO,UAAU,UAAU;AAAA,IAC9B,OAAO,kBAAkB,KAAK,KAAK,IAChC,KAAK,IAAI,OAAO,KAAK,GAAG,OAAO,IAC/B;AAAA,EACJ;AAAA,EAGA,IAAI,OAAO,UAAU,UAAU;AAAA,IAC9B,OAAO,SAAS,KAAK,KAAK,IAAI,OAAO,KAAK,GAAG,OAAO,IAAI;AAAA,EACzD;AAAA,EACA,OAAO,OAAO,UAAU,YAAY,OAAO,UAAU,KAAK,KAAK,SAAS,IACrE,KAAK,IAAI,OAAO,OAAO,IACvB;AAAA;AAIG,SAAS,WAAW,CAAC,OAAsC;AAAA,EACjE,IAAI,MAAM,SAAS,cAAc,MAAM,SAAS,cAAc;AAAA,IAC7D,OAAO,OAAO,OAAO,MAAM,KAAK,CAAC;AAAA,EAClC;AAAA,EACA,OAAO,MAAM,SAAS,gBAAgB,OAAO,MAAM,KAAK,IAAI;AAAA;AAOtD,SAAS,aAAa,CAC5B,UACqB;AAAA,EACrB,IAAI,CAAC;AAAA,IAAU;AAAA,EACf,IAAI,kBAAkB,UAAU;AAAA,IAC/B,MAAM,OAAO,OAAO,SAAS,YAAY;AAAA,IACzC,IAAI,SAAS;AAAA,MAAW,OAAO;AAAA,EAChC;AAAA,EACA,IAAI,EAAE,aAAa;AAAA,IAAW;AAAA,EAC9B,MAAM,WAAW,SAAS;AAAA,EAC1B,IAAI,OAAO,aAAa,YAAY,aAAa;AAAA,IAAM;AAAA,EACvD,IAAI,WAAW;AAAA,IAAU,OAAO,OAAO,SAAS,KAAK;AAAA,EACrD,IAAI,aAAa,YAAY,OAAO,SAAS,YAAY,UAAU;AAAA,IAClE,MAAM,UAAU,SAAS;AAAA,IACzB,OAAO,YAAY,QAAQ,UAAU,UAClC,YAAY,OAAoB,IAChC;AAAA,EACJ;AAAA,EACA;AAAA;AAID,SAAS,OAAO,CAAC,OAAsC;AAAA,EAEtD,IAAI,MAAM,SAAS;AAAA,IAAe,OAAO,YAAY,KAAK;AAAA,EAC1D,IAAI,MAAM,SAAS,cAAc,MAAM,SAAS;AAAA,IAC/C;AAAA,EACD,MAAM,SAAS,OAAO,MAAM,KAAK;AAAA,EAEjC,OAAO,OAAO,SAAS,MAAM,KAAK,UAAU,IACzC,KAAK,IAAI,KAAK,KAAK,MAAM,GAAG,OAAO,IACnC;AAAA;AASG,SAAS,eAAe,CAC9B,UACqB;AAAA,EACrB,MAAM,YAAY,UAAU,SAAS,YAAY,KAChD,CAAC,SAAS,KAAK,KAAK,UAAU,YAC/B;AAAA,EACA,IAAI;AAAA,EACJ,WAAW,QAAQ,WAAW,aAAa,CAAC,GAAG;AAAA,IAC9C,IAAI,KAAK,KAAK,UAAU,SAAS,KAAK,KAAK,UAAU,gBAAgB;AAAA,MACpE;AAAA,IACD;AAAA,IACA,MAAM,QAAQ,QAAQ,KAAK,KAAK;AAAA,IAChC,IAAI,UAAU,cAAc,YAAY,aAAa,QAAQ,UAAU;AAAA,MACtE,UAAU;AAAA,IACX;AAAA,EACD;AAAA,EACA,OAAO;AAAA;;;ADzDR,IAAM,WAAW,IAAI;AAKrB,SAAS,SAAS,CACjB,MACA,QACA,YACU;AAAA,EACV,IAAI,UAAU,SAAS,IAAI,KAAK,MAAM;AAAA,EACtC,IAAI,CAAC,SAAS;AAAA,IACb,UAAU,IAAI;AAAA,IACd,SAAS,IAAI,KAAK,QAAQ,OAAO;AAAA,EAClC;AAAA,EACA,IAAI,UAAU,QAAQ,IAAI,KAAK,aAAa;AAAA,EAC5C,IAAI,CAAC,SAAS;AAAA,IACb,UAAU,IAAI;AAAA,IACd,QAAQ,IAAI,KAAK,eAAe,OAAO;AAAA,EACxC;AAAA,EACA,MAAM,MAAM,GAAG,QAAQ,QAAQ,WAAW;AAAA,EAC1C,MAAM,QAAQ,QAAQ,IAAI,GAAG;AAAA,EAC7B,IAAI;AAAA,IAAO,OAAO;AAAA,EAIlB,MAAM,cAAc,CAAC,UAAU;AAAA,EAC/B,IAAI,eAAe,MAAM,GAAG;AAAA,IAC3B,WAAW,QAAQ,KAAK,OAAO,iBAAiB,MAAM,GAAG;AAAA,MACxD,MAAM,cAAc,KAAK,UAAU,EAAE,WAAW;AAAA,MAChD,IAAI;AAAA,QAAa,YAAY,KAAK,WAAW;AAAA,IAC9C;AAAA,EACD;AAAA,EACA,MAAM,UAAmB;AAAA,IACxB,SAAS,KAAK,cAAc,IAAI,MAAG;AAAA,MAAG;AAAA,KAAS;AAAA,IAC/C,QAAQ,KAAK,cAAc,IAAI,MAAG;AAAA,MAAG;AAAA,KAAS;AAAA,IAC9C,WAAW,KAAK,cAAc,IAAI,MAAM,KAAK;AAAA,IAC7C,UAAU,KAAK,cAAc,IAAI,MAAM,KAAK;AAAA,IAC5C,UAAU;AAAA,IACV,UAAU;AAAA,IACV,gBAAgB;AAAA,EACjB;AAAA,EACA,WAAW,SAAS,aAAa;AAAA,IAChC,IAAI,MAAM;AAAA,IACV,KAAK,cAAc,QAAQ,CAAC,MAAM,UAAU;AAAA,MAC3C,MAAM,WAAW,MAAM,KAAK,KAAK,CAAC,QAAQ,IAAI,SAAS,IAAI;AAAA,MAC3D,MAAM,MAAM,gBAAgB,QAAQ;AAAA,MACpC,IAAI,QAAQ;AAAA,QAAW,QAAQ,UAAU,SAAS;AAAA,MAC7C;AAAA,gBAAQ,OAAO,SAAS,KAAK,IAAI,QAAQ,OAAO,UAAU,GAAG,GAAG;AAAA,MACrE,MAAM,OAAO,cAAc,QAAQ;AAAA,MACnC,IAAI,SAAS,WAAW;AAAA,QACvB,QAAQ,SAAS,SAAS;AAAA,QAC1B;AAAA,MACD;AAAA,MACA,MAAM;AAAA,MACN,QAAQ,QAAQ,SAAS,KAAK,IAAI,QAAQ,QAAQ,UAAU,GAAG,IAAI;AAAA,KACnE;AAAA,IACD,IAAI,CAAC;AAAA,MAAK,QAAQ,WAAW;AAAA,IAC7B,IAAI,MAAM,KAAK,KAAK,CAAC,QAAQ,KAAK,cAAc,SAAS,IAAI,IAAI,CAAC,GAAG;AAAA,MACpE,QAAQ,WAAW;AAAA,IACpB,EAAO;AAAA,MACN,QAAQ,iBAAiB;AAAA;AAAA,EAE3B;AAAA,EACA,QAAQ,IAAI,KAAK,OAAO;AAAA,EACxB,OAAO;AAAA;AAIR,SAAS,YAAY,CACpB,MACA,SACA,OACA,MACqB;AAAA,EACrB,MAAM,UAAU,QAAQ,QAAQ;AAAA,EAChC,IAAI,CAAC;AAAA,IAAM,OAAO;AAAA,EAClB,MAAM,UAAU,YAAY,KAAK,KAAK;AAAA,EACtC,IAAI,YAAY;AAAA,IAAW,OAAO;AAAA,EAGlC,MAAM,QAAQ,QAAQ,SAAS,SAC5B,KAAK,IAAI,WAAW,GAAG,KAAK,YAAY,IACxC;AAAA,EACH,MAAM,QAAQ,cAAc,MAAM,SAAS,KAAK;AAAA,EAChD,OAAO,UAAU,YAAY,QAAQ,KAAK,IAAI,SAAS,GAAG,KAAK;AAAA;AAIhE,SAAS,aAAa,CACrB,MACA,SACA,OACqB;AAAA,EACrB,MAAM,UAAU,QAAQ,UAAU,SAAS,KAAK,eAAe;AAAA,EAC/D,MAAM,WAAW,QAAQ,OAAO;AAAA,EAChC,IAAI,YAAY;AAAA,IAAW,OAAO;AAAA,EAClC,OAAO,KAAK,IAAI,YAAY,GAAG,OAAO;AAAA;AAWhC,SAAS,UAAU,CACzB,MACA,QACA,YACA,MACqB;AAAA,EACrB,MAAM,UAAU,UAAU,MAAM,QAAQ,UAAU;AAAA,EAClD,IAAI;AAAA,EACJ,IAAI,QAAQ;AAAA,EACZ,KAAK,cAAc,QAAQ,CAAC,MAAM,UAAU;AAAA,IAC3C,MAAM,OAAO,MAAM,KAAK,CAAC,QAAQ,IAAI,KAAK,UAAU,IAAI;AAAA,IACxD,IAAI;AAAA,MAAM,QAAQ;AAAA,IAClB,MAAM,OAAO,aAAa,MAAM,SAAS,OAAO,IAAI;AAAA,IACpD,IAAI,SAAS;AAAA,MAAW,OAAO,KAAK,IAAI,QAAQ,GAAG,IAAI;AAAA,GACvD;AAAA,EAED,IAAI,SAAS,aAAa,CAAC,SAAS,QAAQ,UAAU;AAAA,IACrD,OAAO,KAAK,IAAI,MAAM,KAAK,YAAY;AAAA,EACxC;AAAA,EACA,OAAO;AAAA;AAQD,SAAS,WAAW,CAC1B,MACA,QACA,YAC0B;AAAA,EAC1B,QAAQ,UAAU,mBAAmB,UAAU,MAAM,QAAQ,UAAU;AAAA,EACvE,IAAI,CAAC;AAAA,IAAU,OAAO;AAAA,EACtB,OAAO,iBAAiB,SAAS;AAAA;;;AE9I3B,IAAM,yBAAyB,CAAC,SAAS,QAAQ,OAAO;;;ACzBxD,SAAS,aAAa,CAC5B,MACA,QACA,YACA,MACA,SACS;AAAA,EACT,MAAM,MAAM,MACX,WAAW,MAAM,QAAQ,YAAY,IAAI,KAAK,KAAK;AAAA,EACpD,IAAI,YAAY;AAAA,IAAW,OAAO,IAAI;AAAA,EACtC,MAAM,WAAW,YAAY,MAAM,QAAQ,UAAU;AAAA,EACrD,IAAI,aAAa;AAAA,IAAQ,OAAO;AAAA,EAChC,IAAI,aAAa;AAAA,IAAO,OAAO,IAAI;AAAA,EAEnC,OAAO,KAAK,IAAI,SAAS,IAAI,CAAC;AAAA;;;ALW/B,SAAS,SAAS,CACjB,MACA,QACA,WACA,YACA,SACS;AAAA,EACT,IAAI,CAAC,UAAU;AAAA,IAAc,OAAO;AAAA,EACpC,MAAM,OAAO,UAAU,KAAK;AAAA,EAC5B,MAAM,OAAO,aAAa,WAAW,IAAI;AAAA,EACzC,IAAI,CAAC,WAAW,gBAAgB,WAAW,IAAI,CAAC,GAAG;AAAA,IAGlD,MAAM,SAAS,WAAW,MAAM,QAAQ,YAAY,UAAU,SAAS;AAAA,IACvE,MAAM,QAAQ,OAAO,MAAM,UAAU,cAAc,MAAM,MAAM;AAAA,IAC/D,OAAO,IAAI,GAAG,KAAK;AAAA,EACpB;AAAA,EACA,MAAM,QAAQ,OAAO,MAAM,UAAU,cAAc,MAAM,SAAS;AAAA,EAClE,MAAM,OAAO,QAAQ,KAAK,WAAW,IAAI,IACtC,kBAAkB,KAAK,QAAQ,IAAI,IACnC,cAAc,MAAM,QAAQ,YAAY,UAAU,WAAW,OAAO;AAAA,EACvE,OAAO,IAAI,GAAG,SAAS,OAAO,IAAI,CAAC;AAAA;AAIpC,SAAS,MAAM,CACd,MACA,cACA,QACA,SACS;AAAA,EACT,IAAI,QAAQ;AAAA,EACZ,WAAW,aAAa,aAAa,YAAY;AAAA,IAChD,IAAI,UAAU,SAAS,SAAS;AAAA,MAC/B,MAAM,OAAO,UAAU,KAAK;AAAA,MAC5B,IAAI,SAAS;AAAA,QAAc;AAAA,MAC3B,IAAI,oBAAoB,IAAI,KAAK,KAAK;AAAA,QAAqB;AAAA,MAC3D,MAAM,aAAa,QAAQ,MAAM,QAAQ,IAAI;AAAA,MAE7C,IAAI,CAAC;AAAA,QAAY;AAAA,MACjB,QAAQ,IACP,OACA,UAAU,MAAM,QAAQ,WAAW,YAAY,OAAO,CACvD;AAAA,IACD,EAAO,SAAI,UAAU,SAAS,kBAAkB;AAAA,MAC/C,MAAM,YAAY,UAAU,gBACzB,KAAK,OAAO,QAAQ,UAAU,cAAc,KAAK,KAAK,IACtD;AAAA,MACH,QAAQ,IACP,OACA,OAAO,MAAM,UAAU,cAAc,WAAW,OAAO,CACxD;AAAA,IACD,EAAO;AAAA,MACN,QAAQ,IAAI,OAAO,aAAa,MAAM,UAAU,KAAK,OAAO,OAAO,CAAC;AAAA;AAAA,EAEtE;AAAA,EACA,OAAO;AAAA;AAIR,SAAS,YAAY,CACpB,MACA,MACA,SACS;AAAA,EACT,MAAM,MAAM,CAAC,UACZ,SAAS,OAAO,OAAO,KAAK;AAAA,EAC7B,OAAO,cAAc,MAAM,MAAM,KAAK,CAAC,UAAU,OAChD,OACC,MACA,SAAS,cACT,KAAK,OAAO,QAAQ,SAAS,cAAc,KAAK,KAAK,GACrD,OAAO,aAAa,YAAY,EACjC,CACD;AAAA;AAyDM,SAAS,WAAW,CAAC,SAA6C;AAAA,EACxE,QAAQ,QAAQ,iBAAiB;AAAA,EAGjC,MAAM,gBAAgB,OAAO,OAAO;AAAA,IACnC,GAAI,QAAQ,iBAAiB;AAAA,EAC9B,CAAC;AAAA,EACD,cAAc,uBAAuB,QAAQ,CAAC;AAAA,EAC9C,cAAc,6BAA6B,cAAc,CAAC;AAAA,EAC1D,QAAQ,iBAAiB;AAAA,EACzB,IAAI,iBAAiB,WAAW;AAAA,IAC/B,cAAc,6BAA6B,cAAc,CAAC;AAAA,EAC3D;AAAA,EAEA,OAAO,CAAC,YAA+B;AAAA,IACtC,MAAM,SAAS,QAAQ,UAAU;AAAA,IACjC,MAAM,OAAoB;AAAA,MACzB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,qBAAqB,QAAQ,uBAAuB;AAAA,SACjD,gBAAgB,CAAC,SAAS,QAAQ,YAAY,IAAI,CAAC;AAAA,IACvD;AAAA,IACA,OAAO;AAAA,MACN,mBAAmB,CAAC,WAAW;AAAA,QAC9B,MAAM,QAAQ,OACb,MACA,UAAU,cACV,SAAS,QAAQ,SAAS,GAC1B,SACD;AAAA,QACA,IAAI,QAAQ,QAAQ;AAAA,UACnB,QAAQ,YACP,IAAI,cACH,GAAG,eAAe,SAAS,WAAW,wBAAwB,kBAC9D;AAAA,YACC,OAAO,CAAC,SAAS;AAAA,YACjB,YAAY;AAAA,cACX,MAAM;AAAA,cACN,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,UACD,CACD,CACD;AAAA,QACD;AAAA,QACA,OAAO;AAAA;AAAA,IAET;AAAA;AAAA;;AMxNF;AAmHO,SAAS,SAKf,CACA,QACA,SAWC;AAAA,EACD,MAAM,QAAQ,OAAO,WAAW,aAAa,YAAY,MAAM,MAAM;AAAA,EACrE,OAAO,OAAO,QAAQ,MAAM,SAAS,SAAoC;AAAA,IACxE,MAAM,QAAQ,GAAG,KAAK,WAAW,QAAQ,KAAK;AAAA,IAC9C,MAAM,UACL,SACA,MAAM,MAAO,OAAsC,SAAS,IAAI,CAAC;AAAA,IAClE,MAAM,SAAU,MAAM,UAAU,SAAS,MAAM,KAAK;AAAA,IAGpD,OAAO,MAAM,QAAQ,QAAQ,QAAQ,SAAS,IAAI;AAAA;AAAA;AAKpD,SAAS,KAAK,CAAC,QAA+B;AAAA,EAE7C,OACC,UAAU,SAAS,SAAS,EAAE,OAAO,MAAuB;AAAA;;ACxJ9D;AAAA;AAAA;AAaA,IAAM,UAAU,OAAO,IAAI,kCAAkC;AAE7D,IAAM,cAAc,OAAO,IAAI,kCAAkC;AAiBjE,SAAS,QAAQ,CAChB,QACA,OACA,SACA,cACW;AAAA,EACX,MAAM,QAAkB,OAAO,QAAQ,MAAM,SAAS,SACrD,MAAM,QACL,QACA,MAAM,UAAU,QAAQ,MAAM,OAAO,YAAY,GACjD,SACA,IACD;AAAA,EACD,MAAM,WAAW;AAAA,EACjB,OAAO;AAAA;AASR,SAAS,IAAI,CACZ,OACA,MACA,OACA,cACA,cACO;AAAA,EACP,MAAM,YAAa,MAAM,cACvB,eAAe,uBAAuB;AAAA,EACxC,IAAI,WAAW;AAAA,IACd,IAAI,CAAC,UAAU;AAAA,MACd,MAAM,YAAY,SAAS,MAAM,OAAO,WAAW,YAAY;AAAA,IAChE;AAAA,EACD;AAAA,EACA,MAAM,UAAW,MAAM,WAAW;AAAA,EAClC,IAAI,CAAC,QAAQ;AAAA,IACZ,MAAM,UAAU,SAAS,MAAM,OAAO,SAAS,YAAY;AAAA;AA+BtD,SAAS,cAIf,CAAC,QAAW,UAAoC,CAAC,GAAM;AAAA,EACvD,MAAM,UAAyB,QAAQ,WAAW,CAAC;AAAA,EACnD,MAAM,SAAS;AAAA,EACf,MAAM,SAAS,OAAO;AAAA,EACtB,IAAI,UAAU,CAAC,YAAY,QAAQ,OAAO,GAAG;AAAA,IAC5C,MAAM,IAAI,MACT,iHACD;AAAA,EACD;AAAA,EACA,MAAM,YAAY,kBACjB,QACA,CAAC,MAAM,OAAO,MAAM,aAAa;AAAA,IAChC,MAAM,eAAe,SAAS,OAAO,oBAAoB;AAAA,IAEzD,MAAM,QAAsB,CAAC,UAAU;AAAA,MACtC,MAAM,WAAW,aAAa,KAAK;AAAA,MACnC,IAAI,CAAC;AAAA,QAAU;AAAA,MAGf,MAAM,QAAQ,SAAS,MAAM,IAAI,EAAE,KAClC,GAAG,WAAW,KAAK,aAAa,QACjC;AAAA,MACA,OAAO,SAAS,EAAE,UAAU,OAAO,MAAM,MAAM;AAAA;AAAA,IAEhD,KAAK,OAAO,MAAM,GAAG,KAAK,QAAQ,MAAM,QAAQ,cAAc,KAAK;AAAA,KAEpE,OACD;AAAA,EACA,IAAI,CAAC,WAAW;AAAA,IACf,MAAM,IAAI,MACT,gHACD;AAAA,EACD;AAAA,EACA,IAAI,CAAC;AAAA,IAAQ,OAAO,eAAe,QAAQ,aAAa,EAAE,OAAO,QAAQ,CAAC;AAAA,EAC1E,OAAO;AAAA;AAIR,SAAS,WAAW,CAAC,GAAkB,GAA2B;AAAA,EACjE,MAAM,QAAQ,OAAO,KAAK,CAAC;AAAA,EAC3B,OACC,MAAM,WAAW,OAAO,KAAK,CAAC,EAAE,UAChC,MAAM,MAAM,CAAC,SAAS,OAAO,OAAO,GAAG,IAAI,KAAK,EAAE,UAAU,EAAE,KAAK;AAAA;",
|
|
23
|
+
"debugId": "B1856E23719B140164756E2164756E21",
|
|
21
24
|
"names": []
|
|
22
25
|
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type GraphQLField, type GraphQLNamedType, type GraphQLSchema, type OperationDefinitionNode } from 'graphql';
|
|
2
|
+
import { type FragmentWalk } from './fragments.js';
|
|
2
3
|
import type { SizeContext } from './list-size.js';
|
|
3
|
-
export declare const add: (a: number, b: number) => number;
|
|
4
4
|
export declare const multiply: (a: number, b: number) => number;
|
|
5
5
|
/** What a walk of one document needs: the options, and what it has measured so far. */
|
|
6
|
-
export interface CostContext extends SizeContext {
|
|
6
|
+
export interface CostContext extends SizeContext, FragmentWalk {
|
|
7
7
|
ignoreIntrospection: boolean;
|
|
8
|
-
getFragment: (name: string) => FragmentDefinitionNode | null | undefined;
|
|
9
|
-
fragmentCosts: Map<string, Map<number, number>>;
|
|
10
|
-
costing: Set<string>;
|
|
11
8
|
}
|
|
12
9
|
/** The definition of the field `name` on `parent`, meta-fields of the query root included. */
|
|
13
10
|
export declare function fieldOf(cost: CostContext, parent: GraphQLNamedType | undefined, name: string): GraphQLField<unknown, unknown> | undefined;
|
|
14
11
|
/** The type an operation selects on. */
|
|
15
12
|
export declare function rootType(schema: GraphQLSchema, operation: OperationDefinitionNode): import("graphql").GraphQLObjectType<any, any> | undefined;
|
|
16
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* The key a fragment is memoized under when no size is pending: the walk's own
|
|
15
|
+
* "no key", which no real size can equal (a size is never negative).
|
|
16
|
+
*/
|
|
17
17
|
export declare const NO_PENDING = -1;
|
|
18
18
|
/**
|
|
19
19
|
* The pending size a fragment is costed under. A fragment spread under many
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cost-context.d.ts","sourceRoot":"","sources":["../../src/limits/cost-context.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,
|
|
1
|
+
{"version":3,"file":"cost-context.d.ts","sourceRoot":"","sources":["../../src/limits/cost-context.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAGlB,KAAK,uBAAuB,EAC5B,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,KAAK,YAAY,EAAU,MAAM,aAAa,CAAC;AAExD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,eAAO,MAAM,QAAQ,GAAI,GAAG,MAAM,EAAE,GAAG,MAAM,WAA6B,CAAC;AAE3E,uFAAuF;AACvF,MAAM,WAAW,WAAY,SAAQ,WAAW,EAAE,YAAY;IAC7D,mBAAmB,EAAE,OAAO,CAAC;CAC7B;AAED,8FAA8F;AAC9F,wBAAgB,OAAO,CACtB,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,gBAAgB,GAAG,SAAS,EACpC,IAAI,EAAE,MAAM,GACV,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,SAAS,CAO5C;AAED,wCAAwC;AACxC,wBAAgB,QAAQ,CACvB,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,uBAAuB,6DASlC;AAKD;;;GAGG;AACH,eAAO,MAAM,UAAU,KAAS,CAAC;AAEjC;;;;;;GAMG;AACH,wBAAgB,QAAQ,CACvB,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAClC,OAAO,EAAE,MAAM,GAAG,SAAS,GACzB,MAAM,GAAG,SAAS,CAQpB"}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
import type { OperationDefinitionNode } from 'graphql';
|
|
2
|
+
/** Costs and counts are plain numbers, held below this so a hostile query never reaches `Infinity`. */
|
|
3
|
+
export declare const CEILING: number;
|
|
4
|
+
/** `a + b`, clamped where a number stops being exact. */
|
|
5
|
+
export declare const add: (a: number, b: number) => number;
|
|
2
6
|
/** `Operation "Name"`, or `Operation` for an anonymous one. */
|
|
3
7
|
export declare function operationLabel(operation: OperationDefinitionNode): string;
|
|
4
8
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"describe.d.ts","sourceRoot":"","sources":["../../src/limits/describe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAEvD,+DAA+D;AAC/D,wBAAgB,cAAc,CAAC,SAAS,EAAE,uBAAuB,GAAG,MAAM,CAEzE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC5B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,GAAG,
|
|
1
|
+
{"version":3,"file":"describe.d.ts","sourceRoot":"","sources":["../../src/limits/describe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAEvD,uGAAuG;AACvG,eAAO,MAAM,OAAO,QAA0B,CAAC;AAE/C,yDAAyD;AACzD,eAAO,MAAM,GAAG,GAAI,GAAG,MAAM,EAAE,GAAG,MAAM,WAA6B,CAAC;AAEtE,+DAA+D;AAC/D,wBAAgB,cAAc,CAAC,SAAS,EAAE,uBAAuB,GAAG,MAAM,CAEzE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC5B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,GAAG,SAAU,GACX,IAAI,CAMN"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { FragmentDefinitionNode } from 'graphql';
|
|
2
|
+
/** The key of a fragment whose value does not depend on anything but its name. */
|
|
3
|
+
export declare const NO_KEY = -1;
|
|
4
|
+
/** What the fragment walk of one document keeps: the fragments, and what each was worth. */
|
|
5
|
+
export interface FragmentWalk {
|
|
6
|
+
getFragment: (name: string) => FragmentDefinitionNode | null | undefined;
|
|
7
|
+
values: Map<string, Map<number, number>>;
|
|
8
|
+
visiting: Set<string>;
|
|
9
|
+
}
|
|
10
|
+
/** An empty walk over the fragments of one document. */
|
|
11
|
+
export declare function newFragmentWalk(getFragment: FragmentWalk['getFragment']): FragmentWalk;
|
|
12
|
+
/**
|
|
13
|
+
* The value of the named fragment under `key`, computed once. `key` is a number,
|
|
14
|
+
* or a function of what is already known for this fragment (`maxListCost` rounds
|
|
15
|
+
* its pending size by it). A fragment reached while it is being computed is a
|
|
16
|
+
* cycle, NoFragmentCyclesRule's to report: its back-edge adds nothing (0).
|
|
17
|
+
*/
|
|
18
|
+
export declare function fragmentValue(walk: FragmentWalk, name: string, key: number | ((known: ReadonlyMap<number, number>) => number), compute: (fragment: FragmentDefinitionNode, key: number) => number): number;
|
|
19
|
+
//# sourceMappingURL=fragments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fragments.d.ts","sourceRoot":"","sources":["../../src/limits/fragments.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAEtD,kFAAkF;AAClF,eAAO,MAAM,MAAM,KAAK,CAAC;AAEzB,4FAA4F;AAC5F,MAAM,WAAW,YAAY;IAC5B,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,sBAAsB,GAAG,IAAI,GAAG,SAAS,CAAC;IACzE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACzC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACtB;AAED,wDAAwD;AACxD,wBAAgB,eAAe,CAC9B,WAAW,EAAE,YAAY,CAAC,aAAa,CAAC,GACtC,YAAY,CAEd;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC5B,IAAI,EAAE,YAAY,EAClB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,MAAM,CAAC,EAC9D,OAAO,EAAE,CAAC,QAAQ,EAAE,sBAAsB,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,GAChE,MAAM,CAgBR"}
|
|
@@ -4,6 +4,8 @@ export interface SizeContext {
|
|
|
4
4
|
schema: GraphQLSchema;
|
|
5
5
|
sizeArguments: readonly string[];
|
|
6
6
|
defaultFirst: number;
|
|
7
|
+
/** What to assume for a size argument given as a variable where some definition declares no bound. */
|
|
8
|
+
variableSize?: number | undefined;
|
|
7
9
|
}
|
|
8
10
|
/**
|
|
9
11
|
* The size `definition` states on `parent`, as selected by `args`: the largest
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list-size.d.ts","sourceRoot":"","sources":["../../src/limits/list-size.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,aAAa,
|
|
1
|
+
{"version":3,"file":"list-size.d.ts","sourceRoot":"","sources":["../../src/limits/list-size.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAElB,MAAM,SAAS,CAAC;AAGjB,wEAAwE;AACxE,MAAM,WAAW,WAAW;IAC3B,MAAM,EAAE,aAAa,CAAC;IACtB,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,sGAAsG;IACtG,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAyHD;;;;;;;GAOG;AACH,wBAAgB,UAAU,CACzB,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,gBAAgB,GAAG,SAAS,EACpC,UAAU,EAAE,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,EAC1C,IAAI,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,GACvC,MAAM,GAAG,SAAS,CAepB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAC1B,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,gBAAgB,GAAG,SAAS,EACpC,UAAU,EAAE,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,GACxC,KAAK,GAAG,MAAM,GAAG,MAAM,CAIzB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"max-depth.d.ts","sourceRoot":"","sources":["../../src/limits/max-depth.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"max-depth.d.ts","sourceRoot":"","sources":["../../src/limits/max-depth.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,KAAK,cAAc,EACnB,MAAM,SAAS,CAAC;AAUjB,mCAAmC;AACnC,MAAM,WAAW,eAAe;IAC/B,kFAAkF;IAClF,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAoCD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,cAAc,CA0BjE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"max-fields.d.ts","sourceRoot":"","sources":["../../src/limits/max-fields.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"max-fields.d.ts","sourceRoot":"","sources":["../../src/limits/max-fields.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,KAAK,cAAc,EACnB,MAAM,SAAS,CAAC;AAUjB,oCAAoC;AACpC,MAAM,WAAW,gBAAgB;IAChC,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAiCD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,cAAc,CA0BnE"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** Options of `maxListCost`. */
|
|
2
|
+
export interface MaxListCostOptions {
|
|
3
|
+
/** The most an operation may cost (at least 0). */
|
|
4
|
+
budget: number;
|
|
5
|
+
/** The size of a list field whose size cannot be read (an integer of at least 0). */
|
|
6
|
+
defaultFirst: number;
|
|
7
|
+
/**
|
|
8
|
+
* The argument names that size a list. Each one given, or defaulted in the
|
|
9
|
+
* SDL, says a size (an Int, a canonical-integer string or an integral Float)
|
|
10
|
+
* and the largest wins. Default `['first', 'last', 'limit']`. One on a
|
|
11
|
+
* non-list field also sizes the lists declaring none directly on its return
|
|
12
|
+
* type (a Relay connection's `edges` and `nodes`).
|
|
13
|
+
*/
|
|
14
|
+
sizeArguments?: readonly string[];
|
|
15
|
+
/**
|
|
16
|
+
* Do not cost `__schema` and `__type` (default `false`). Only where
|
|
17
|
+
* introspection is disabled or the client is trusted, e.g. GraphiQL in
|
|
18
|
+
* development: the standard introspection query is costly (on the order of
|
|
19
|
+
* 200,000 on a one-field schema).
|
|
20
|
+
*/
|
|
21
|
+
ignoreIntrospection?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* What to assume for a size argument the client sends as a variable (or
|
|
24
|
+
* writes as an unusable literal): an integer of at least 0. Validation has
|
|
25
|
+
* no variable values, and the client may send any value the argument
|
|
26
|
+
* accepts, so such a size counts as the largest of its SDL default (else
|
|
27
|
+
* `defaultFirst`), its declared bound (`@constraint(max)` or `exclusiveMax`)
|
|
28
|
+
* and, where some definition declares no bound, this. It applies to every
|
|
29
|
+
* size argument. A declared bound wins over this option only when every
|
|
30
|
+
* definition declares one (the interface's field and each possible type's);
|
|
31
|
+
* if any lacks one, this applies too and the largest wins. A code-first
|
|
32
|
+
* argument has no SDL node, so only this applies to it. The operation's own
|
|
33
|
+
* variable default is ignored. Default: none.
|
|
34
|
+
*/
|
|
35
|
+
variableSize?: number;
|
|
36
|
+
}
|
|
37
|
+
export declare const DEFAULT_SIZE_ARGUMENTS: readonly ["first", "last", "limit"];
|
|
38
|
+
//# sourceMappingURL=max-list-cost-options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"max-list-cost-options.d.ts","sourceRoot":"","sources":["../../src/limits/max-list-cost-options.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,MAAM,WAAW,kBAAkB;IAClC,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,qFAAqF;IACrF,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;;;;;;;OAYG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,sBAAsB,qCAAsC,CAAC"}
|
|
@@ -1,26 +1,6 @@
|
|
|
1
1
|
import { type ValidationRule } from 'graphql';
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
/** The most an operation may cost (at least 0). */
|
|
5
|
-
budget: number;
|
|
6
|
-
/** The size of a list field whose size cannot be read (an integer of at least 0). */
|
|
7
|
-
defaultFirst: number;
|
|
8
|
-
/**
|
|
9
|
-
* The argument names that size a list. Each one given, or defaulted in the
|
|
10
|
-
* SDL, says a size (an Int, a canonical-integer string or an integral Float)
|
|
11
|
-
* and the largest wins. Default `['first', 'last', 'limit']`. One on a
|
|
12
|
-
* non-list field also sizes the lists declaring none directly on its return
|
|
13
|
-
* type (a Relay connection's `edges` and `nodes`).
|
|
14
|
-
*/
|
|
15
|
-
sizeArguments?: readonly string[];
|
|
16
|
-
/**
|
|
17
|
-
* Do not cost `__schema` and `__type` (default `false`). Only where
|
|
18
|
-
* introspection is disabled or the client is trusted, e.g. GraphiQL in
|
|
19
|
-
* development: the standard introspection query is costly (on the order of
|
|
20
|
-
* 200,000 on a one-field schema).
|
|
21
|
-
*/
|
|
22
|
-
ignoreIntrospection?: boolean;
|
|
23
|
-
}
|
|
2
|
+
import { type MaxListCostOptions } from './max-list-cost-options.js';
|
|
3
|
+
export type { MaxListCostOptions };
|
|
24
4
|
/**
|
|
25
5
|
* A graphql-js validation rule refusing an operation whose cost is more than
|
|
26
6
|
* `budget`, to stop a client from exploiting list cycles (`Folder.items`,
|
|
@@ -38,13 +18,15 @@ export interface MaxListCostOptions {
|
|
|
38
18
|
* `first`, `last`, `limit`) say. A literal Int, a String holding a canonical
|
|
39
19
|
* integer (`"1000"`) or an integral Float (`1e3`) of at least 0 says that
|
|
40
20
|
* number. Anything else (a negative literal, a variable, since validation has
|
|
41
|
-
* no variable values) says the argument's SDL default when it
|
|
42
|
-
* `defaultFirst` otherwise
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
21
|
+
* no variable values) says the largest of the argument's SDL default when it
|
|
22
|
+
* has a usable one (`defaultFirst` otherwise), its declared bound
|
|
23
|
+
* (`@constraint(max)` or `exclusiveMax`) and, when some definition declares no
|
|
24
|
+
* bound, `variableSize`; an argument not given says its SDL default, or
|
|
25
|
+
* nothing. When nothing is said the size is `defaultFirst`. On an interface
|
|
26
|
+
* the largest default and bound over its possible types is used. Hence no
|
|
27
|
+
* subtree ever costs less than nothing: a negative `first` on one field cannot
|
|
28
|
+
* cancel the cost of its sibling. A field whose type (once unwrapped from
|
|
29
|
+
* non-null) is a list is one list, nested `[[X]]` included.
|
|
48
30
|
*
|
|
49
31
|
* A Relay connection puts the size on a field returning an object, with the
|
|
50
32
|
* list below it (`items(first: 100) { edges { node { id } } }`). A field that
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"max-list-cost.d.ts","sourceRoot":"","sources":["../../src/limits/max-list-cost.ts"],"names":[],"mappings":"AAAA,OAAO,EAUN,KAAK,cAAc,EACnB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"max-list-cost.d.ts","sourceRoot":"","sources":["../../src/limits/max-list-cost.ts"],"names":[],"mappings":"AAAA,OAAO,EAUN,KAAK,cAAc,EACnB,MAAM,SAAS,CAAC;AAajB,OAAO,EAEN,KAAK,kBAAkB,EACvB,MAAM,yBAAyB,CAAC;AAGjC,YAAY,EAAE,kBAAkB,EAAE,CAAC;AAoFnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,cAAc,CAmDvE"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { GraphQLArgument, ValueNode } from 'graphql';
|
|
2
|
+
/**
|
|
3
|
+
* The one reading of a size, wherever it comes from (a literal, a default): a
|
|
4
|
+
* non-negative integral number or bigint, or a canonical-integer string,
|
|
5
|
+
* clamped to the ceiling. Anything else says nothing.
|
|
6
|
+
*/
|
|
7
|
+
export declare function sizeOf(value: unknown): number | undefined;
|
|
8
|
+
/** The size a literal gives: an Int, a canonical-integer String or an integral Float (`1e3`). */
|
|
9
|
+
export declare function literalSize(value: ValueNode): number | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* An argument's SDL default as a size. graphql 16 holds it as `defaultValue`;
|
|
12
|
+
* graphql 17 as `default`, `{ value }` or `{ literal }`.
|
|
13
|
+
*/
|
|
14
|
+
export declare function defaultSizeOf(argument: object | undefined): number | undefined;
|
|
15
|
+
/**
|
|
16
|
+
* The bound of an argument's `@constraint` directive, as a size: what the
|
|
17
|
+
* client may send at most. The largest of `max` and `exclusiveMax` (the value
|
|
18
|
+
* itself, a slight over-count), a fractional one rounded up. Read from the SDL
|
|
19
|
+
* node, so a code-first argument (no `astNode`) declares none.
|
|
20
|
+
*/
|
|
21
|
+
export declare function constraintMaxOf(argument: GraphQLArgument | undefined): number | undefined;
|
|
22
|
+
//# sourceMappingURL=size-reading.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"size-reading.d.ts","sourceRoot":"","sources":["../../src/limits/size-reading.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAK1D;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAczD;AAED,iGAAiG;AACjG,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,SAAS,CAKhE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC5B,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC1B,MAAM,GAAG,SAAS,CAiBpB;AAeD;;;;;GAKG;AACH,wBAAgB,eAAe,CAC9B,QAAQ,EAAE,eAAe,GAAG,SAAS,GACnC,MAAM,GAAG,SAAS,CAepB"}
|
|
@@ -102,7 +102,7 @@ The refusal:
|
|
|
102
102
|
`depth` is the operation's real depth. An anonymous operation reads
|
|
103
103
|
`Operation is 9 levels deep, ...`.
|
|
104
104
|
|
|
105
|
-
## `maxListCost({ budget, defaultFirst, sizeArguments?, ignoreIntrospection? })`
|
|
105
|
+
## `maxListCost({ budget, defaultFirst, sizeArguments?, ignoreIntrospection?, variableSize? })`
|
|
106
106
|
|
|
107
107
|
### How cost is counted
|
|
108
108
|
|
|
@@ -149,31 +149,59 @@ argument says:
|
|
|
149
149
|
| a bigint (an SDL default held by a code-first schema, or after graphql-tools' `mapSchema`) | that number |
|
|
150
150
|
| an integral Float literal (`first: 1000.0`, `first: 1e3`) | that number; `1.5` and `-1000.0` are unusable |
|
|
151
151
|
| a negative literal (`first: -1000`), another string | as if unusable, see below |
|
|
152
|
-
| a variable (`first: $n`) | as if unusable: validation has no variable values |
|
|
152
|
+
| a variable (`first: $n`) | as if unusable, see below: validation has no variable values |
|
|
153
153
|
| not given | its SDL default, when it has one; else nothing |
|
|
154
154
|
|
|
155
155
|
An SDL default is read the same way: `limit: String = "1000"` and `first:
|
|
156
156
|
Float = 1000.0` are sizes of 1000. Every size is held at most
|
|
157
157
|
`Number.MAX_SAFE_INTEGER`.
|
|
158
158
|
|
|
159
|
-
An argument given but unusable
|
|
160
|
-
any accepted form (`items(first:
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
field where no size argument says anything is
|
|
159
|
+
An argument given but unusable (a negative number, a variable) counts for the
|
|
160
|
+
largest of its SDL default when it has one in any accepted form (`items(first:
|
|
161
|
+
Int = 100)`, else `defaultFirst`), its declared bound (`@constraint(max)` or
|
|
162
|
+
`exclusiveMax`) and, where some definition declares no bound, `variableSize`:
|
|
163
|
+
see [Variables](#variables). A field where no size argument says anything is
|
|
164
|
+
sized `defaultFirst`.
|
|
164
165
|
|
|
165
166
|
On an interface or a union, the default is the **largest** over the interface's
|
|
166
167
|
field and the field of every possible type (`Node.kids(first: Int = 1)` next to
|
|
167
168
|
`Folder.kids(first: Int = 100000)` is sized 100,000), since the query cannot
|
|
168
|
-
say which object comes back
|
|
169
|
+
say which object comes back; `defaultFirst` counts too when it is larger and
|
|
170
|
+
some possible type has no default.
|
|
169
171
|
|
|
170
172
|
A negative number is therefore never taken as a size: no subtree costs less than
|
|
171
173
|
nothing, and `items(first: -1000)` next to an expensive sibling cannot cancel
|
|
172
174
|
the sibling's cost.
|
|
173
175
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
176
|
+
### Variables
|
|
177
|
+
|
|
178
|
+
The client can send any value the argument accepts, so a size given as a
|
|
179
|
+
variable (or as an unusable literal) counts as the **largest** of:
|
|
180
|
+
|
|
181
|
+
- its SDL default, else `defaultFirst`: never less than that;
|
|
182
|
+
- the bound of the argument's `@constraint` (the directive `withValidation`
|
|
183
|
+
enforces), read from the schema's SDL: `first: Int = 20 @constraint(max: 100)`
|
|
184
|
+
counts 100 for `first: $n`. `exclusiveMax` is read the same way (the value
|
|
185
|
+
itself, a slight over-count), a fractional bound is rounded up (`max: 100.5`
|
|
186
|
+
counts 101), and the largest of `max` and `exclusiveMax` counts. On an
|
|
187
|
+
interface it is the largest over the interface's field and each possible
|
|
188
|
+
type's field;
|
|
189
|
+
- `variableSize`, where some definition declares no bound:
|
|
190
|
+
`maxListCost({ budget, defaultFirst, variableSize: 100 })` for a server that
|
|
191
|
+
caps every page at 100 in its resolvers. It applies to every size argument
|
|
192
|
+
(`first`, `last`, `limit`, your own `sizeArguments`) and to unusable
|
|
193
|
+
literals. A declared bound wins over it only when every definition (the
|
|
194
|
+
interface's field and each possible type's) declares one; if any lacks one,
|
|
195
|
+
`variableSize` applies too and the largest wins.
|
|
196
|
+
|
|
197
|
+
```graphql
|
|
198
|
+
query ($n: Int) { wards(first: $n) { edges { node { rooms(first: $n) { id } } } } }
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
With `first: Int = 20 @constraint(max: 100)` on both fields, that query is
|
|
202
|
+
costed as the same one written with `first: 100`, not with the defaults. The
|
|
203
|
+
operation's own variable default (`query ($n: Int = 5)`) is ignored: the client
|
|
204
|
+
can override it. An argument not given at all keeps its SDL default.
|
|
177
205
|
|
|
178
206
|
### Relay connections
|
|
179
207
|
|
|
@@ -209,7 +237,7 @@ selected **directly on its return type**:
|
|
|
209
237
|
- A connection field that states nothing (no size argument given, none declared
|
|
210
238
|
with a default) hands down nothing: its lists are sized `defaultFirst`, as
|
|
211
239
|
before. A variable, a negative number or an unusable value on it counts as for
|
|
212
|
-
a list
|
|
240
|
+
a list, see [Variables](#variables).
|
|
213
241
|
- The rule is structural: any non-list field stating a size sizes the lists
|
|
214
242
|
declaring no size argument directly on its return type, whether or not it is
|
|
215
243
|
a connection. `user(limit: 0) { friends { … } }` sizes `friends` 0. So an
|
|
@@ -243,7 +271,7 @@ never underestimated.
|
|
|
243
271
|
}
|
|
244
272
|
```
|
|
245
273
|
|
|
246
|
-
`budget` and `
|
|
274
|
+
`budget`, `defaultFirst` and `variableSize` must be integers below `Number.MAX_SAFE_INTEGER`
|
|
247
275
|
(a cost never exceeds it, so a budget at or over it would refuse nothing); the
|
|
248
276
|
rule throws a `RangeError` otherwise.
|
|
249
277
|
|
|
@@ -301,6 +329,11 @@ two: `maxDepth` bounds nesting, `maxListCost` bounds list multiplication, and
|
|
|
301
329
|
|
|
302
330
|
## Not covered
|
|
303
331
|
|
|
332
|
+
- A code-first argument has no SDL node, hence no declared bound: only
|
|
333
|
+
`variableSize` applies to a variable on it.
|
|
334
|
+
- A size bounded only by a custom scalar (`first: PageSize`) or by `maxItems`
|
|
335
|
+
or `maxLength` counts as having no bound: declare `@constraint(max)` on the
|
|
336
|
+
argument.
|
|
304
337
|
- A size carried inside an input object (`items(page: { first: 1000 })`) is not
|
|
305
338
|
read: the field has no size argument, so it is sized `defaultFirst`. Name the
|
|
306
339
|
size as an argument, or raise `defaultFirst`.
|
package/docs/roadmap.md
CHANGED
|
@@ -21,6 +21,12 @@ Nothing planned yet.
|
|
|
21
21
|
- **Relay connection sizing** — `maxListCost` sizes the `edges` and `nodes` of
|
|
22
22
|
a connection from the connection field's size argument (`items(first: 100)
|
|
23
23
|
{ edges { … } }`), not `defaultFirst`.
|
|
24
|
+
- **Variable sizes counted at their bound** — `maxListCost` counts a size sent
|
|
25
|
+
as a variable (or an unusable literal) at the argument's declared bound
|
|
26
|
+
(`@constraint(max)` or `exclusiveMax`) and the new `variableSize` option. The
|
|
27
|
+
bound wins only when every definition declares one, and never counts below the
|
|
28
|
+
SDL default or `defaultFirst`, so a query cannot hide a large page behind a
|
|
29
|
+
variable.
|
|
24
30
|
- **Query depth, cost and breadth limits** — `maxDepth`, `maxListCost` and
|
|
25
31
|
`maxFields` are graphql-js validation rules (also for graphql-yoga's
|
|
26
32
|
`addValidationRule`) that refuse a query nested too deep, too costly for a
|
package/docs/troubleshooting.md
CHANGED
|
@@ -425,14 +425,18 @@ reads `Operation is 9 levels deep, ...`.
|
|
|
425
425
|
**When:** an operation is validated with `maxListCost({ budget: 1000, ... })`.
|
|
426
426
|
**Why:** `extensions` is `{ code: 'QUERY_TOO_COSTLY', cost: 5002, limit: 1000 }`.
|
|
427
427
|
Each field costs 1, times the sizes of the lists enclosing it. A list without a
|
|
428
|
-
usable `first`
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
428
|
+
usable `first` counts for its SDL default, else `defaultFirst`; a variable or
|
|
429
|
+
a negative number counts for the largest of that, the declared bound and
|
|
430
|
+
`variableSize`, so a query that is cheap with the variable's real value can
|
|
431
|
+
still be refused, see [Variables](guide/query-limits.md#variables). A size
|
|
432
|
+
argument on a field returning an object (a connection's `first`) sizes its
|
|
433
|
+
`edges` and `nodes`, and any non-list field stating a size sizes the lists
|
|
434
|
+
declaring none directly under it, see
|
|
433
435
|
[Relay connections](guide/query-limits.md#relay-connections).
|
|
434
|
-
|
|
435
|
-
|
|
436
|
+
|
|
437
|
+
**Fix:** ask for fewer items with a literal `first`, lower the `@constraint(max)`
|
|
438
|
+
of a size argument, or raise `budget`. A query on an interface or a union is
|
|
439
|
+
overestimated (every branch is summed).
|
|
436
440
|
|
|
437
441
|
### `Operation "Name" selects 4000 fields, more than the 500 allowed`
|
|
438
442
|
|
|
@@ -468,6 +472,17 @@ budget at or over it would refuse nothing.
|
|
|
468
472
|
**When:** `defaultFirst` is negative, fractional or too large.
|
|
469
473
|
**Fix:** pass the size to assume for a list with no usable size argument.
|
|
470
474
|
|
|
475
|
+
### `maxListCost: variableSize must be an integer from 0 to 9007199254740990.`
|
|
476
|
+
|
|
477
|
+
**When:** `variableSize` is negative, fractional or too large.
|
|
478
|
+
**Why:** it is the size assumed for a variable or unusable size argument, and
|
|
479
|
+
a size is an integer from 0 up to a bound a cost cannot overflow.
|
|
480
|
+
**Fix:** pass an integer in range, such as the page cap of your resolvers:
|
|
481
|
+
|
|
482
|
+
```ts
|
|
483
|
+
maxListCost({ budget: 10_000, defaultFirst: 50, variableSize: 100 });
|
|
484
|
+
```
|
|
485
|
+
|
|
471
486
|
### A query refused although its `first` is small, or an introspection query refused
|
|
472
487
|
|
|
473
488
|
**When:** `QUERY_TOO_COSTLY`, `QUERY_TOO_DEEP` or `QUERY_TOO_WIDE` for GraphiQL's schema fetch or
|
|
@@ -475,8 +490,10 @@ a codegen's introspection query.
|
|
|
475
490
|
**Why:** `__schema` is counted: the standard introspection query is 15 levels
|
|
476
491
|
deep, selects 220 fields and costs on the order of 200,000 on a one-field schema.
|
|
477
492
|
**Fix:** `ignoreIntrospection: true` on the rule where introspection is
|
|
478
|
-
disabled or the client is trusted. A `first: $n` variable counts for
|
|
479
|
-
|
|
493
|
+
disabled or the client is trusted. A `first: $n` variable counts for its
|
|
494
|
+
declared bound (`@constraint(max)` or `exclusiveMax`, when every definition
|
|
495
|
+
declares one) and `variableSize` otherwise, never below the SDL default or
|
|
496
|
+
`defaultFirst`, not for the value sent.
|
|
480
497
|
|
|
481
498
|
## The bin
|
|
482
499
|
|
package/package.json
CHANGED