@takeshape/schema 8.214.0 → 8.215.3

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.
Files changed (89) hide show
  1. package/dist/create-input-schema.d.ts.map +1 -1
  2. package/dist/create-input-schema.js +8 -0
  3. package/dist/index.d.ts +1 -0
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +14 -0
  6. package/dist/interfaces.d.ts +10 -0
  7. package/dist/interfaces.d.ts.map +1 -0
  8. package/dist/interfaces.js +73 -0
  9. package/dist/migration/index.d.ts +1 -0
  10. package/dist/migration/index.d.ts.map +1 -1
  11. package/dist/migration/index.js +4 -1
  12. package/dist/migration/to/v3.21.0.d.ts +5 -0
  13. package/dist/migration/to/v3.21.0.d.ts.map +1 -0
  14. package/dist/migration/to/v3.21.0.js +18 -0
  15. package/dist/project-schema/index.d.ts +4 -1
  16. package/dist/project-schema/index.d.ts.map +1 -1
  17. package/dist/project-schema/index.js +20 -3
  18. package/dist/project-schema/latest.d.ts +3 -1
  19. package/dist/project-schema/latest.d.ts.map +1 -1
  20. package/dist/project-schema/migrate.d.ts.map +1 -1
  21. package/dist/project-schema/migrate.js +4 -0
  22. package/dist/project-schema/v3.21.0.d.ts +1339 -0
  23. package/dist/project-schema/v3.21.0.d.ts.map +1 -0
  24. package/dist/project-schema/v3.21.0.js +5 -0
  25. package/dist/refs.d.ts +1 -1
  26. package/dist/refs.d.ts.map +1 -1
  27. package/dist/refs.js +2 -2
  28. package/dist/schema-util.d.ts +1 -1
  29. package/dist/schema-util.d.ts.map +1 -1
  30. package/dist/schema-util.js +9 -5
  31. package/dist/schemas/index.d.ts +2 -2
  32. package/dist/schemas/index.d.ts.map +1 -1
  33. package/dist/schemas/index.js +6 -4
  34. package/dist/schemas/index.ts +4 -2
  35. package/dist/schemas/project-schema/latest.json +9 -2
  36. package/dist/schemas/project-schema/v3.21.0.json +2370 -0
  37. package/dist/schemas/project-schema.json +3 -0
  38. package/dist/types/types.d.ts +2 -2
  39. package/dist/types/types.d.ts.map +1 -1
  40. package/dist/validate.d.ts.map +1 -1
  41. package/dist/validate.js +161 -4
  42. package/es/create-input-schema.js +7 -0
  43. package/es/index.js +2 -1
  44. package/es/interfaces.js +55 -0
  45. package/es/migration/index.js +3 -1
  46. package/es/migration/to/v3.21.0.js +10 -0
  47. package/es/project-schema/index.js +3 -1
  48. package/es/project-schema/migrate.js +5 -1
  49. package/es/project-schema/v3.21.0.js +1 -0
  50. package/es/refs.js +2 -2
  51. package/es/schema-util.js +9 -5
  52. package/es/schemas/index.js +4 -3
  53. package/es/schemas/index.ts +4 -2
  54. package/es/schemas/project-schema/latest.json +9 -2
  55. package/es/schemas/project-schema/v3.21.0.json +2370 -0
  56. package/es/schemas/project-schema.json +3 -0
  57. package/es/validate.js +158 -5
  58. package/examples/latest/betzino.json +1 -1
  59. package/examples/latest/blog-schema.json +1 -1
  60. package/examples/latest/brewery-schema.json +1 -1
  61. package/examples/latest/complex-project-schema.json +1 -1
  62. package/examples/latest/complex-schema.json +1 -1
  63. package/examples/latest/fabric-ecommerce.json +1 -1
  64. package/examples/latest/frank-and-fred-schema.json +1 -1
  65. package/examples/latest/klirr-schema.json +1 -1
  66. package/examples/latest/massive-schema.json +1 -1
  67. package/examples/latest/mill-components-schema.json +1 -1
  68. package/examples/latest/one-earth.json +1 -1
  69. package/examples/latest/pet-oneof-array.json +1 -1
  70. package/examples/latest/post-schema.json +1 -1
  71. package/examples/latest/pruned-shopify-product-schema.json +1 -1
  72. package/examples/latest/real-world-schema.json +1 -1
  73. package/examples/latest/recursive-repeater-schema.json +1 -1
  74. package/examples/latest/recursive-schema.json +1 -1
  75. package/examples/latest/rick-and-morty-ast.json +1 -1
  76. package/examples/latest/rick-and-morty-graphql.json +1 -1
  77. package/examples/latest/rick-and-morty-rest.json +1 -1
  78. package/examples/latest/schema-with-repeater-draftjs.json +1 -1
  79. package/examples/latest/shape-books-v3_2_0.json +1 -1
  80. package/examples/latest/shape-books.json +1 -1
  81. package/examples/latest/shopify-lookbook.json +1 -1
  82. package/examples/latest/shopify-product-2022-07.json +26800 -1890
  83. package/examples/latest/shopify-store-with-widget.json +1 -1
  84. package/examples/latest/stripe-product-runtime-schema.json +1 -1
  85. package/examples/latest/stripe-starter-resolved.json +1 -1
  86. package/examples/latest/user-schema-no-required.json +1 -1
  87. package/examples/latest/user-schema-with-defaults.json +1 -1
  88. package/examples/source/shopify-product-2022-07.json +26799 -1888
  89. package/package.json +4 -4
