@takeshape/schema 9.32.3 → 9.33.2
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/dist/schema-util.js +1 -1
- package/dist/types/types.d.ts +14 -1
- package/dist/types/types.d.ts.map +1 -1
- package/dist/validate.d.ts +15 -9
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +310 -180
- package/es/schema-util.js +1 -1
- package/es/validate.js +309 -183
- package/examples/dependencies/rick-and-morty-layer.json +575 -0
- package/examples/dependencies/shopify-layer-2023-01.json +86171 -0
- package/package.json +6 -5
package/dist/validate.js
CHANGED
|
@@ -3,13 +3,14 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.ensureValidLatestSchemaSyntax = ensureValidLatestSchemaSyntax;
|
|
7
7
|
exports.ensureValidProjectSchemaImport = ensureValidProjectSchemaImport;
|
|
8
8
|
exports.ensureValidRoleImport = ensureValidRoleImport;
|
|
9
9
|
exports.formatError = formatError;
|
|
10
10
|
exports.validateProjectSchemaImport = validateProjectSchemaImport;
|
|
11
11
|
exports.validateRoleInput = validateRoleInput;
|
|
12
12
|
exports.validateSchema = validateSchema;
|
|
13
|
+
exports.validateSchemaSyntax = validateSchemaSyntax;
|
|
13
14
|
|
|
14
15
|
var _types = require("./types/types");
|
|
15
16
|
|
|
@@ -79,8 +80,14 @@ var _isEqual = _interopRequireDefault(require("lodash/isEqual"));
|
|
|
79
80
|
|
|
80
81
|
var _pick = _interopRequireDefault(require("lodash/pick"));
|
|
81
82
|
|
|
83
|
+
var _pMap = _interopRequireDefault(require("p-map"));
|
|
84
|
+
|
|
85
|
+
var _lodash = require("lodash");
|
|
86
|
+
|
|
82
87
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
83
88
|
|
|
89
|
+
const builtInShapeNames = new Set([...Object.keys(_builtinSchema.builtInShapes), ..._scalars.scalars, 'object']);
|
|
90
|
+
|
|
84
91
|
function findDuplicates(items) {
|
|
85
92
|
const seen = {};
|
|
86
93
|
|
|
@@ -214,7 +221,24 @@ function getSemver(schemaVersion) {
|
|
|
214
221
|
return (0, _coerce2.default)(schemaVersion) ?? _versions.LEGACY_SCHEMA_VERSION;
|
|
215
222
|
}
|
|
216
223
|
|
|
217
|
-
function
|
|
224
|
+
function enumerateBasicResolvers(resolver, path) {
|
|
225
|
+
const results = [];
|
|
226
|
+
|
|
227
|
+
const visit = (resolver, path) => {
|
|
228
|
+
if ((0, _utils.isComposeResolver)(resolver)) {
|
|
229
|
+
resolver.compose.forEach((resolver, i) => {
|
|
230
|
+
visit(resolver, [...path, i]);
|
|
231
|
+
});
|
|
232
|
+
} else {
|
|
233
|
+
results.push([resolver, path]);
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
visit(resolver, path);
|
|
238
|
+
return results;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function validateResolver(projectSchema, basePath, baseResolver) {
|
|
218
242
|
const errors = [];
|
|
219
243
|
/**
|
|
220
244
|
* V3.9 Resolver name enums are the set used for earlier v3 validations
|
|
@@ -258,14 +282,14 @@ function validateResolver(projectSchema, basePath, resolver) {
|
|
|
258
282
|
const isLessThanV3_9_0 = (0, _lt.default)(getSemver(projectSchema.schemaVersion), '3.9.0');
|
|
259
283
|
const getNamespace = (0, _refs.createGetNamespace)(projectSchema);
|
|
260
284
|
|
|
261
|
-
const
|
|
285
|
+
for (const [resolver, path] of enumerateBasicResolvers(baseResolver, basePath)) {
|
|
262
286
|
if ((0, _utils.isBasicResolver)(resolver)) {
|
|
263
287
|
var _projectSchema$servic;
|
|
264
288
|
|
|
265
289
|
if ('service' in resolver && resolver.service !== 'takeshape:local' && !((_projectSchema$servic = projectSchema.services) !== null && _projectSchema$servic !== void 0 && _projectSchema$servic[resolver.service])) {
|
|
266
290
|
errors.push({
|
|
267
291
|
type: 'notFound',
|
|
268
|
-
path:
|
|
292
|
+
path: path.concat(['service']),
|
|
269
293
|
message: `Invalid service "${resolver.service}"`
|
|
270
294
|
});
|
|
271
295
|
}
|
|
@@ -273,7 +297,7 @@ function validateResolver(projectSchema, basePath, resolver) {
|
|
|
273
297
|
if (isLessThanV3_9_0 && !isValidResolverNameV3_9_0(resolver.name)) {
|
|
274
298
|
errors.push({
|
|
275
299
|
type: 'notFound',
|
|
276
|
-
path:
|
|
300
|
+
path: path.concat(['name']),
|
|
277
301
|
message: `Invalid resolver name "${resolver.name}"`
|
|
278
302
|
});
|
|
279
303
|
}
|
|
@@ -289,7 +313,7 @@ function validateResolver(projectSchema, basePath, resolver) {
|
|
|
289
313
|
if (!isValidShapeName(shapeName)) {
|
|
290
314
|
errors.push({
|
|
291
315
|
type: 'notFound',
|
|
292
|
-
path:
|
|
316
|
+
path: path.concat(['options', 'model']),
|
|
293
317
|
message: `Invalid Model Shape "${shapeName ?? ''}"`
|
|
294
318
|
});
|
|
295
319
|
}
|
|
@@ -304,7 +328,7 @@ function validateResolver(projectSchema, basePath, resolver) {
|
|
|
304
328
|
if (!isValidShapeName(shapeName)) {
|
|
305
329
|
errors.push({
|
|
306
330
|
type: 'notFound',
|
|
307
|
-
path:
|
|
331
|
+
path: path.concat(['shapeName']),
|
|
308
332
|
message: `Invalid Model Shape "${shapeName ?? ''}"`
|
|
309
333
|
});
|
|
310
334
|
}
|
|
@@ -322,7 +346,7 @@ function validateResolver(projectSchema, basePath, resolver) {
|
|
|
322
346
|
} else {
|
|
323
347
|
errors.push({
|
|
324
348
|
type: 'conflict',
|
|
325
|
-
path:
|
|
349
|
+
path: path.concat('to'),
|
|
326
350
|
message: `Unable to parse property ref "${resolver.to}"`
|
|
327
351
|
});
|
|
328
352
|
}
|
|
@@ -330,62 +354,115 @@ function validateResolver(projectSchema, basePath, resolver) {
|
|
|
330
354
|
} else {
|
|
331
355
|
errors.push({
|
|
332
356
|
type: 'notFound',
|
|
333
|
-
path
|
|
357
|
+
path,
|
|
334
358
|
message: `Invalid resolver`
|
|
335
359
|
});
|
|
336
360
|
}
|
|
337
|
-
};
|
|
338
|
-
|
|
339
|
-
if ((0, _utils.isComposeResolver)(resolver)) {
|
|
340
|
-
resolver.compose.forEach(validateBasicResolver);
|
|
341
|
-
} else {
|
|
342
|
-
validateBasicResolver(resolver);
|
|
343
361
|
}
|
|
344
362
|
|
|
345
363
|
return errors;
|
|
346
|
-
}
|
|
347
|
-
|
|
364
|
+
}
|
|
348
365
|
|
|
349
|
-
function
|
|
366
|
+
function validateLocalQueryConfig(projectSchema, query, operation, name) {
|
|
350
367
|
const location = operation === 'query' ? 'queries' : 'mutations';
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
template,
|
|
354
|
-
shapeName
|
|
355
|
-
} = (0, _refs.parseReturnShape)(projectSchema, query.shape);
|
|
368
|
+
return validateResolver(projectSchema, [location, name, 'resolver'], query.resolver);
|
|
369
|
+
}
|
|
356
370
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
371
|
+
const operationProps = [['query', 'queries'], ['mutation', 'mutations']];
|
|
372
|
+
|
|
373
|
+
function validateLocalQueryConfigs(projectSchema) {
|
|
374
|
+
const errors = [];
|
|
375
|
+
|
|
376
|
+
for (const [operation, prop] of operationProps) {
|
|
377
|
+
for (const name of Object.keys(projectSchema[prop])) {
|
|
378
|
+
errors.push(...validateLocalQueryConfig(projectSchema, projectSchema[prop][name], operation, name));
|
|
379
|
+
}
|
|
363
380
|
}
|
|
364
381
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
382
|
+
return errors;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
function allowDisconnected(context, status) {
|
|
386
|
+
return Boolean(context.allowDisconnectedLayers) && status !== 'notAvailable';
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
function isValidShapeReference(context, layerState, shapeName) {
|
|
390
|
+
if (layerState.status !== 'ok') {
|
|
391
|
+
return allowDisconnected(context, layerState.status);
|
|
371
392
|
}
|
|
372
393
|
|
|
394
|
+
return Boolean(layerState.schema.shapes[shapeName]);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
async function validateResolverReferences(context, projectSchema, basePath, baseResolver) {
|
|
398
|
+
const errors = [];
|
|
399
|
+
await (0, _pMap.default)(enumerateBasicResolvers(baseResolver, basePath), async ([resolver, path]) => {
|
|
400
|
+
if (resolver.name === 'graphql:query' || resolver.name === 'graphql:mutation') {
|
|
401
|
+
const {
|
|
402
|
+
service,
|
|
403
|
+
fieldName
|
|
404
|
+
} = resolver;
|
|
405
|
+
const prop = resolver.name === 'graphql:query' ? 'queries' : 'mutations';
|
|
406
|
+
const layerState = await context.resolveLayer(service);
|
|
407
|
+
const valid = layerState.status === 'ok' ? Boolean(layerState.schema[prop][fieldName]) : allowDisconnected(context, layerState.status);
|
|
408
|
+
|
|
409
|
+
if (!valid) {
|
|
410
|
+
const operation = resolver.name === 'graphql:query' ? 'query' : 'mutation';
|
|
411
|
+
errors.push({
|
|
412
|
+
type: 'notFound',
|
|
413
|
+
path: path.concat('fieldName'),
|
|
414
|
+
message: `Missing ${operation} "${resolver.fieldName}" in service layer "${service}"`
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
} else if (resolver.name === 'delegate') {
|
|
418
|
+
const ref = (0, _refs.parsePropertyRef)(resolver.to);
|
|
419
|
+
|
|
420
|
+
if (ref && ref.serviceId !== 'local') {
|
|
421
|
+
const layerState = await context.resolveLayer(ref.serviceId);
|
|
422
|
+
const valid = layerState.status === 'ok' ? Boolean((0, _get.default)(layerState.schema, (0, _refs.propertyRefItemToPath)((0, _util.value)(''), ref))) : allowDisconnected(context, layerState.status);
|
|
423
|
+
|
|
424
|
+
if (!valid) {
|
|
425
|
+
errors.push({
|
|
426
|
+
type: 'notFound',
|
|
427
|
+
path: path.concat('to'),
|
|
428
|
+
message: `Missing resolver config at property ref "${resolver.to}"`
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
});
|
|
373
434
|
return errors;
|
|
374
435
|
}
|
|
375
436
|
|
|
376
|
-
function
|
|
377
|
-
|
|
378
|
-
|
|
437
|
+
async function validateQueryConfig(context, projectSchema, {
|
|
438
|
+
query,
|
|
439
|
+
name,
|
|
440
|
+
operation
|
|
441
|
+
}) {
|
|
442
|
+
const location = operation === 'query' ? 'queries' : 'mutations';
|
|
443
|
+
return validateResolverReferences(context, projectSchema, [location, name, 'resolver'], query.resolver);
|
|
444
|
+
}
|
|
379
445
|
|
|
380
|
-
|
|
381
|
-
|
|
446
|
+
async function validateQueryConfigs(context, projectSchema) {
|
|
447
|
+
const isLessThanV3_9_0 = (0, _lt.default)(getSemver(projectSchema.schemaVersion), '3.9.0');
|
|
448
|
+
|
|
449
|
+
if (isLessThanV3_9_0) {
|
|
450
|
+
return [];
|
|
382
451
|
}
|
|
383
452
|
|
|
384
|
-
|
|
385
|
-
|
|
453
|
+
const promises = [];
|
|
454
|
+
|
|
455
|
+
for (const [operation, prop] of operationProps) {
|
|
456
|
+
for (const name of Object.keys(projectSchema[prop])) {
|
|
457
|
+
promises.push(validateQueryConfig(context, projectSchema, {
|
|
458
|
+
query: projectSchema[prop][name],
|
|
459
|
+
operation,
|
|
460
|
+
name
|
|
461
|
+
}));
|
|
462
|
+
}
|
|
386
463
|
}
|
|
387
464
|
|
|
388
|
-
return
|
|
465
|
+
return (0, _lodash.flatten)(await Promise.all(promises));
|
|
389
466
|
}
|
|
390
467
|
|
|
391
468
|
function validateIndexedShapeConfig(projectSchema, shapeName, config) {
|
|
@@ -467,8 +544,6 @@ function validateIndexedShapes(projectSchema) {
|
|
|
467
544
|
return errors;
|
|
468
545
|
}
|
|
469
546
|
|
|
470
|
-
const builtInShapeNames = [...Object.keys(_builtinSchema.builtInShapes), ..._scalars.scalars, 'object'];
|
|
471
|
-
|
|
472
547
|
function getModelShapeIds(shapes) {
|
|
473
548
|
return Object.values(shapes).filter(shape => shape.model).map(shape => shape.id);
|
|
474
549
|
}
|
|
@@ -483,44 +558,94 @@ function isAllOfPath(path) {
|
|
|
483
558
|
return index !== -1 && (0, _util.isIntegerLike)(path[index + 1]);
|
|
484
559
|
}
|
|
485
560
|
|
|
486
|
-
function
|
|
561
|
+
function validateLocalRefs(projectSchema) {
|
|
487
562
|
const errors = [];
|
|
488
|
-
const shapeNames = new Set([...
|
|
489
|
-
const refs = (0, _schemaUtil.
|
|
563
|
+
const shapeNames = new Set([...builtInShapeNames, ...Object.keys(projectSchema.shapes)]);
|
|
564
|
+
const refs = (0, _schemaUtil.getAllRefs)(projectSchema).filter(item => !item.isForeign);
|
|
490
565
|
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
566
|
+
for (const item of refs) {
|
|
567
|
+
if (item.template && !(0, _templateShapes.isValidTemplate)(item.template)) {
|
|
568
|
+
errors.push({
|
|
569
|
+
type: 'notFound',
|
|
570
|
+
path: item.path,
|
|
571
|
+
message: `Invalid template "${item.template}"`
|
|
572
|
+
});
|
|
573
|
+
}
|
|
494
574
|
|
|
495
|
-
|
|
496
|
-
errors.push({
|
|
497
|
-
type: 'notFound',
|
|
498
|
-
path: item.path,
|
|
499
|
-
message: `Invalid ref "${(0, _refs.refItemToAtRef)(item)}"`
|
|
500
|
-
});
|
|
501
|
-
} // Make sure refs inside allOf don't refer to their own Shape
|
|
575
|
+
const shapeName = (0, _refs.refItemToShapeName)(item);
|
|
502
576
|
|
|
577
|
+
if (!shapeNames.has(shapeName)) {
|
|
578
|
+
errors.push({
|
|
579
|
+
type: 'notFound',
|
|
580
|
+
path: item.path,
|
|
581
|
+
message: `Invalid ref "${(0, _get.default)(projectSchema, item.path)}"`
|
|
582
|
+
});
|
|
583
|
+
} // Make sure refs inside allOf don't refer to their own Shape
|
|
503
584
|
|
|
504
|
-
if (item.path[1] === shapeName && isAllOfPath(item.path)) {
|
|
505
|
-
errors.push({
|
|
506
|
-
type: 'conflict',
|
|
507
|
-
path: item.path,
|
|
508
|
-
message: `allOf cannot be self-referential`
|
|
509
|
-
});
|
|
510
|
-
}
|
|
511
585
|
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
586
|
+
if (item.path[1] === shapeName && isAllOfPath(item.path)) {
|
|
587
|
+
errors.push({
|
|
588
|
+
type: 'conflict',
|
|
589
|
+
path: item.path,
|
|
590
|
+
message: `allOf cannot be self-referential`
|
|
591
|
+
});
|
|
592
|
+
}
|
|
515
593
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
594
|
+
const parentPath = (0, _initial.default)(item.path);
|
|
595
|
+
const parentSchema = (0, _get.default)(projectSchema, parentPath);
|
|
596
|
+
const propName = (0, _last.default)(item.path);
|
|
597
|
+
|
|
598
|
+
if (propName === '@ref' && parentSchema.$ref) {
|
|
599
|
+
errors.push({
|
|
600
|
+
type: 'conflict',
|
|
601
|
+
path: parentPath,
|
|
602
|
+
message: `Ref cannot have both @ref and $ref`
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
return errors;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
async function validateRefs(context, projectSchema) {
|
|
611
|
+
const {
|
|
612
|
+
resolveLayer
|
|
613
|
+
} = context;
|
|
614
|
+
const errors = [];
|
|
615
|
+
const refs = (0, _schemaUtil.getAllRefs)(projectSchema);
|
|
616
|
+
const layerIds = new Set();
|
|
617
|
+
|
|
618
|
+
for (const item of refs) {
|
|
619
|
+
if (item.serviceKey !== 'local') {
|
|
620
|
+
layerIds.add(item.serviceKey);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
const layersById = Object.fromEntries(await (0, _pMap.default)(layerIds, async layerId => [layerId, await resolveLayer(layerId)]));
|
|
625
|
+
|
|
626
|
+
for (const item of refs) {
|
|
627
|
+
if (item.template && !(0, _templateShapes.isValidTemplate)(item.template)) {
|
|
628
|
+
errors.push({
|
|
629
|
+
type: 'notFound',
|
|
630
|
+
path: item.path,
|
|
631
|
+
message: `Invalid template "${item.path}"`
|
|
632
|
+
});
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
const {
|
|
636
|
+
serviceKey: layerId
|
|
637
|
+
} = item;
|
|
638
|
+
const shapeName = (0, _refs.refItemToShapeName)(item);
|
|
639
|
+
const localShapeExists = Boolean(projectSchema.shapes[shapeName]) || builtInShapeNames.has(shapeName);
|
|
640
|
+
const valid = layerId === 'local' ? localShapeExists : localShapeExists || isValidShapeReference(context, layersById[layerId], shapeName);
|
|
641
|
+
|
|
642
|
+
if (!valid) {
|
|
643
|
+
errors.push({
|
|
644
|
+
type: 'notFound',
|
|
645
|
+
path: item.path,
|
|
646
|
+
message: `Invalid ref "${(0, _get.default)(projectSchema, item.path)}"`
|
|
647
|
+
});
|
|
648
|
+
}
|
|
524
649
|
}
|
|
525
650
|
|
|
526
651
|
return errors;
|
|
@@ -788,9 +913,13 @@ function formatError(error) {
|
|
|
788
913
|
};
|
|
789
914
|
}
|
|
790
915
|
|
|
916
|
+
function isValidateReferencesContext(context) {
|
|
917
|
+
return Boolean(context.resolveLayer);
|
|
918
|
+
}
|
|
919
|
+
|
|
791
920
|
const ajv = (0, _jsonSchema.createAjv)();
|
|
792
921
|
|
|
793
|
-
function validateStructure(schemaVersion, schema, ref
|
|
922
|
+
function validateStructure(schemaVersion, context, schema, ref) {
|
|
794
923
|
var _coerce, _ajv$errors;
|
|
795
924
|
|
|
796
925
|
const versionStr = (_coerce = (0, _coerce2.default)(schemaVersion)) === null || _coerce === void 0 ? void 0 : _coerce.format();
|
|
@@ -805,7 +934,9 @@ function validateStructure(schemaVersion, schema, ref, options) {
|
|
|
805
934
|
|
|
806
935
|
ajv.validate(`https://schema.takeshape.io/project-schema/v${versionStr}#${ref ?? ''}`, schema);
|
|
807
936
|
let errors = ((_ajv$errors = ajv.errors) === null || _ajv$errors === void 0 ? void 0 : _ajv$errors.map(formatError)) ?? [];
|
|
808
|
-
const
|
|
937
|
+
const {
|
|
938
|
+
suppressErrorPaths
|
|
939
|
+
} = context;
|
|
809
940
|
|
|
810
941
|
if (errors.length && suppressErrorPaths) {
|
|
811
942
|
errors = errors.filter(error => {
|
|
@@ -828,20 +959,10 @@ function validateStructure(schemaVersion, schema, ref, options) {
|
|
|
828
959
|
};
|
|
829
960
|
}
|
|
830
961
|
|
|
831
|
-
function
|
|
832
|
-
const
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
return structuralValidation;
|
|
836
|
-
}
|
|
837
|
-
|
|
838
|
-
const schema = obj;
|
|
839
|
-
let errors = [];
|
|
840
|
-
const namespaceShapes = (0, _schemaUtil.getAllNamespaceShapes)(schema);
|
|
841
|
-
const additionalShapeNames = (options !== null && options !== void 0 && options.additionalShapeNames ? builtInShapeNames.concat(options.additionalShapeNames) : builtInShapeNames).concat(namespaceShapes);
|
|
842
|
-
const additionalModelShapeIds = options !== null && options !== void 0 && options.additionalModelShapeIds ? builtInModelShapeIds.concat(options.additionalModelShapeIds) : builtInModelShapeIds;
|
|
843
|
-
errors = errors.concat(checkShapeNames(schema.shapes)).concat(checkShapeIds(schema.shapes)).concat(validateWorkflowsV3(schema)).concat(validateQueryConfigs(schema, additionalShapeNames)).concat(validateRefs(schema, additionalShapeNames)).concat(validateDirectives(schema, additionalModelShapeIds)).concat(validateLocales(schema)).concat(checkWorkflowStepNames(schema.workflows)).concat(checkWorkflowStepKeys(schema.workflows)).concat(validateOneOfs(schema)).concat(validateIndexedShapes(schema)).concat(validateInterfaces(schema)).concat(validateInterfaceImplementations(schema));
|
|
844
|
-
const suppressErrorPaths = options === null || options === void 0 ? void 0 : options.suppressErrorPaths;
|
|
962
|
+
function formatValidationResult(context, errors, schema) {
|
|
963
|
+
const {
|
|
964
|
+
suppressErrorPaths
|
|
965
|
+
} = context;
|
|
845
966
|
|
|
846
967
|
if (suppressErrorPaths) {
|
|
847
968
|
errors = errors.filter(error => {
|
|
@@ -860,133 +981,142 @@ function validateV3X(version, obj, options) {
|
|
|
860
981
|
};
|
|
861
982
|
}
|
|
862
983
|
|
|
863
|
-
function validateV4X(version, obj, options) {
|
|
864
|
-
const structuralValidation = validateStructure(version, obj);
|
|
865
|
-
|
|
866
|
-
if (!structuralValidation.valid) {
|
|
867
|
-
return structuralValidation;
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
const schema = obj;
|
|
871
|
-
|
|
872
|
-
for (const [index, layerConfig] of Object.entries(schema.layers)) {
|
|
873
|
-
var _options$resolveLayer;
|
|
874
|
-
|
|
875
|
-
const layerId = typeof layerConfig === 'string' ? layerConfig : layerConfig.id;
|
|
876
|
-
const layer = options === null || options === void 0 ? void 0 : (_options$resolveLayer = options.resolveLayer) === null || _options$resolveLayer === void 0 ? void 0 : _options$resolveLayer.call(options, layerId);
|
|
877
|
-
|
|
878
|
-
if (layer) {
|
|
879
|
-
const results = validateStructure(version, layer, '/definitions/layerSchema');
|
|
880
|
-
|
|
881
|
-
if (!results.valid) {
|
|
882
|
-
return results;
|
|
883
|
-
}
|
|
884
|
-
} else {
|
|
885
|
-
return {
|
|
886
|
-
valid: false,
|
|
887
|
-
schema: undefined,
|
|
888
|
-
errors: [{
|
|
889
|
-
path: ['layers', index],
|
|
890
|
-
type: 'undefined',
|
|
891
|
-
message: `Layer with id is undefined`
|
|
892
|
-
}]
|
|
893
|
-
};
|
|
894
|
-
}
|
|
895
|
-
}
|
|
896
|
-
|
|
897
|
-
return {
|
|
898
|
-
valid: true,
|
|
899
|
-
schema,
|
|
900
|
-
errors: undefined
|
|
901
|
-
};
|
|
902
|
-
}
|
|
903
|
-
|
|
904
984
|
const validators = [{
|
|
905
985
|
range: '^1.0.0',
|
|
906
986
|
|
|
907
|
-
|
|
908
|
-
const structuralValidation = validateStructure(schemaVersion, obj);
|
|
909
|
-
|
|
910
|
-
if (!structuralValidation.valid) {
|
|
911
|
-
return structuralValidation;
|
|
912
|
-
}
|
|
913
|
-
|
|
987
|
+
validateSyntax(schemaVersion, context, obj) {
|
|
914
988
|
const schemaV1 = obj;
|
|
915
989
|
let errors = [];
|
|
916
990
|
errors = errors.concat(checkContentTypeNames(schemaV1.contentTypes)).concat(validateWorkflowsV1(schemaV1)).concat(checkWorkflowStepNames(schemaV1.workflows)).concat(checkWorkflowStepKeys(schemaV1.workflows));
|
|
917
|
-
return errors
|
|
918
|
-
valid: false,
|
|
919
|
-
schema: undefined,
|
|
920
|
-
errors
|
|
921
|
-
} : {
|
|
922
|
-
valid: true,
|
|
923
|
-
schema: schemaV1,
|
|
924
|
-
errors: undefined
|
|
925
|
-
};
|
|
991
|
+
return formatValidationResult(context, errors, schemaV1);
|
|
926
992
|
}
|
|
927
993
|
|
|
928
994
|
}, {
|
|
929
995
|
range: '^3.0.0',
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
996
|
+
|
|
997
|
+
validateSyntax(schemaVersion, context, obj) {
|
|
998
|
+
const schema = obj;
|
|
999
|
+
let errors = [];
|
|
1000
|
+
errors = errors.concat(checkShapeNames(schema.shapes)).concat(checkShapeIds(schema.shapes)).concat(validateWorkflowsV3(schema)).concat(validateLocalQueryConfigs(schema)).concat(validateLocalRefs(schema)).concat(validateDirectives(schema)).concat(validateLocales(schema)).concat(checkWorkflowStepNames(schema.workflows)).concat(checkWorkflowStepKeys(schema.workflows)).concat(validateOneOfs(schema)).concat(validateIndexedShapes(schema)).concat(validateInterfaces(schema)).concat(validateInterfaceImplementations(schema));
|
|
1001
|
+
return formatValidationResult(context, errors, schema);
|
|
1002
|
+
},
|
|
1003
|
+
|
|
1004
|
+
async validateReferences(schemaVersion, context, obj) {
|
|
1005
|
+
const schema = obj;
|
|
1006
|
+
const errors = (0, _lodash.flatten)(await Promise.all([validateRefs(context, schema), validateQueryConfigs(context, schema)]));
|
|
1007
|
+
return formatValidationResult(context, errors, schema);
|
|
1008
|
+
}
|
|
1009
|
+
|
|
934
1010
|
}];
|
|
935
1011
|
|
|
936
1012
|
function findValidator(schemaVersion) {
|
|
937
|
-
const
|
|
938
|
-
const schemaSemVer = (0, _coerce2.default)(normalizedSchemaVersion);
|
|
1013
|
+
const schemaSemVer = (0, _coerce2.default)(schemaVersion);
|
|
939
1014
|
|
|
940
1015
|
if (schemaSemVer) {
|
|
941
1016
|
const validator = validators.find(v => (0, _satisfies.default)(schemaSemVer, v.range));
|
|
942
1017
|
|
|
943
1018
|
if (validator) {
|
|
944
|
-
|
|
1019
|
+
const {
|
|
1020
|
+
validateSyntax,
|
|
1021
|
+
validateReferences
|
|
1022
|
+
} = validator;
|
|
1023
|
+
return {
|
|
1024
|
+
validateSyntax: validateSyntax.bind(null, schemaVersion),
|
|
1025
|
+
...(validateReferences ? {
|
|
1026
|
+
validateReferences: validateReferences.bind(null, schemaVersion)
|
|
1027
|
+
} : {})
|
|
1028
|
+
};
|
|
945
1029
|
}
|
|
946
1030
|
}
|
|
947
1031
|
}
|
|
1032
|
+
|
|
1033
|
+
const schemaUndefinedResult = {
|
|
1034
|
+
valid: false,
|
|
1035
|
+
schema: undefined,
|
|
1036
|
+
errors: [{
|
|
1037
|
+
path: [],
|
|
1038
|
+
type: 'undefined',
|
|
1039
|
+
message: 'Schema is undefined'
|
|
1040
|
+
}]
|
|
1041
|
+
};
|
|
1042
|
+
const invalidVersionResult = {
|
|
1043
|
+
valid: false,
|
|
1044
|
+
schema: undefined,
|
|
1045
|
+
errors: [{
|
|
1046
|
+
path: [],
|
|
1047
|
+
type: 'invalidVersion',
|
|
1048
|
+
message: 'Unknown schema version'
|
|
1049
|
+
}]
|
|
1050
|
+
};
|
|
1051
|
+
|
|
1052
|
+
function normalizeSchemaVersion(schema) {
|
|
1053
|
+
return schema.schemaVersion ?? '1';
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
function validateSchemaSyntax(obj, options = {}) {
|
|
1057
|
+
if ((0, _isUndefined.default)(obj)) {
|
|
1058
|
+
return schemaUndefinedResult;
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
const schema = obj;
|
|
1062
|
+
const schemaVersion = normalizeSchemaVersion(schema);
|
|
1063
|
+
const validator = findValidator(schemaVersion);
|
|
1064
|
+
|
|
1065
|
+
if (!validator) {
|
|
1066
|
+
return invalidVersionResult;
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
const structuralValidation = validateStructure(schemaVersion, options, obj);
|
|
1070
|
+
|
|
1071
|
+
if (!structuralValidation.valid) {
|
|
1072
|
+
return structuralValidation;
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1075
|
+
return validator.validateSyntax(options, schema);
|
|
1076
|
+
}
|
|
948
1077
|
/**
|
|
949
1078
|
* Validates a schema using a matching validation based on the `schemaVersion` property.
|
|
950
1079
|
*/
|
|
951
1080
|
|
|
952
1081
|
|
|
953
|
-
function validateSchema(
|
|
1082
|
+
async function validateSchema(context, obj) {
|
|
954
1083
|
if ((0, _isUndefined.default)(obj)) {
|
|
955
|
-
return
|
|
956
|
-
valid: false,
|
|
957
|
-
schema: undefined,
|
|
958
|
-
errors: [{
|
|
959
|
-
path: [],
|
|
960
|
-
type: 'undefined',
|
|
961
|
-
message: 'Schema is undefined'
|
|
962
|
-
}]
|
|
963
|
-
};
|
|
1084
|
+
return schemaUndefinedResult;
|
|
964
1085
|
}
|
|
965
1086
|
|
|
1087
|
+
const contextWithDefaults = {
|
|
1088
|
+
allowDisconnectedLayers: true,
|
|
1089
|
+
...context
|
|
1090
|
+
};
|
|
966
1091
|
const schema = obj;
|
|
967
|
-
const
|
|
1092
|
+
const schemaVersion = normalizeSchemaVersion(schema);
|
|
1093
|
+
const validator = findValidator(schemaVersion);
|
|
968
1094
|
|
|
969
1095
|
if (!validator) {
|
|
970
|
-
return
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
1096
|
+
return invalidVersionResult;
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
const structuralValidation = validateStructure(schemaVersion, contextWithDefaults, obj);
|
|
1100
|
+
|
|
1101
|
+
if (!structuralValidation.valid) {
|
|
1102
|
+
return structuralValidation;
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
const syntaxValidation = validator.validateSyntax(contextWithDefaults, schema);
|
|
1106
|
+
|
|
1107
|
+
if (!syntaxValidation.valid || !validator.validateReferences || !isValidateReferencesContext(contextWithDefaults)) {
|
|
1108
|
+
return syntaxValidation;
|
|
979
1109
|
}
|
|
980
1110
|
|
|
981
|
-
return validator(
|
|
1111
|
+
return validator.validateReferences(contextWithDefaults, obj);
|
|
982
1112
|
}
|
|
983
1113
|
|
|
984
|
-
function
|
|
1114
|
+
function ensureValidLatestSchemaSyntax(obj) {
|
|
985
1115
|
const {
|
|
986
1116
|
valid,
|
|
987
1117
|
schema,
|
|
988
1118
|
errors
|
|
989
|
-
} =
|
|
1119
|
+
} = validateSchemaSyntax(obj);
|
|
990
1120
|
|
|
991
1121
|
if (!valid && errors) {
|
|
992
1122
|
throw new Error(`Invalid Schema "${errors[0].path.join(',')}": "${errors[0].message}"`);
|
|
@@ -1080,7 +1210,7 @@ function ensureValidRoleImport(maybeRoles) {
|
|
|
1080
1210
|
* Only use when validating an imported schema! ignore fields optional when importing
|
|
1081
1211
|
*/
|
|
1082
1212
|
function validateProjectSchemaImport(maybeSchema) {
|
|
1083
|
-
return
|
|
1213
|
+
return validateSchemaSyntax(maybeSchema, {
|
|
1084
1214
|
suppressErrorPaths: [..._types.projectSchemaImportOptionalProps, ..._types.legacyProjectSchemaImportOptionalProps]
|
|
1085
1215
|
});
|
|
1086
1216
|
}
|
package/es/schema-util.js
CHANGED
|
@@ -746,7 +746,7 @@ export function getAllRefsInQuery(projectSchema, queryPath, query, predicate) {
|
|
|
746
746
|
}
|
|
747
747
|
|
|
748
748
|
if (query.args && typeof query.args === 'object') {
|
|
749
|
-
visitSchemaProperties(dereferenceObjectSchema(projectSchema, query.args), queryPath, propertyVisitor);
|
|
749
|
+
visitSchemaProperties(dereferenceObjectSchema(projectSchema, query.args), [...queryPath, 'args'], propertyVisitor);
|
|
750
750
|
}
|
|
751
751
|
|
|
752
752
|
if (query.shape) {
|