@formspec/build 0.1.0-alpha.41 → 0.1.0-alpha.43

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/cli.js CHANGED
@@ -1600,12 +1600,25 @@ function applyCustomConstraint(schema, constraint, ctx) {
1600
1600
  `Cannot generate JSON Schema for custom constraint "${constraint.constraintId}" without a matching extension registration`
1601
1601
  );
1602
1602
  }
1603
- assignVendorPrefixedExtensionKeywords(
1604
- schema,
1605
- registration.toJsonSchema(constraint.payload, ctx.vendorPrefix),
1606
- ctx.vendorPrefix,
1607
- `custom constraint "${constraint.constraintId}"`
1608
- );
1603
+ const extensionSchema = registration.toJsonSchema(constraint.payload, ctx.vendorPrefix);
1604
+ if (registration.emitsVocabularyKeywords) {
1605
+ const target = schema;
1606
+ for (const [key, value] of Object.entries(extensionSchema)) {
1607
+ if (JSON_SCHEMA_STRUCTURAL_KEYWORDS.has(key)) {
1608
+ throw new Error(
1609
+ `Custom constraint "${constraint.constraintId}" with emitsVocabularyKeywords must not overwrite standard JSON Schema keyword "${key}"`
1610
+ );
1611
+ }
1612
+ target[key] = value;
1613
+ }
1614
+ } else {
1615
+ assignVendorPrefixedExtensionKeywords(
1616
+ schema,
1617
+ extensionSchema,
1618
+ ctx.vendorPrefix,
1619
+ `custom constraint "${constraint.constraintId}"`
1620
+ );
1621
+ }
1609
1622
  }
1610
1623
  function applyCustomAnnotation(schema, annotation, ctx) {
1611
1624
  const registration = ctx.extensionRegistry?.findAnnotation(annotation.annotationId);
@@ -1634,11 +1647,72 @@ function assignVendorPrefixedExtensionKeywords(schema, extensionSchema, vendorPr
1634
1647
  schema[key] = value;
1635
1648
  }
1636
1649
  }
1650
+ var JSON_SCHEMA_STRUCTURAL_KEYWORDS;
1637
1651
  var init_ir_generator = __esm({
1638
1652
  "src/json-schema/ir-generator.ts"() {
1639
1653
  "use strict";
1640
1654
  init_metadata();
1641
1655
  init_collision_guards();
1656
+ JSON_SCHEMA_STRUCTURAL_KEYWORDS = /* @__PURE__ */ new Set([
1657
+ "$schema",
1658
+ "$ref",
1659
+ "$defs",
1660
+ "$id",
1661
+ "$anchor",
1662
+ "$dynamicRef",
1663
+ "$dynamicAnchor",
1664
+ "$vocabulary",
1665
+ "$comment",
1666
+ "type",
1667
+ "enum",
1668
+ "const",
1669
+ "properties",
1670
+ "patternProperties",
1671
+ "additionalProperties",
1672
+ "required",
1673
+ "items",
1674
+ "prefixItems",
1675
+ "additionalItems",
1676
+ "contains",
1677
+ "allOf",
1678
+ "oneOf",
1679
+ "anyOf",
1680
+ "not",
1681
+ "if",
1682
+ "then",
1683
+ "else",
1684
+ "minimum",
1685
+ "maximum",
1686
+ "exclusiveMinimum",
1687
+ "exclusiveMaximum",
1688
+ "multipleOf",
1689
+ "minLength",
1690
+ "maxLength",
1691
+ "pattern",
1692
+ "minItems",
1693
+ "maxItems",
1694
+ "uniqueItems",
1695
+ "minProperties",
1696
+ "maxProperties",
1697
+ "minContains",
1698
+ "maxContains",
1699
+ "format",
1700
+ "title",
1701
+ "description",
1702
+ "default",
1703
+ "deprecated",
1704
+ "readOnly",
1705
+ "writeOnly",
1706
+ "examples",
1707
+ "dependentRequired",
1708
+ "dependentSchemas",
1709
+ "propertyNames",
1710
+ "unevaluatedItems",
1711
+ "unevaluatedProperties",
1712
+ "contentEncoding",
1713
+ "contentMediaType",
1714
+ "contentSchema"
1715
+ ]);
1642
1716
  }
1643
1717
  });
1644
1718
 