@@ -90,6 +90,9 @@
90
90
  {
91
91
  "$ref": "https://schema.takeshape.io/project-schema/v3.20.0#"
92
92
  },
93
+ {
94
+ "$ref": "https://schema.takeshape.io/project-schema/v3.21.0#"
95
+ },
93
96
  {
94
97
  "$ref": "https://schema.takeshape.io/project-schema/v4.0.0#"
95
98
  }
package/es/validate.js CHANGED
@@ -15,7 +15,7 @@ import authSchemas from './schemas/auth-schemas.json';
15
15
  import { getAllNamespaceShapes, getAllRefsInShapes } from './schema-util';
16
16
  import { builtInShapes } from './builtin-schema';
17
17
  import { isValidTemplate } from './template-shapes';
18
- import { isBasicResolver, isComposeResolver } from './types/utils';
18
+ import { isBasicResolver, isComposeResolver, isExtendsSchema, isObjectSchema } from './types/utils';
19
19
  import { refItemToAtRef, refItemToShapeName, parseReturnShape, getRefShapeName } from './refs';
20
20
  import { scalars } from './scalars';
21
21
  import { isUnionSchema } from './unions';
@@ -28,6 +28,10 @@ import initial from 'lodash/initial';
28
28
  import last from 'lodash/last';
29
29
  import { getRelationship } from './relationships';
30
30
  import get from 'lodash/get';
31
+ import gte from 'semver/functions/gte';
32
+ import size from 'lodash/size';
33
+ import isEqual from 'lodash/isEqual';
34
+ import pick from 'lodash/pick';
31
35
 
