@formspec/build 0.1.0-alpha.13 → 0.1.0-alpha.14

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 (39) hide show
  1. package/README.md +20 -20
  2. package/dist/__tests__/alias-chain-propagation.test.d.ts +9 -0
  3. package/dist/__tests__/alias-chain-propagation.test.d.ts.map +1 -0
  4. package/dist/__tests__/fixtures/alias-chains.d.ts +37 -0
  5. package/dist/__tests__/fixtures/alias-chains.d.ts.map +1 -0
  6. package/dist/__tests__/fixtures/example-a-builtins.d.ts +7 -7
  7. package/dist/__tests__/fixtures/example-interface-types.d.ts +17 -17
  8. package/dist/__tests__/json-utils.test.d.ts +5 -0
  9. package/dist/__tests__/json-utils.test.d.ts.map +1 -0
  10. package/dist/__tests__/path-target-parser.test.d.ts +9 -0
  11. package/dist/__tests__/path-target-parser.test.d.ts.map +1 -0
  12. package/dist/analyzer/class-analyzer.d.ts.map +1 -1
  13. package/dist/analyzer/jsdoc-constraints.d.ts +2 -2
  14. package/dist/analyzer/jsdoc-constraints.d.ts.map +1 -1
  15. package/dist/analyzer/json-utils.d.ts +22 -0
  16. package/dist/analyzer/json-utils.d.ts.map +1 -0
  17. package/dist/analyzer/tsdoc-parser.d.ts +18 -4
  18. package/dist/analyzer/tsdoc-parser.d.ts.map +1 -1
  19. package/dist/browser.cjs +76 -7
  20. package/dist/browser.cjs.map +1 -1
  21. package/dist/browser.js +76 -7
  22. package/dist/browser.js.map +1 -1
  23. package/dist/build.d.ts +1 -0
  24. package/dist/cli.cjs +140 -41
  25. package/dist/cli.cjs.map +1 -1
  26. package/dist/cli.js +145 -41
  27. package/dist/cli.js.map +1 -1
  28. package/dist/index.cjs +134 -40
  29. package/dist/index.cjs.map +1 -1
  30. package/dist/index.js +139 -41
  31. package/dist/index.js.map +1 -1
  32. package/dist/internals.cjs +147 -46
  33. package/dist/internals.cjs.map +1 -1
  34. package/dist/internals.js +152 -47
  35. package/dist/internals.js.map +1 -1
  36. package/dist/json-schema/ir-generator.d.ts +1 -0
  37. package/dist/json-schema/ir-generator.d.ts.map +1 -1
  38. package/dist/validate/constraint-validator.d.ts.map +1 -1
  39. package/package.json +3 -3
package/dist/browser.js CHANGED
@@ -360,8 +360,70 @@ function collectFields(elements, properties, required, ctx) {
360
360
  }
361
361
  function generateFieldSchema(field, ctx) {
362
362
  const schema = generateTypeNode(field.type, ctx);
363
- applyConstraints(schema, field.constraints);
363
+ const directConstraints = [];
364
+ const pathConstraints = [];
365
+ for (const c of field.constraints) {
366
+ if (c.path) {
367
+ pathConstraints.push(c);
368
+ } else {
369
+ directConstraints.push(c);
370
+ }
371
+ }
372
+ applyConstraints(schema, directConstraints);
364
373
  applyAnnotations(schema, field.annotations);
374
+ if (pathConstraints.length === 0) {
375
+ return schema;
376
+ }
377
+ return applyPathTargetedConstraints(schema, pathConstraints);
378
+ }
379
+ function applyPathTargetedConstraints(schema, pathConstraints) {
380
+ if (schema.type === "array" && schema.items) {
381
+ schema.items = applyPathTargetedConstraints(schema.items, pathConstraints);
382
+ return schema;
383
+ }
384
+ const byTarget = /* @__PURE__ */ new Map();
385
+ for (const c of pathConstraints) {
386
+ const target = c.path?.segments[0];
387
+ if (!target) continue;
388
+ const group = byTarget.get(target) ?? [];
389
+ group.push(c);
390
+ byTarget.set(target, group);
391
+ }
392
+ const propertyOverrides = {};
393
+ for (const [target, constraints] of byTarget) {
394
+ const subSchema = {};
395
+ applyConstraints(subSchema, constraints);
396
+ propertyOverrides[target] = subSchema;
397
+ }
398
+ if (schema.$ref) {
399
+ const { $ref, ...rest } = schema;
400
+ const refPart = { $ref };
401
+ const overridePart = {
402
+ properties: propertyOverrides,
403
+ ...rest
404
+ };
405
+ return { allOf: [refPart, overridePart] };
406
+ }
407
+ if (schema.type === "object" && schema.properties) {
408
+ const missingOverrides = {};
409
+ for (const [target, overrideSchema] of Object.entries(propertyOverrides)) {
410
+ if (schema.properties[target]) {
411
+ Object.assign(schema.properties[target], overrideSchema);
412
+ } else {
413
+ missingOverrides[target] = overrideSchema;
414
+ }
415
+ }
416
+ if (Object.keys(missingOverrides).length === 0) {
417
+ return schema;
418
+ }
419
+ return {
420
+ allOf: [schema, { properties: missingOverrides }]
421
+ };
422
+ }
423
+ if (schema.allOf) {
424
+ schema.allOf = [...schema.allOf, { properties: propertyOverrides }];
425
+ return schema;
426
+ }
365
427
  return schema;
366
428
  }
367
429
  function generateTypeNode(type, ctx) {
@@ -881,14 +943,10 @@ function addUnknownExtension(ctx, message, primary) {
881
943
  });
882
944
  }
883
945
  function findNumeric(constraints, constraintKind) {
884
- return constraints.find(
885
- (c) => c.constraintKind === constraintKind
886
- );
946
+ return constraints.find((c) => c.constraintKind === constraintKind);
887
947
  }
888
948
  function findLength(constraints, constraintKind) {
889
- return constraints.find(
890
- (c) => c.constraintKind === constraintKind
891
- );
949
+ return constraints.find((c) => c.constraintKind === constraintKind);
892
950
  }
893
951
  function findAllowedMembers(constraints) {
894
952
  return constraints.filter(
@@ -1012,6 +1070,17 @@ function checkTypeApplicability(ctx, fieldName, type, constraints) {
1012
1070
  const isEnum = type.kind === "enum";
1013
1071
  const label = typeLabel(type);
1014
1072
  for (const constraint of constraints) {
1073
+ if (constraint.path) {
1074
+ const isTraversable = type.kind === "object" || type.kind === "array" || type.kind === "reference";
1075
+ if (!isTraversable) {
1076
+ addTypeMismatch(
1077
+ ctx,
1078
+ `Field "${fieldName}": path-targeted constraint "${constraint.constraintKind}" is invalid because type "${label}" cannot be traversed`,
1079
+ constraint.provenance
1080
+ );
1081
+ }
1082
+ continue;
1083
+ }
1015
1084
  const ck = constraint.constraintKind;
1016
1085
  switch (ck) {
1017
1086
  case "minimum":