@@ -2179,72 +2253,25 @@ var init_schema2 = __esm({
2179
2253
  import * as ts from "typescript";
2180
2254
  import {
2181
2255
  checkSyntheticTagApplication,
2256
+ choosePreferredPayloadText,
2182
2257
  extractPathTarget as extractSharedPathTarget,
2183
2258
  getTagDefinition as getTagDefinition2,
2184
2259
  hasTypeSemanticCapability,
2185
2260
  normalizeFormSpecTagName as normalizeFormSpecTagName2,
2186
2261
  parseConstraintTagValue,
2187
2262
  parseDefaultValueTagValue,
2263
+ parseTagSyntax,
2264
+ parseUnifiedComment,
2188
2265
  resolveDeclarationPlacement,
2189
2266
  resolvePathTargetType,
2190
- sliceCommentSpan,
2191
- parseCommentBlock,
2192
- parseTagSyntax
2267
+ TAGS_REQUIRING_RAW_TEXT
2193
2268
  } from "@formspec/analysis/internal";
2194
- import {
2195
- TSDocParser,
2196
- TSDocConfiguration,
2197
- TSDocTagDefinition,
2198
- TSDocTagSyntaxKind,
2199
- DocExcerpt,
2200
- DocPlainText,
2201
- DocSoftBreak,
2202
- TextRange
2203
- } from "@microsoft/tsdoc";
2204
2269
  import {
2205
2270
  BUILTIN_CONSTRAINT_DEFINITIONS as BUILTIN_CONSTRAINT_DEFINITIONS2,
2206
2271
  normalizeConstraintTagName as normalizeConstraintTagName2,
2207
2272
  isBuiltinConstraintName
2208
2273
  } from "@formspec/core/internals";
2209
2274
  import "@formspec/core/internals";
2210
- function createFormSpecTSDocConfig(extensionTagNames = []) {
2211
- const config = new TSDocConfiguration();
2212
- for (const tagName of Object.keys(BUILTIN_CONSTRAINT_DEFINITIONS2)) {
2213
- config.addTagDefinition(
2214
- new TSDocTagDefinition({
2215
- tagName: "@" + tagName,
2216
- syntaxKind: TSDocTagSyntaxKind.BlockTag,
2217
- allowMultiple: true
2218
- })
2219
- );
2220
- }
2221
- for (const tagName of ["apiName", "displayName", "format", "placeholder"]) {
2222
- config.addTagDefinition(
2223
- new TSDocTagDefinition({
2224
- tagName: "@" + tagName,
2225
- syntaxKind: TSDocTagSyntaxKind.BlockTag,
2226
- allowMultiple: true
2227
- })
2228
- );
2229
- }
2230
- for (const tagName of extensionTagNames) {
2231
- config.addTagDefinition(
2232
- new TSDocTagDefinition({
2233
- tagName: "@" + tagName,
2234
- syntaxKind: TSDocTagSyntaxKind.BlockTag,
2235
- allowMultiple: true
2236
- })
2237
- );
2238
- }
2239
- return config;
2240
- }
2241
- function sharedCommentSyntaxOptions(options, offset) {
2242
- const extensions = options?.extensionRegistry?.extensions;
2243
- return {
2244
- ...offset !== void 0 ? { offset } : {},
2245
- ...extensions !== void 0 ? { extensions } : {}
2246
- };
2247
- }
2248
2275
  function sharedTagValueOptions(options) {
2249
2276
  return {
2250
2277
  ...options?.extensionRegistry !== void 0 ? { registry: options.extensionRegistry } : {},
@@ -2343,6 +2370,30 @@ function pushUniqueCompilerDiagnostics(target, additions) {
2343
2370
  target.push(diagnostic);
2344
2371
  }
2345
2372
  }
2373
+ function processConstraintTag(tagName, text, parsedTag, provenance, node, sourceFile, supportingDeclarations, options, constraints, diagnostics) {
2374
+ const compilerDiagnostics = buildCompilerBackedConstraintDiagnostics(
2375
+ node,
2376
+ sourceFile,
2377
+ tagName,
2378
+ parsedTag,
2379
+ provenance,
2380
+ supportingDeclarations,
2381
+ options
2382
+ );
2383
+ if (compilerDiagnostics.length > 0) {
2384
+ pushUniqueCompilerDiagnostics(diagnostics, compilerDiagnostics);
2385
+ return;
2386
+ }
2387
+ const constraintNode = parseConstraintTagValue(
2388
+ tagName,
2389
+ text,
2390
+ provenance,
2391
+ sharedTagValueOptions(options)
2392
+ );
2393
+ if (constraintNode) {
2394
+ constraints.push(constraintNode);
2395
+ }
2396
+ }
2346
2397
  function renderSyntheticArgumentExpression(valueKind, argumentText) {
2347
2398
  const trimmed = argumentText.trim();
2348
2399
  if (trimmed === "") {
@@ -2628,8 +2679,8 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
2628
2679
  )
2629
2680
  ];
2630
2681
  }
2631
- function getParser(options) {
2632
- const extensionTagNames = [
2682
+ function getExtensionTagNames(options) {
2683
+ return [
2633
2684
  ...options?.extensionRegistry?.extensions.flatMap(
2634
2685
  (extension) => (extension.constraintTags ?? []).map((tag) => normalizeFormSpecTagName2(tag.tagName))
2635
2686
  ) ?? [],
@@ -2637,14 +2688,6 @@ function getParser(options) {
2637
2688
  (extension) => (extension.metadataSlots ?? []).map((slot) => normalizeFormSpecTagName2(slot.tagName))
2638
2689
  ) ?? []
2639
2690
  ].sort();
2640
- const cacheKey = extensionTagNames.join("|");
2641
- const existing = parserCache.get(cacheKey);
2642
- if (existing) {
2643
- return existing;
2644
- }
2645
- const parser = new TSDocParser(createFormSpecTSDocConfig(extensionTagNames));
2646
- parserCache.set(cacheKey, parser);
2647
- return parser;
2648
2691
  }
2649
2692
  function getExtensionRegistryCacheKey(registry) {
2650
2693
  if (registry === void 0) {
@@ -2695,13 +2738,13 @@ function parseTSDocTags(node, file = "", options) {
2695
2738
  let placeholder;
2696
2739
  let displayNameProvenance;
2697
2740
  let placeholderProvenance;
2698
- const rawTextTags = [];
2699
2741
  const sourceFile = node.getSourceFile();
2700
2742
  const sourceText = sourceFile.getFullText();
2701
2743
  const extensionTypeNames = getExtensionTypeNames(options?.extensionRegistry);
2702
2744
  const supportingDeclarations = buildSupportingDeclarations(sourceFile, extensionTypeNames);
2703
2745
  const commentRanges = ts.getLeadingCommentRanges(sourceText, node.getFullStart());
2704
2746
  const rawTextFallbacks = collectRawTextFallbacks(node, file);
2747
+ const extensionTagNames = getExtensionTagNames(options);
2705
2748
  if (commentRanges) {
2706
2749
  for (const range of commentRanges) {
2707
2750
  if (range.kind !== ts.SyntaxKind.MultiLineCommentTrivia) {
@@ -2711,38 +2754,18 @@ function parseTSDocTags(node, file = "", options) {
2711
2754
  if (!commentText.startsWith("/**")) {
2712
2755
  continue;
2713
2756
  }
2714
- const parser = getParser(options);
2715
- const parserContext = parser.parseRange(
2716
- TextRange.fromStringRange(sourceText, range.pos, range.end)
2717
- );
2718
- const docComment = parserContext.docComment;
2719
- const parsedComment = parseCommentBlock(
2720
- commentText,
2721
- sharedCommentSyntaxOptions(options, range.pos)
2722
- );
2723
- let parsedTagCursor = 0;
2724
- const nextParsedTag = (normalizedTagName) => {
2725
- while (parsedTagCursor < parsedComment.tags.length) {
2726
- const candidate = parsedComment.tags[parsedTagCursor];
2727
- parsedTagCursor += 1;
2728
- if (candidate?.normalizedTagName === normalizedTagName) {
2729
- return candidate;
2730
- }
2731
- }
2732
- return null;
2733
- };
2734
- for (const parsedTag of parsedComment.tags) {
2735
- if (TAGS_REQUIRING_RAW_TEXT.has(parsedTag.normalizedTagName)) {
2736
- rawTextTags.push({ tag: parsedTag, commentText, commentOffset: range.pos });
2737
- }
2738
- }
2739
- for (const block of docComment.customBlocks) {
2740
- const tagName = normalizeConstraintTagName2(block.blockTag.tagName.substring(1));
2741
- const parsedTag = nextParsedTag(tagName);
2757
+ const extensions = options?.extensionRegistry?.extensions;
2758
+ const unified = parseUnifiedComment(commentText, {
2759
+ offset: range.pos,
2760
+ extensionTagNames,
2761
+ ...extensions !== void 0 ? { extensions } : {}
2762
+ });
2763
+ for (const tag of unified.tags) {
2764
+ const tagName = tag.normalizedTagName;
2742
2765
  if (tagName === "displayName" || tagName === "format" || tagName === "placeholder") {
2743
- const text2 = getBestBlockPayloadText(parsedTag, commentText, range.pos, block);
2766
+ const text2 = tag.resolvedPayloadText;
2744
2767
  if (text2 === "") continue;
2745
- const provenance2 = parsedTag !== null ? provenanceForParsedTag(parsedTag, sourceFile, file) : provenanceForComment(range, sourceFile, file, tagName);
2768
+ const provenance2 = provenanceForParsedTag(tag, sourceFile, file);
2746
2769
  switch (tagName) {
2747
2770
  case "displayName":
2748
2771
  if (!isMemberTargetDisplayName(text2) && displayName === void 0) {
@@ -2767,64 +2790,69 @@ function parseTSDocTags(node, file = "", options) {
2767
2790
  }
2768
2791
  continue;
2769
2792
  }
2770
- if (TAGS_REQUIRING_RAW_TEXT.has(tagName)) continue;
2771
- const text = getBestBlockPayloadText(parsedTag, commentText, range.pos, block);
2772
- const expectedType = isBuiltinConstraintName(tagName) ? BUILTIN_CONSTRAINT_DEFINITIONS2[tagName] : void 0;
2773
- if (text === "" && expectedType !== "boolean") continue;
2774
- const provenance = parsedTag !== null ? provenanceForParsedTag(parsedTag, sourceFile, file) : provenanceForComment(range, sourceFile, file, tagName);
2775
- const compilerDiagnostics = buildCompilerBackedConstraintDiagnostics(
2776
- node,
2777
- sourceFile,
2778
- tagName,
2779
- parsedTag,
2780
- provenance,
2781
- supportingDeclarations,
2782
- options
2783
- );
2784
- if (compilerDiagnostics.length > 0) {
2785
- pushUniqueCompilerDiagnostics(diagnostics, compilerDiagnostics);
2793
+ if (TAGS_REQUIRING_RAW_TEXT.has(tagName)) {
2794
+ const fallback = rawTextFallbacks.get(tagName)?.shift();
2795
+ const text2 = choosePreferredPayloadText(tag.resolvedPayloadText, fallback?.text ?? "");
2796
+ if (text2 === "") continue;
2797
+ const provenance2 = provenanceForParsedTag(tag, sourceFile, file);
2798
+ if (tagName === "defaultValue") {
2799
+ annotations.push(parseDefaultValueTagValue(text2, provenance2));
2800
+ continue;
2801
+ }
2802
+ processConstraintTag(
2803
+ tagName,
2804
+ text2,
2805
+ tag,
2806
+ provenance2,
2807
+ node,
2808
+ sourceFile,
2809
+ supportingDeclarations,
2810
+ options,
2811
+ constraints,
2812
+ diagnostics
2813
+ );
2786
2814
  continue;
2787
2815
  }
2788
- const constraintNode = parseConstraintTagValue(
2816
+ const text = tag.resolvedPayloadText;
2817
+ const expectedType = isBuiltinConstraintName(tagName) ? BUILTIN_CONSTRAINT_DEFINITIONS2[tagName] : void 0;
2818
+ if (text === "" && expectedType !== "boolean") continue;
2819
+ const provenance = provenanceForParsedTag(tag, sourceFile, file);
2820
+ processConstraintTag(
2789
2821
  tagName,
2790
2822
  text,
2823
+ tag,
2791
2824
  provenance,
2792
- sharedTagValueOptions(options)
2825
+ node,
2826
+ sourceFile,
2827
+ supportingDeclarations,
2828
+ options,
2829
+ constraints,
2830
+ diagnostics
2793
2831
  );
2794
- if (constraintNode) {
2795
- constraints.push(constraintNode);
2796
- }
2797
2832
  }
2798
- if (docComment.deprecatedBlock !== void 0) {
2799
- const message = extractBlockText(docComment.deprecatedBlock).trim();
2833
+ if (unified.isDeprecated) {
2800
2834
  annotations.push({
2801
2835
  kind: "annotation",
2802
2836
  annotationKind: "deprecated",
2803
- ...message !== "" && { message },
2837
+ ...unified.deprecationMessage !== "" && { message: unified.deprecationMessage },
2804
2838
  provenance: provenanceForComment(range, sourceFile, file, "deprecated")
2805
2839
  });
2806
2840
  }
2807
- {
2808
- const summary = extractPlainText(docComment.summarySection).trim();
2809
- if (summary !== "") {
2810
- annotations.push({
2811
- kind: "annotation",
2812
- annotationKind: "description",
2813
- value: summary,
2814
- provenance: provenanceForComment(range, sourceFile, file, "summary")
2815
- });
2816
- }
2841
+ if (unified.summaryText !== "") {
2842
+ annotations.push({
2843
+ kind: "annotation",
2844
+ annotationKind: "description",
2845
+ value: unified.summaryText,
2846
+ provenance: provenanceForComment(range, sourceFile, file, "summary")
2847
+ });
2817
2848
  }
2818
- if (docComment.remarksBlock !== void 0) {
2819
- const remarksText = extractBlockText(docComment.remarksBlock).trim();
2820
- if (remarksText !== "") {
2821
- annotations.push({
2822
- kind: "annotation",
2823
- annotationKind: "remarks",
2824
- value: remarksText,
2825
- provenance: provenanceForComment(range, sourceFile, file, "remarks")
2826
- });
2827
- }
2849
+ if (unified.remarksText !== "") {
2850
+ annotations.push({
2851
+ kind: "annotation",
2852
+ annotationKind: "remarks",
2853
+ value: unified.remarksText,
2854
+ provenance: provenanceForComment(range, sourceFile, file, "remarks")
2855
+ });
2828
2856
  }
2829
2857
  }
2830
2858
  }
@@ -2844,77 +2872,27 @@ function parseTSDocTags(node, file = "", options) {
2844
2872
  provenance: placeholderProvenance
2845
2873
  });
2846
2874
  }
2847
- if (rawTextTags.length > 0) {
2848
- for (const rawTextTag of rawTextTags) {
2849
- const fallbackQueue = rawTextFallbacks.get(rawTextTag.tag.normalizedTagName);
2850
- const fallback = fallbackQueue?.shift();
2851
- const text = choosePreferredPayloadText(
2852
- getSharedPayloadText(rawTextTag.tag, rawTextTag.commentText, rawTextTag.commentOffset),
2853
- fallback?.text ?? ""
2854
- );
2855
- if (text === "") continue;
2856
- const provenance = provenanceForParsedTag(rawTextTag.tag, sourceFile, file);
2857
- if (rawTextTag.tag.normalizedTagName === "defaultValue") {
2858
- const defaultValueNode = parseDefaultValueTagValue(text, provenance);
2859
- annotations.push(defaultValueNode);
2860
- continue;
2861
- }
2862
- const compilerDiagnostics = buildCompilerBackedConstraintDiagnostics(
2863
- node,
2864
- sourceFile,
2865
- rawTextTag.tag.normalizedTagName,
2866
- rawTextTag.tag,
2867
- provenance,
2868
- supportingDeclarations,
2869
- options
2870
- );
2871
- if (compilerDiagnostics.length > 0) {
2872
- pushUniqueCompilerDiagnostics(diagnostics, compilerDiagnostics);
2873
- continue;
2874
- }
2875
- const constraintNode = parseConstraintTagValue(
2876
- rawTextTag.tag.normalizedTagName,
2877
- text,
2878
- provenance,
2879
- sharedTagValueOptions(options)
2880
- );
2881
- if (constraintNode) {
2882
- constraints.push(constraintNode);
2883
- }
2884
- }
2885
- }
2886
2875
  for (const [tagName, fallbacks] of rawTextFallbacks) {
2887
2876
  for (const fallback of fallbacks) {
2888
2877
  const text = fallback.text.trim();
2889
2878
  if (text === "") continue;
2890
2879
  const provenance = fallback.provenance;
2891
2880
  if (tagName === "defaultValue") {
2892
- const defaultValueNode = parseDefaultValueTagValue(text, provenance);
2893
- annotations.push(defaultValueNode);
2881
+ annotations.push(parseDefaultValueTagValue(text, provenance));
2894
2882
  continue;
2895
2883
  }
2896
- const compilerDiagnostics = buildCompilerBackedConstraintDiagnostics(
2897
- node,
2898
- sourceFile,
2884
+ processConstraintTag(
2899
2885
  tagName,
2886
+ text,
2900
2887
  null,
2901
2888
  provenance,
2889
+ node,
2890
+ sourceFile,
2902
2891
  supportingDeclarations,
2903
- options
2904
- );
2905
- if (compilerDiagnostics.length > 0) {
2906
- pushUniqueCompilerDiagnostics(diagnostics, compilerDiagnostics);
2907
- continue;
2908
- }
2909
- const constraintNode = parseConstraintTagValue(
2910
- tagName,
2911
- text,
2912
- provenance,
2913
- sharedTagValueOptions(options)
2892
+ options,
2893
+ constraints,
2894
+ diagnostics
2914
2895
  );
2915
- if (constraintNode) {
2916
- constraints.push(constraintNode);
2917
- }
2918
2896
  }
2919
2897
  }
2920
2898
  const result = { constraints, annotations, diagnostics };
@@ -2932,8 +2910,8 @@ function extractDisplayNameMetadata(node) {
2932
2910
  if (range.kind !== ts.SyntaxKind.MultiLineCommentTrivia) continue;
2933
2911
  const commentText = sourceText.substring(range.pos, range.end);
2934
2912
  if (!commentText.startsWith("/**")) continue;
2935
- const parsed = parseCommentBlock(commentText);
2936
- for (const tag of parsed.tags) {
2913
+ const unified = parseUnifiedComment(commentText);
2914
+ for (const tag of unified.tags) {
2937
2915
  if (tag.normalizedTagName !== "displayName") {
2938
2916
  continue;
2939
2917
  }
@@ -2952,51 +2930,6 @@ function extractDisplayNameMetadata(node) {
2952
2930
  memberDisplayNames
2953
2931
  };
2954
2932
  }
2955
- function extractBlockText(block) {
2956
- return extractPlainText(block.content);
2957
- }
2958
- function extractPlainText(node) {
2959
- let result = "";
2960
- if (node instanceof DocExcerpt) {
2961
- return node.content.toString();
2962
- }
2963
- if (node instanceof DocPlainText) {
2964
- return node.text;
2965
- }
2966
- if (node instanceof DocSoftBreak) {
2967
- return " ";
2968
- }
2969
- if (typeof node.getChildNodes === "function") {
2970
- for (const child of node.getChildNodes()) {
2971
- result += extractPlainText(child);
2972
- }
2973
- }
2974
- return result;
2975
- }
2976
- function choosePreferredPayloadText(primary, fallback) {
2977
- const preferred = primary.trim();
2978
- const alternate = fallback.trim();
2979
- if (preferred === "") return alternate;
2980
- if (alternate === "") return preferred;
2981
- if (alternate.includes("\n")) return alternate;
2982
- if (alternate.length > preferred.length && alternate.startsWith(preferred)) {
2983
- return alternate;
2984
- }
2985
- return preferred;
2986
- }
2987
- function getSharedPayloadText(tag, commentText, commentOffset) {
2988
- if (tag.payloadSpan === null) {
2989
- return "";
2990
- }
2991
- return sliceCommentSpan(commentText, tag.payloadSpan, {
2992
- offset: commentOffset
2993
- }).trim();
2994
- }
2995
- function getBestBlockPayloadText(tag, commentText, commentOffset, block) {
2996
- const sharedText = tag === null ? "" : getSharedPayloadText(tag, commentText, commentOffset);
2997
- const blockText = extractBlockText(block).replace(/\s+/g, " ").trim();
2998
- return choosePreferredPayloadText(sharedText, blockText);
2999
- }
3000
2933
  function collectRawTextFallbacks(node, file) {
3001
2934
  const fallbacks = /* @__PURE__ */ new Map();
3002
2935
  for (const tag of ts.getJSDocTags(node)) {
@@ -3056,13 +2989,11 @@ function getTagCommentText(tag) {
3056
2989
  }
3057
2990
  return ts.getTextOfJSDocComment(tag.comment);
3058
2991
  }
3059
- var TAGS_REQUIRING_RAW_TEXT, SYNTHETIC_TYPE_FORMAT_FLAGS, parserCache, parseResultCache;
2992
+ var SYNTHETIC_TYPE_FORMAT_FLAGS, parseResultCache;
3060
2993
  var init_tsdoc_parser = __esm({
3061
2994
  "src/analyzer/tsdoc-parser.ts"() {
3062
2995
  "use strict";
3063
- TAGS_REQUIRING_RAW_TEXT = /* @__PURE__ */ new Set(["pattern", "enumOptions", "defaultValue"]);
3064
2996
  SYNTHETIC_TYPE_FORMAT_FLAGS = ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
3065
- parserCache = /* @__PURE__ */ new Map();
3066
2997
  parseResultCache = /* @__PURE__ */ new Map();
3067
2998
  }
3068
2999
  });
@@ -3124,7 +3055,7 @@ var init_jsdoc_constraints = __esm({
3124
3055
  import * as ts3 from "typescript";
3125
3056
  import {
3126
3057
  analyzeMetadataForNodeWithChecker,
3127
- parseCommentBlock as parseCommentBlock2
3058
+ parseCommentBlock
3128
3059
  } from "@formspec/analysis/internal";
3129
3060
  function isObjectType(type) {
3130
3061
  return !!(type.flags & ts3.TypeFlags.Object);
@@ -3511,7 +3442,7 @@ function getLeadingParsedTags(node) {
3511
3442
  if (!commentText.startsWith("/**")) {
3512
3443
  continue;
3513
3444
  }
3514
- parsedTags.push(...parseCommentBlock2(commentText, { offset: range.pos }).tags);
3445
+ parsedTags.push(...parseCommentBlock(commentText, { offset: range.pos }).tags);
3515
3446
  }
3516
3447
  return parsedTags;
3517
3448
  }
@@ -4663,7 +4594,7 @@ function typeNodeContainsReference(type, targetName) {
4663
4594
  }
4664
4595
  }
4665
4596
  function shouldEmitResolvedObjectProperty(property, declaration) {
4666
- if (property.name.startsWith("__@")) {
4597
+ if (property.name.startsWith("__")) {
4667
4598
  return false;
4668
4599
  }
4669
4600
  if (declaration !== void 0 && "name" in declaration && declaration.name !== void 0) {
@@ -5692,7 +5623,9 @@ function generateSchemasFromClass(options) {
5692
5623
  classDecl,
5693
5624
  ctx.checker,
5694
5625
  options.filePath,
5626
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5695
5627
  options.extensionRegistry,
5628
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5696
5629
  options.metadata,
5697
5630
  options.discriminator
5698
5631
  );
@@ -5700,9 +5633,13 @@ function generateSchemasFromClass(options) {
5700
5633
  analysis,
5701
5634
  { file: options.filePath },
5702
5635
  {
5636
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5703
5637
  extensionRegistry: options.extensionRegistry,
5638
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5704
5639
  metadata: options.metadata,
5640
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5705
5641
  enumSerialization: options.enumSerialization,
5642
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5706
5643
  vendorPrefix: options.vendorPrefix
5707
5644
  }
5708
5645
  );
@@ -5749,7 +5686,12 @@ function generateSchemasDetailedInternal(options) {
5749
5686
  diagnostics: [createProgramContextFailureDiagnostic(options.filePath, error)]
5750
5687
  };
5751
5688
  }
5752
- return generateSchemasFromDetailedProgramContext(ctx, options.filePath, options.typeName, options);
5689
+ return generateSchemasFromDetailedProgramContext(
5690
+ ctx,
5691
+ options.filePath,
5692
+ options.typeName,
5693
+ options
5694
+ );
5753
5695
  }
5754
5696
  function generateSchemasFromProgramDetailed(options) {
5755
5697
  return generateSchemasFromProgram({
@@ -5767,7 +5709,12 @@ function generateSchemasFromProgramDetailedInternal(options) {
5767
5709
  diagnostics: [createProgramContextFailureDiagnostic(options.filePath, error)]
5768
5710
  };
5769
5711
  }
5770
- return generateSchemasFromDetailedProgramContext(ctx, options.filePath, options.typeName, options);
5712
+ return generateSchemasFromDetailedProgramContext(
5713
+ ctx,
5714
+ options.filePath,
5715
+ options.typeName,
5716
+ options
5717
+ );
5771
5718
  }
5772
5719
  function generateSchemasBatch(options) {
5773
5720
  const contextCache = /* @__PURE__ */ new Map();
@@ -5811,13 +5758,27 @@ function generateSchemasBatchFromProgram(options) {
5811
5758
  );
5812
5759
  });
5813
5760
  }
5761
+ function resolveOptions(options) {
5762
+ const configRegistry = options.config?.extensions !== void 0 ? createExtensionRegistry(options.config.extensions) : void 0;
5763
+ return {
5764
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5765
+ extensionRegistry: options.extensionRegistry ?? configRegistry,
5766
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5767
+ vendorPrefix: options.vendorPrefix ?? options.config?.vendorPrefix,
5768
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5769
+ enumSerialization: options.enumSerialization ?? options.config?.enumSerialization,
5770
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5771
+ metadata: options.metadata ?? options.config?.metadata
5772
+ };
5773
+ }
5814
5774
  function generateSchemasFromDetailedProgramContext(ctx, filePath, typeName, options) {
5775
+ const resolved = resolveOptions(options);
5815
5776
  const analysisResult = analyzeNamedTypeToIRFromProgramContextDetailed(
5816
5777
  ctx,
5817
5778
  filePath,
5818
5779
  typeName,
5819
- options.extensionRegistry,
5820
- options.metadata,
5780
+ resolved.extensionRegistry,
5781
+ resolved.metadata,
5821
5782
  options.discriminator
5822
5783
  );
5823
5784
  if (!analysisResult.ok) {
@@ -5830,10 +5791,10 @@ function generateSchemasFromDetailedProgramContext(ctx, filePath, typeName, opti
5830
5791
  analysisResult.analysis,
5831
5792
  { file: filePath },
5832
5793
  {
5833
- extensionRegistry: options.extensionRegistry,
5834
- metadata: options.metadata,
5835
- enumSerialization: options.enumSerialization,
5836
- vendorPrefix: options.vendorPrefix
5794
+ extensionRegistry: resolved.extensionRegistry,
5795
+ metadata: resolved.metadata,
5796
+ enumSerialization: resolved.enumSerialization,
5797
+ vendorPrefix: resolved.vendorPrefix
5837
5798
  }
5838
5799
  );
5839
5800
  }
@@ -5865,6 +5826,7 @@ var init_class_schema = __esm({
5865
5826
  init_class_analyzer();
5866
5827
  init_canonicalize();
5867
5828
  init_ir_generator();
5829
+ init_extensions();
5868
5830
  init_ir_generator2();
5869
5831
  init_validate();
5870
5832
  }
@@ -5987,6 +5949,7 @@ function omitApiName(metadata) {
5987
5949
  }
5988
5950
  function enforceRequiredMetadata(metadata, declarationKind, logicalName, options) {
5989
5951
  const declarationPolicy = getDeclarationMetadataPolicy(
5952
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5990
5953
  normalizeMetadataPolicy(options.metadata),
5991
5954
  declarationKind
5992
5955
  );
@@ -6061,6 +6024,7 @@ function toStandaloneJsonSchema(root, typeRegistry, options) {
6061
6024
  provenance: syntheticField.provenance
6062
6025
  },
6063
6026
  {
6027
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6064
6028
  policy: normalizeMetadataPolicy(options?.metadata),
6065
6029
  surface: "tsdoc",
6066
6030
  rootLogicalName: root.name
@@ -6069,8 +6033,11 @@ function toStandaloneJsonSchema(root, typeRegistry, options) {
6069
6033
  const schema = generateJsonSchemaFromIR(
6070
6034
  ir,
6071
6035
  {
6036
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6072
6037
  extensionRegistry: options?.extensionRegistry,
6038
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6073
6039
  enumSerialization: options?.enumSerialization,
6040
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6074
6041
  vendorPrefix: options?.vendorPrefix
6075
6042
  }
6076
6043
  );
@@ -6096,9 +6063,13 @@ function generateSchemasFromAnalysis(analysis, filePath, options) {
6096
6063
  analysis,
6097
6064
  { file: filePath },
6098
6065
  {
6066
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6099
6067
  extensionRegistry: options?.extensionRegistry,
6068
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6100
6069
  enumSerialization: options?.enumSerialization,
6070
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6101
6071
  metadata: options?.metadata,
6072
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6102
6073
  vendorPrefix: options?.vendorPrefix
6103
6074
  }
6104
6075
  ),
@@ -6123,7 +6094,9 @@ function generateSchemasFromResolvedType(options, skipNamedDeclaration = false,
6123
6094
  typeRegistry,
6124
6095
  /* @__PURE__ */ new Set(),
6125
6096
  options.sourceNode,
6097
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6126
6098
  createAnalyzerMetadataPolicy(options.metadata, options.discriminator),
6099
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6127
6100
  options.extensionRegistry,
6128
6101
  diagnostics
6129
6102
  );
@@ -6172,7 +6145,9 @@ function generateSchemasFromDeclaration(options) {
6172
6145
  options.declaration,
6173
6146
  options.context.checker,
6174
6147
  filePath,
6148
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6175
6149
  options.extensionRegistry,
6150
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6176
6151
  options.metadata,
6177
6152
  options.discriminator
6178
6153
  ),
@@ -6186,7 +6161,9 @@ function generateSchemasFromDeclaration(options) {
6186
6161
  options.declaration,
6187
6162
  options.context.checker,
6188
6163
  filePath,
6164
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6189
6165
  options.extensionRegistry,
6166
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6190
6167
  options.metadata,
6191
6168
  options.discriminator
6192
6169
  ),
@@ -6199,7 +6176,9 @@ function generateSchemasFromDeclaration(options) {
6199
6176
  options.declaration,
6200
6177
  options.context.checker,
6201
6178
  filePath,
6179
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6202
6180
  options.extensionRegistry,
6181
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6203
6182
  options.metadata,
6204
6183
  options.discriminator
6205
6184
  );
@@ -6210,7 +6189,9 @@ function generateSchemasFromDeclaration(options) {
6210
6189
  options.declaration,
6211
6190
  options.context.checker,
6212
6191
  filePath,
6192
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6213
6193
  options.extensionRegistry,
6194
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6214
6195
  options.metadata
6215
6196
  );
6216
6197
  if (aliasRootInfo.diagnostics.length > 0) {
@@ -6265,7 +6246,9 @@ function resolveDeclarationMetadata(options) {
6265
6246
  const analysis = analyzeMetadataForNodeWithChecker2({
6266
6247
  checker: options.context.checker,
6267
6248
  node: options.declaration,
6249
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6268
6250
  metadata: options.metadata,
6251
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6269
6252
  extensions: options.extensionRegistry?.extensions,
6270
6253
  buildContext: options.context
6271
6254
  });
@@ -6311,7 +6294,9 @@ function buildMixedAuthoringSchemas(options) {
6311
6294
  const analysis = analyzeNamedTypeToIR(
6312
6295
  filePath,
6313
6296
  typeName,
6297
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6314
6298
  schemaOptions.extensionRegistry,
6299
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6315
6300
  schemaOptions.metadata,
6316
6301
  schemaOptions.discriminator
6317
6302
  );
@@ -6319,6 +6304,7 @@ function buildMixedAuthoringSchemas(options) {
6319
6304
  const ir = canonicalizeTSDoc(
6320
6305
  composedAnalysis,
6321
6306
  { file: filePath },
6307
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6322
6308
  schemaOptions.metadata !== void 0 ? { metadata: schemaOptions.metadata } : void 0
6323
6309
  );
6324
6310
  return {