32
36
  function findDuplicates(items) {
33
37
  const seen = {};
@@ -158,6 +162,10 @@ function validateWorkflowsV3(projectSchema) {
158
162
  return errors;
159
163
  }
160
164
 
165
+ function getSemver(schemaVersion) {
166
+ return coerce(schemaVersion) ?? LEGACY_SCHEMA_VERSION;
167
+ }
168
+
161
169
  function validateResolver(projectSchema, basePath, resolver) {
162
170
  const errors = [];
163
171
  /**
@@ -185,7 +193,7 @@ function validateResolver(projectSchema, basePath, resolver) {
185
193
  return Boolean((modelShape === null || modelShape === void 0 ? void 0 : modelShape.model) || shapeName && ((_indexedShapes = projectSchema.indexedShapes) === null || _indexedShapes === void 0 ? void 0 : _indexedShapes[shapeName]));
186
194
  };
187
195
 
188
- const isLessThanV3_9_0 = lt(coerce(projectSchema.schemaVersion) ?? LEGACY_SCHEMA_VERSION, '3.9.0');
196
+ const isLessThanV3_9_0 = lt(getSemver(projectSchema.schemaVersion), '3.9.0');
189
197
 
190
198
  const validateBasicResolver = resolver => {
191
199
  if (isBasicResolver(resolver)) {
@@ -321,7 +329,7 @@ function validateIndexedShapeConfig(projectSchema, shapeName, config) {
321
329
  function validateIndexedShapes(projectSchema) {
322
330
  let errors = [];
323
331
 
324
- if (gt(coerce(projectSchema.schemaVersion) ?? LEGACY_SCHEMA_VERSION, '3.12.0')) {
332
+ if (gt(getSemver(projectSchema.schemaVersion), '3.12.0')) {
325
333
  const {
326
334
  indexedShapes
327
335
  } = projectSchema;
@@ -406,7 +414,7 @@ function visitShapePropertiesJson(projectSchema, callback) {
406
414
  function validateDirectives(projectSchema, additionalShapeIds = builtInModelShapeIds) {
407
415
  const errors = [];
408
416
  const projectShapeIds = new Set([...getModelShapeIds(projectSchema.shapes), ...additionalShapeIds]);
409
- const isLessThanV3_18_0 = lt(coerce(projectSchema.schemaVersion) ?? LEGACY_SCHEMA_VERSION, '3.18.0');
417
+ const isLessThanV3_18_0 = lt(getSemver(projectSchema.schemaVersion), '3.18.0');
410
418
  visitShapePropertiesJson(projectSchema, (property, propertyPath) => {
411
419
  if (isLessThanV3_18_0) {
412
420
  const propSchema = property;
@@ -487,6 +495,151 @@ function validateLocales(projectSchema) {
487
495
  return errors;
488
496
  }
489
497
 
498
+ const importantFields = ['type', '@ref', 'allOf', 'oneOf', 'anyOf', 'extends', 'items', '@tag'];
499
+
500
+ function isSchemaEqual(a, b) {
501
+ return isEqual(pick(a, importantFields), pick(b, importantFields));
502
+ }
503
+
504
+ function matchesInterface(shape, interfaceShape, path) {
505
+ const errors = [];
506
+ const {
507
+ schema
508
+ } = shape;
509
+ const interfaceSchema = interfaceShape.schema;
510
+
511
+ for (const name of Object.keys(interfaceSchema.properties)) {
512
+ const propSchema = schema.properties[name];
513
+ const interfacePropSchema = interfaceSchema.properties[name];
514
+
515
+ if (!propSchema) {
516
+ errors.push({
517
+ type: 'notFound',
518
+ path,
519
+ message: `"${shape.name}" is missing property "${name}" required by interface "${interfaceShape.name}"`
520
+ });
521
+ } else if (!isSchemaEqual(propSchema, interfacePropSchema)) {
522
+ errors.push({
523
+ type: 'conflict',
524
+ path: [...path, name],
525
+ message: `"${shape.name}.${name}" must match "${interfaceShape.name}.${name}"`
526
+ });
527
+ } else {
528
+ var _schema$required, _interfaceSchema$requ;
529
+
530
+ const propRequired = Boolean((_schema$required = schema.required) === null || _schema$required === void 0 ? void 0 : _schema$required.includes(name));
531
+ const interfacePropRequired = Boolean((_interfaceSchema$requ = interfaceSchema.required) === null || _interfaceSchema$requ === void 0 ? void 0 : _interfaceSchema$requ.includes(name));
532
+
533
+ if (interfacePropRequired !== propRequired) {
534
+ errors.push({
535
+ type: 'conflict',
536
+ path: [...path, name],
537
+ message: `"${shape.name}.${name}" must ${interfacePropRequired ? '' : 'not '}be required to match "${interfaceShape.name}.${name}"`
538
+ });
539
+ }
540
+ }
541
+ }
542
+
543
+ return errors;
544
+ }
545
+
546
+ function validateShapeImplementsInterface(projectSchema, shape, interfaceShapeName, path) {
547
+ const errors = [];
548
+ const interfaceShape = projectSchema.shapes[interfaceShapeName];
549
+
550
+ if (!interfaceShape) {
551
+ errors.push({
552
+ type: 'notFound',
553
+ path,
554
+ message: `Invalid interface "${interfaceShapeName}" not found`
555
+ });
556
+ } else if (interfaceShape.type !== 'interface') {
557
+ errors.push({
558
+ type: 'conflict',
559
+ path,
560
+ message: `"${shape.name}" cannot implement non-interface "${interfaceShape.name}"`
561
+ });
562
+ } else if (isExtendsSchema(shape.schema)) {// TODO stricter extends validation needs https://app.shortcut.com/takeshape/story/9783/use-service-schemas-during-schema-validation
563
+ } else if (isObjectSchema(shape.schema) && isObjectSchema(interfaceShape.schema)) {
564
+ const matchErrors = matchesInterface(shape, interfaceShape, ['shapes', shape.name, 'schema', 'properties']);
565
+
566
+ if (matchErrors.length) {
567
+ errors.push(...matchErrors);
568
+ }
569
+ }
570
+
571
+ return errors;
572
+ }
573
+
574
+ function validateInterfaceImplementations(projectSchema) {
575
+ if (!gte(getSemver(projectSchema.schemaVersion), '3.21.0')) {
576
+ return [];
577
+ }
578
+
579
+ const errors = [];
580
+
581
+ for (const shape of Object.values(projectSchema.shapes)) {
582
+ var _shape$interfaces;
583
+
584
+ if ((_shape$interfaces = shape.interfaces) !== null && _shape$interfaces !== void 0 && _shape$interfaces.length) {
585
+ if (!isObjectSchema(shape.schema) && !isExtendsSchema(shape.schema)) {
586
+ return [{
587
+ path: ['shapes', shape.name, 'schema'],
588
+ type: 'conflict',
589
+ message: `"${shape.name}" must have an object or extends schema to implement interfaces`
590
+ }];
591
+ }
592
+
593
+ for (let i = 0; i < shape.interfaces.length; i++) {
594
+ const path = ['shapes', shape.name, 'interfaces', i];
595
+ const interfaceErrors = validateShapeImplementsInterface(projectSchema, shape, shape.interfaces[i], path);
596
+
597
+ if (interfaceErrors.length) {
598
+ errors.push(...interfaceErrors);
599
+ }
600
+ }
601
+ }
602
+ }
603
+
604
+ return errors;
605
+ }
606
+
607
+ function validateInterfaces(projectSchema) {
608
+ if (!gte(getSemver(projectSchema.schemaVersion), '3.21.0')) {
609
+ return [];
610
+ }
611
+
612
+ const errors = []; // Validate interface shapes must be an object schema with at least one property
613
+
614
+ for (const shape of Object.values(projectSchema.shapes)) {
615
+ if (shape.type === 'interface') {
616
+ if (shape.model) {
617
+ errors.push({
618
+ path: ['shapes', shape.name, 'model'],
619
+ type: 'conflict',
620
+ message: `"${shape.name}" may not be both an interface and model. Create a separate model shape which implements this interface.`
621
+ });
622
+ } else if (isObjectSchema(shape.schema)) {
623
+ if (size(shape.schema.properties) === 0) {
624
+ errors.push({
625
+ path: ['shapes', shape.name, 'schema', 'properties'],
626
+ type: 'conflict',
627
+ message: `Interface "${shape.name}" must define at least one property`
628
+ });
629
+ }
630
+ } else {
631
+ errors.push({
632
+ path: ['shapes', shape.name, 'schema'],
633
+ type: 'conflict',
634
+ message: `Interface "${shape.name}" must define an object schema`
635
+ });
636
+ }
637
+ }
638
+ }
639
+
640
+ return errors;
641
+ }
642
+
490
643
  export function formatError(error) {
491
644
  let pathStr = error.instancePath;
492
645
  let message = error.message ?? '';
@@ -562,7 +715,7 @@ function validateV3X(version, obj, options) {
562
715
  const namespaceShapes = getAllNamespaceShapes(schema);
563
716
  const additionalShapeNames = (options !== null && options !== void 0 && options.additionalShapeNames ? builtInShapeNames.concat(options.additionalShapeNames) : builtInShapeNames).concat(namespaceShapes);
564
717
  const additionalModelShapeIds = options !== null && options !== void 0 && options.additionalModelShapeIds ? builtInModelShapeIds.concat(options.additionalModelShapeIds) : builtInModelShapeIds;
565
- 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));
718
+ 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));
566
719
  const suppressErrorPaths = options === null || options === void 0 ? void 0 : options.suppressErrorPaths;
567
720
 
568
721
  if (suppressErrorPaths) {
@@ -52529,6 +52529,6 @@
52529
52529
  }
52530
52530
  }
52531
52531
  },
52532
- "schemaVersion": "3.20.0",
52532
+ "schemaVersion": "3.21.0",
52533
52533
  "services": {}
52534
52534
  }
@@ -403,6 +403,6 @@
403
403
  }
404
404
  }
405
405
  },
406
- "schemaVersion": "3.20.0",
406
+ "schemaVersion": "3.21.0",
407
407
  "services": {}
408
408
  }
@@ -386,6 +386,6 @@
386
386
  }
387
387
  }
388
388
  },
389
- "schemaVersion": "3.20.0",
389
+ "schemaVersion": "3.21.0",
390
390
  "services": {}
391
391
  }
@@ -4189,6 +4189,6 @@
4189
4189
  }
4190
4190
  }
4191
4191
  },
4192
- "schemaVersion": "3.20.0",
4192
+ "schemaVersion": "3.21.0",
4193
4193
  "services": {}
4194
4194
  }
@@ -17,7 +17,7 @@
17
17
  "apiVersion": "1",
18
18
  "queries": {},
19
19
  "mutations": {},
20
- "schemaVersion": "3.20.0",
20
+ "schemaVersion": "3.21.0",
21
21
  "created": "2019-06-20T12:58:43.119Z",
22
22
  "updated": "2020-04-29T10:10:28.182Z",
23
23
  "shapes": {
@@ -10509,5 +10509,5 @@
10509
10509
  }
10510
10510
  }
10511
10511
  },
10512
- "schemaVersion": "3.20.0"
10512
+ "schemaVersion": "3.21.0"
10513
10513
  }
@@ -23255,6 +23255,6 @@
23255
23255
  }
23256
23256
  }
23257
23257
  },
23258
- "schemaVersion": "3.20.0",
23258
+ "schemaVersion": "3.21.0",
23259
23259
  "services": {}
23260
23260
  }
@@ -34790,6 +34790,6 @@
34790
34790
  }
34791
34791
  }
34792
34792
  },
34793
- "schemaVersion": "3.20.0",
34793
+ "schemaVersion": "3.21.0",
34794
34794
  "services": {}
34795
34795
  }
@@ -7841,6 +7841,6 @@
7841
7841
  }
7842
7842
  }
7843
7843
  },
7844
- "schemaVersion": "3.20.0",
7844
+ "schemaVersion": "3.21.0",
7845
7845
  "services": {}
7846
7846
  }
@@ -1888,6 +1888,6 @@
1888
1888
  }
1889
1889
  }
1890
1890
  },
1891
- "schemaVersion": "3.20.0",
1891
+ "schemaVersion": "3.21.0",
1892
1892
  "services": {}
1893
1893
  }
@@ -14220,6 +14220,6 @@
14220
14220
  }
14221
14221
  }
14222
14222
  },
14223
- "schemaVersion": "3.20.0",
14223
+ "schemaVersion": "3.21.0",
14224
14224
  "services": {}
14225
14225
  }
@@ -392,6 +392,6 @@
392
392
  }
393
393
  }
394
394
  },
395
- "schemaVersion": "3.20.0",
395
+ "schemaVersion": "3.21.0",
396
396
  "services": {}
397
397
  }
@@ -230,6 +230,6 @@
230
230
  }
231
231
  }
232
232
  },
233
- "schemaVersion": "3.20.0",
233
+ "schemaVersion": "3.21.0",
234
234
  "services": {}
235
235
  }
@@ -9760,5 +9760,5 @@
9760
9760
  }
9761
9761
  }
9762
9762
  },
9763
- "schemaVersion": "3.20.0"
9763
+ "schemaVersion": "3.21.0"
9764
9764
  }
@@ -1045,6 +1045,6 @@
1045
1045
  }
1046
1046
  }
1047
1047
  },
1048
- "schemaVersion": "3.20.0",
1048
+ "schemaVersion": "3.21.0",
1049
1049
  "services": {}
1050
1050
  }
@@ -146,6 +146,6 @@
146
146
  }
147
147
  }
148
148
  },
149
- "schemaVersion": "3.20.0",
149
+ "schemaVersion": "3.21.0",
150
150
  "services": {}
151
151
  }
@@ -153,6 +153,6 @@
153
153
  }
154
154
  }
155
155
  },
156
- "schemaVersion": "3.20.0",
156
+ "schemaVersion": "3.21.0",
157
157
  "services": {}
158
158
  }
@@ -2824,5 +2824,5 @@
2824
2824
  }
2825
2825
  }
2826
2826
  },
2827
- "schemaVersion": "3.20.0"
2827
+ "schemaVersion": "3.21.0"
2828
2828
  }
@@ -2296,5 +2296,5 @@
2296
2296
  }
2297
2297
  }
2298
2298
  },
2299
- "schemaVersion": "3.20.0"
2299
+ "schemaVersion": "3.21.0"
2300
2300
  }
@@ -95,5 +95,5 @@
95
95
  }
96
96
  }
97
97
  },
98
- "schemaVersion": "3.20.0"
98
+ "schemaVersion": "3.21.0"
99
99
  }
@@ -401,6 +401,6 @@
401
401
  }
402
402
  }
403
403
  },
404
- "schemaVersion": "3.20.0",
404
+ "schemaVersion": "3.21.0",
405
405
  "services": {}
406
406
  }
@@ -1128,6 +1128,6 @@
1128
1128
  }
1129
1129
  }
1130
1130
  },
1131
- "schemaVersion": "3.20.0",
1131
+ "schemaVersion": "3.21.0",
1132
1132
  "services": {}
1133
1133
  }
@@ -1128,6 +1128,6 @@
1128
1128
  }
1129
1129
  }
1130
1130
  },
1131
- "schemaVersion": "3.20.0",
1131
+ "schemaVersion": "3.21.0",
1132
1132
  "services": {}
1133
1133
  }
@@ -1181,5 +1181,5 @@
1181
1181
  }
1182
1182
  }
1183
1183
  },
1184
- "schemaVersion": "3.20.0"
1184
+ "schemaVersion": "3.21.0"
1185
1185
  }