@formspec/build 0.1.0-alpha.42 → 0.1.0-alpha.44

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.cjs CHANGED
@@ -1626,7 +1626,7 @@ function applyCustomConstraint(schema, constraint, ctx) {
1626
1626
  if (registration.emitsVocabularyKeywords) {
1627
1627
  const target = schema;
1628
1628
  for (const [key, value] of Object.entries(extensionSchema)) {
1629
- if (JSON_SCHEMA_STRUCTURAL_KEYWORDS.has(key)) {
1629
+ if (VOCABULARY_MODE_BLOCKED_KEYWORDS.has(key)) {
1630
1630
  throw new Error(
1631
1631
  `Custom constraint "${constraint.constraintId}" with emitsVocabularyKeywords must not overwrite standard JSON Schema keyword "${key}"`
1632
1632
  );
@@ -1669,13 +1669,13 @@ function assignVendorPrefixedExtensionKeywords(schema, extensionSchema, vendorPr
1669
1669
  schema[key] = value;
1670
1670
  }
1671
1671
  }
1672
- var JSON_SCHEMA_STRUCTURAL_KEYWORDS;
1672
+ var VOCABULARY_MODE_BLOCKED_KEYWORDS;
1673
1673
  var init_ir_generator = __esm({
1674
1674
  "src/json-schema/ir-generator.ts"() {
1675
1675
  "use strict";
1676
1676
  init_metadata();
1677
1677
  init_collision_guards();
1678
- JSON_SCHEMA_STRUCTURAL_KEYWORDS = /* @__PURE__ */ new Set([
1678
+ VOCABULARY_MODE_BLOCKED_KEYWORDS = /* @__PURE__ */ new Set([
1679
1679
  "$schema",
1680
1680
  "$ref",
1681
1681
  "$defs",
@@ -2267,44 +2267,6 @@ var init_schema2 = __esm({
2267
2267
  });
2268
2268
 
2269
2269
  // src/analyzer/tsdoc-parser.ts
2270
- function createFormSpecTSDocConfig(extensionTagNames = []) {
2271
- const config = new import_tsdoc.TSDocConfiguration();
2272
- for (const tagName of Object.keys(import_internals4.BUILTIN_CONSTRAINT_DEFINITIONS)) {
2273
- config.addTagDefinition(
2274
- new import_tsdoc.TSDocTagDefinition({
2275
- tagName: "@" + tagName,
2276
- syntaxKind: import_tsdoc.TSDocTagSyntaxKind.BlockTag,
2277
- allowMultiple: true
2278
- })
2279
- );
2280
- }
2281
- for (const tagName of ["apiName", "displayName", "format", "placeholder"]) {
2282
- config.addTagDefinition(
2283
- new import_tsdoc.TSDocTagDefinition({
2284
- tagName: "@" + tagName,
2285
- syntaxKind: import_tsdoc.TSDocTagSyntaxKind.BlockTag,
2286
- allowMultiple: true
2287
- })
2288
- );
2289
- }
2290
- for (const tagName of extensionTagNames) {
2291
- config.addTagDefinition(
2292
- new import_tsdoc.TSDocTagDefinition({
2293
- tagName: "@" + tagName,
2294
- syntaxKind: import_tsdoc.TSDocTagSyntaxKind.BlockTag,
2295
- allowMultiple: true
2296
- })
2297
- );
2298
- }
2299
- return config;
2300
- }
2301
- function sharedCommentSyntaxOptions(options, offset) {
2302
- const extensions = options?.extensionRegistry?.extensions;
2303
- return {
2304
- ...offset !== void 0 ? { offset } : {},
2305
- ...extensions !== void 0 ? { extensions } : {}
2306
- };
2307
- }
2308
2270
  function sharedTagValueOptions(options) {
2309
2271
  return {
2310
2272
  ...options?.extensionRegistry !== void 0 ? { registry: options.extensionRegistry } : {},
@@ -2403,6 +2365,30 @@ function pushUniqueCompilerDiagnostics(target, additions) {
2403
2365
  target.push(diagnostic);
2404
2366
  }
2405
2367
  }
2368
+ function processConstraintTag(tagName, text, parsedTag, provenance, node, sourceFile, supportingDeclarations, options, constraints, diagnostics) {
2369
+ const compilerDiagnostics = buildCompilerBackedConstraintDiagnostics(
2370
+ node,
2371
+ sourceFile,
2372
+ tagName,
2373
+ parsedTag,
2374
+ provenance,
2375
+ supportingDeclarations,
2376
+ options
2377
+ );
2378
+ if (compilerDiagnostics.length > 0) {
2379
+ pushUniqueCompilerDiagnostics(diagnostics, compilerDiagnostics);
2380
+ return;
2381
+ }
2382
+ const constraintNode = (0, import_internal2.parseConstraintTagValue)(
2383
+ tagName,
2384
+ text,
2385
+ provenance,
2386
+ sharedTagValueOptions(options)
2387
+ );
2388
+ if (constraintNode) {
2389
+ constraints.push(constraintNode);
2390
+ }
2391
+ }
2406
2392
  function renderSyntheticArgumentExpression(valueKind, argumentText) {
2407
2393
  const trimmed = argumentText.trim();
2408
2394
  if (trimmed === "") {
@@ -2688,8 +2674,8 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
2688
2674
  )
2689
2675
  ];
2690
2676
  }
2691
- function getParser(options) {
2692
- const extensionTagNames = [
2677
+ function getExtensionTagNames(options) {
2678
+ return [
2693
2679
  ...options?.extensionRegistry?.extensions.flatMap(
2694
2680
  (extension) => (extension.constraintTags ?? []).map((tag) => (0, import_internal2.normalizeFormSpecTagName)(tag.tagName))
2695
2681
  ) ?? [],
@@ -2697,14 +2683,6 @@ function getParser(options) {
2697
2683
  (extension) => (extension.metadataSlots ?? []).map((slot) => (0, import_internal2.normalizeFormSpecTagName)(slot.tagName))
2698
2684
  ) ?? []
2699
2685
  ].sort();
2700
- const cacheKey = extensionTagNames.join("|");
2701
- const existing = parserCache.get(cacheKey);
2702
- if (existing) {
2703
- return existing;
2704
- }
2705
- const parser = new import_tsdoc.TSDocParser(createFormSpecTSDocConfig(extensionTagNames));
2706
- parserCache.set(cacheKey, parser);
2707
- return parser;
2708
2686
  }
2709
2687
  function getExtensionRegistryCacheKey(registry) {
2710
2688
  if (registry === void 0) {
@@ -2755,13 +2733,13 @@ function parseTSDocTags(node, file = "", options) {
2755
2733
  let placeholder;
2756
2734
  let displayNameProvenance;
2757
2735
  let placeholderProvenance;
2758
- const rawTextTags = [];
2759
2736
  const sourceFile = node.getSourceFile();
2760
2737
  const sourceText = sourceFile.getFullText();
2761
2738
  const extensionTypeNames = getExtensionTypeNames(options?.extensionRegistry);
2762
2739
  const supportingDeclarations = buildSupportingDeclarations(sourceFile, extensionTypeNames);
2763
2740
  const commentRanges = ts.getLeadingCommentRanges(sourceText, node.getFullStart());
2764
2741
  const rawTextFallbacks = collectRawTextFallbacks(node, file);
2742
+ const extensionTagNames = getExtensionTagNames(options);
2765
2743
  if (commentRanges) {
2766
2744
  for (const range of commentRanges) {
2767
2745
  if (range.kind !== ts.SyntaxKind.MultiLineCommentTrivia) {
@@ -2771,38 +2749,18 @@ function parseTSDocTags(node, file = "", options) {
2771
2749
  if (!commentText.startsWith("/**")) {
2772
2750
  continue;
2773
2751
  }
2774
- const parser = getParser(options);
2775
- const parserContext = parser.parseRange(
2776
- import_tsdoc.TextRange.fromStringRange(sourceText, range.pos, range.end)
2777
- );
2778
- const docComment = parserContext.docComment;
2779
- const parsedComment = (0, import_internal2.parseCommentBlock)(
2780
- commentText,
2781
- sharedCommentSyntaxOptions(options, range.pos)
2782
- );
2783
- let parsedTagCursor = 0;
2784
- const nextParsedTag = (normalizedTagName) => {
2785
- while (parsedTagCursor < parsedComment.tags.length) {
2786
- const candidate = parsedComment.tags[parsedTagCursor];
2787
- parsedTagCursor += 1;
2788
- if (candidate?.normalizedTagName === normalizedTagName) {
2789
- return candidate;
2790
- }
2791
- }
2792
- return null;
2793
- };
2794
- for (const parsedTag of parsedComment.tags) {
2795
- if (TAGS_REQUIRING_RAW_TEXT.has(parsedTag.normalizedTagName)) {
2796
- rawTextTags.push({ tag: parsedTag, commentText, commentOffset: range.pos });
2797
- }
2798
- }
2799
- for (const block of docComment.customBlocks) {
2800
- const tagName = (0, import_internals4.normalizeConstraintTagName)(block.blockTag.tagName.substring(1));
2801
- const parsedTag = nextParsedTag(tagName);
2752
+ const extensions = options?.extensionRegistry?.extensions;
2753
+ const unified = (0, import_internal2.parseUnifiedComment)(commentText, {
2754
+ offset: range.pos,
2755
+ extensionTagNames,
2756
+ ...extensions !== void 0 ? { extensions } : {}
2757
+ });
2758
+ for (const tag of unified.tags) {
2759
+ const tagName = tag.normalizedTagName;
2802
2760
  if (tagName === "displayName" || tagName === "format" || tagName === "placeholder") {
2803
- const text2 = getBestBlockPayloadText(parsedTag, commentText, range.pos, block);
2761
+ const text2 = tag.resolvedPayloadText;
2804
2762
  if (text2 === "") continue;
2805
- const provenance2 = parsedTag !== null ? provenanceForParsedTag(parsedTag, sourceFile, file) : provenanceForComment(range, sourceFile, file, tagName);
2763
+ const provenance2 = provenanceForParsedTag(tag, sourceFile, file);
2806
2764
  switch (tagName) {
2807
2765
  case "displayName":
2808
2766
  if (!isMemberTargetDisplayName(text2) && displayName === void 0) {
@@ -2827,64 +2785,69 @@ function parseTSDocTags(node, file = "", options) {
2827
2785
  }
2828
2786
  continue;
2829
2787
  }
2830
- if (TAGS_REQUIRING_RAW_TEXT.has(tagName)) continue;
2831
- const text = getBestBlockPayloadText(parsedTag, commentText, range.pos, block);
2832
- const expectedType = (0, import_internals4.isBuiltinConstraintName)(tagName) ? import_internals4.BUILTIN_CONSTRAINT_DEFINITIONS[tagName] : void 0;
2833
- if (text === "" && expectedType !== "boolean") continue;
2834
- const provenance = parsedTag !== null ? provenanceForParsedTag(parsedTag, sourceFile, file) : provenanceForComment(range, sourceFile, file, tagName);
2835
- const compilerDiagnostics = buildCompilerBackedConstraintDiagnostics(
2836
- node,
2837
- sourceFile,
2838
- tagName,
2839
- parsedTag,
2840
- provenance,
2841
- supportingDeclarations,
2842
- options
2843
- );
2844
- if (compilerDiagnostics.length > 0) {
2845
- pushUniqueCompilerDiagnostics(diagnostics, compilerDiagnostics);
2788
+ if (import_internal2.TAGS_REQUIRING_RAW_TEXT.has(tagName)) {
2789
+ const fallback = rawTextFallbacks.get(tagName)?.shift();
2790
+ const text2 = (0, import_internal2.choosePreferredPayloadText)(tag.resolvedPayloadText, fallback?.text ?? "");
2791
+ if (text2 === "") continue;
2792
+ const provenance2 = provenanceForParsedTag(tag, sourceFile, file);
2793
+ if (tagName === "defaultValue") {
2794
+ annotations.push((0, import_internal2.parseDefaultValueTagValue)(text2, provenance2));
2795
+ continue;
2796
+ }
2797
+ processConstraintTag(
2798
+ tagName,
2799
+ text2,
2800
+ tag,
2801
+ provenance2,
2802
+ node,
2803
+ sourceFile,
2804
+ supportingDeclarations,
2805
+ options,
2806
+ constraints,
2807
+ diagnostics
2808
+ );
2846
2809
  continue;
2847
2810
  }
2848
- const constraintNode = (0, import_internal2.parseConstraintTagValue)(
2811
+ const text = tag.resolvedPayloadText;
2812
+ const expectedType = (0, import_internals4.isBuiltinConstraintName)(tagName) ? import_internals4.BUILTIN_CONSTRAINT_DEFINITIONS[tagName] : void 0;
2813
+ if (text === "" && expectedType !== "boolean") continue;
2814
+ const provenance = provenanceForParsedTag(tag, sourceFile, file);
2815
+ processConstraintTag(
2849
2816
  tagName,
2850
2817
  text,
2818
+ tag,
2851
2819
  provenance,
2852
- sharedTagValueOptions(options)
2820
+ node,
2821
+ sourceFile,
2822
+ supportingDeclarations,
2823
+ options,
2824
+ constraints,
2825
+ diagnostics
2853
2826
  );
2854
- if (constraintNode) {
2855
- constraints.push(constraintNode);
2856
- }
2857
2827
  }
2858
- if (docComment.deprecatedBlock !== void 0) {
2859
- const message = extractBlockText(docComment.deprecatedBlock).trim();
2828
+ if (unified.isDeprecated) {
2860
2829
  annotations.push({
2861
2830
  kind: "annotation",
2862
2831
  annotationKind: "deprecated",
2863
- ...message !== "" && { message },
2832
+ ...unified.deprecationMessage !== "" && { message: unified.deprecationMessage },
2864
2833
  provenance: provenanceForComment(range, sourceFile, file, "deprecated")
2865
2834
  });
2866
2835
  }
2867
- {
2868
- const summary = extractPlainText(docComment.summarySection).trim();
2869
- if (summary !== "") {
2870
- annotations.push({
2871
- kind: "annotation",
2872
- annotationKind: "description",
2873
- value: summary,
2874
- provenance: provenanceForComment(range, sourceFile, file, "summary")
2875
- });
2876
- }
2836
+ if (unified.summaryText !== "") {
2837
+ annotations.push({
2838
+ kind: "annotation",
2839
+ annotationKind: "description",
2840
+ value: unified.summaryText,
2841
+ provenance: provenanceForComment(range, sourceFile, file, "summary")
2842
+ });
2877
2843
  }
2878
- if (docComment.remarksBlock !== void 0) {
2879
- const remarksText = extractBlockText(docComment.remarksBlock).trim();
2880
- if (remarksText !== "") {
2881
- annotations.push({
2882
- kind: "annotation",
2883
- annotationKind: "remarks",
2884
- value: remarksText,
2885
- provenance: provenanceForComment(range, sourceFile, file, "remarks")
2886
- });
2887
- }
2844
+ if (unified.remarksText !== "") {
2845
+ annotations.push({
2846
+ kind: "annotation",
2847
+ annotationKind: "remarks",
2848
+ value: unified.remarksText,
2849
+ provenance: provenanceForComment(range, sourceFile, file, "remarks")
2850
+ });
2888
2851
  }
2889
2852
  }
2890
2853
  }
@@ -2904,77 +2867,27 @@ function parseTSDocTags(node, file = "", options) {
2904
2867
  provenance: placeholderProvenance
2905
2868
  });
2906
2869
  }
2907
- if (rawTextTags.length > 0) {
2908
- for (const rawTextTag of rawTextTags) {
2909
- const fallbackQueue = rawTextFallbacks.get(rawTextTag.tag.normalizedTagName);
2910
- const fallback = fallbackQueue?.shift();
2911
- const text = choosePreferredPayloadText(
2912
- getSharedPayloadText(rawTextTag.tag, rawTextTag.commentText, rawTextTag.commentOffset),
2913
- fallback?.text ?? ""
2914
- );
2915
- if (text === "") continue;
2916
- const provenance = provenanceForParsedTag(rawTextTag.tag, sourceFile, file);
2917
- if (rawTextTag.tag.normalizedTagName === "defaultValue") {
2918
- const defaultValueNode = (0, import_internal2.parseDefaultValueTagValue)(text, provenance);
2919
- annotations.push(defaultValueNode);
2920
- continue;
2921
- }
2922
- const compilerDiagnostics = buildCompilerBackedConstraintDiagnostics(
2923
- node,
2924
- sourceFile,
2925
- rawTextTag.tag.normalizedTagName,
2926
- rawTextTag.tag,
2927
- provenance,
2928
- supportingDeclarations,
2929
- options
2930
- );
2931
- if (compilerDiagnostics.length > 0) {
2932
- pushUniqueCompilerDiagnostics(diagnostics, compilerDiagnostics);
2933
- continue;
2934
- }
2935
- const constraintNode = (0, import_internal2.parseConstraintTagValue)(
2936
- rawTextTag.tag.normalizedTagName,
2937
- text,
2938
- provenance,
2939
- sharedTagValueOptions(options)
2940
- );
2941
- if (constraintNode) {
2942
- constraints.push(constraintNode);
2943
- }
2944
- }
2945
- }
2946
2870
  for (const [tagName, fallbacks] of rawTextFallbacks) {
2947
2871
  for (const fallback of fallbacks) {
2948
2872
  const text = fallback.text.trim();
2949
2873
  if (text === "") continue;
2950
2874
  const provenance = fallback.provenance;
2951
2875
  if (tagName === "defaultValue") {
2952
- const defaultValueNode = (0, import_internal2.parseDefaultValueTagValue)(text, provenance);
2953
- annotations.push(defaultValueNode);
2876
+ annotations.push((0, import_internal2.parseDefaultValueTagValue)(text, provenance));
2954
2877
  continue;
2955
2878
  }
2956
- const compilerDiagnostics = buildCompilerBackedConstraintDiagnostics(
2957
- node,
2958
- sourceFile,
2879
+ processConstraintTag(
2959
2880
  tagName,
2881
+ text,
2960
2882
  null,
2961
2883
  provenance,
2884
+ node,
2885
+ sourceFile,
2962
2886
  supportingDeclarations,
2963
- options
2964
- );
2965
- if (compilerDiagnostics.length > 0) {
2966
- pushUniqueCompilerDiagnostics(diagnostics, compilerDiagnostics);
2967
- continue;
2968
- }
2969
- const constraintNode = (0, import_internal2.parseConstraintTagValue)(
2970
- tagName,
2971
- text,
2972
- provenance,
2973
- sharedTagValueOptions(options)
2887
+ options,
2888
+ constraints,
2889
+ diagnostics
2974
2890
  );
2975
- if (constraintNode) {
2976
- constraints.push(constraintNode);
2977
- }
2978
2891
  }
2979
2892
  }
2980
2893
  const result = { constraints, annotations, diagnostics };
@@ -2992,8 +2905,8 @@ function extractDisplayNameMetadata(node) {
2992
2905
  if (range.kind !== ts.SyntaxKind.MultiLineCommentTrivia) continue;
2993
2906
  const commentText = sourceText.substring(range.pos, range.end);
2994
2907
  if (!commentText.startsWith("/**")) continue;
2995
- const parsed = (0, import_internal2.parseCommentBlock)(commentText);
2996
- for (const tag of parsed.tags) {
2908
+ const unified = (0, import_internal2.parseUnifiedComment)(commentText);
2909
+ for (const tag of unified.tags) {
2997
2910
  if (tag.normalizedTagName !== "displayName") {
2998
2911
  continue;
2999
2912
  }
@@ -3012,56 +2925,11 @@ function extractDisplayNameMetadata(node) {
3012
2925
  memberDisplayNames
3013
2926
  };
3014
2927
  }
3015
- function extractBlockText(block) {
3016
- return extractPlainText(block.content);
3017
- }
3018
- function extractPlainText(node) {
3019
- let result = "";
3020
- if (node instanceof import_tsdoc.DocExcerpt) {
3021
- return node.content.toString();
3022
- }
3023
- if (node instanceof import_tsdoc.DocPlainText) {
3024
- return node.text;
3025
- }
3026
- if (node instanceof import_tsdoc.DocSoftBreak) {
3027
- return " ";
3028
- }
3029
- if (typeof node.getChildNodes === "function") {
3030
- for (const child of node.getChildNodes()) {
3031
- result += extractPlainText(child);
3032
- }
3033
- }
3034
- return result;
3035
- }
3036
- function choosePreferredPayloadText(primary, fallback) {
3037
- const preferred = primary.trim();
3038
- const alternate = fallback.trim();
3039
- if (preferred === "") return alternate;
3040
- if (alternate === "") return preferred;
3041
- if (alternate.includes("\n")) return alternate;
3042
- if (alternate.length > preferred.length && alternate.startsWith(preferred)) {
3043
- return alternate;
3044
- }
3045
- return preferred;
3046
- }
3047
- function getSharedPayloadText(tag, commentText, commentOffset) {
3048
- if (tag.payloadSpan === null) {
3049
- return "";
3050
- }
3051
- return (0, import_internal2.sliceCommentSpan)(commentText, tag.payloadSpan, {
3052
- offset: commentOffset
3053
- }).trim();
3054
- }
3055
- function getBestBlockPayloadText(tag, commentText, commentOffset, block) {
3056
- const sharedText = tag === null ? "" : getSharedPayloadText(tag, commentText, commentOffset);
3057
- const blockText = extractBlockText(block).replace(/\s+/g, " ").trim();
3058
- return choosePreferredPayloadText(sharedText, blockText);
3059
- }
3060
2928
  function collectRawTextFallbacks(node, file) {
3061
2929
  const fallbacks = /* @__PURE__ */ new Map();
3062
2930
  for (const tag of ts.getJSDocTags(node)) {
3063
2931
  const tagName = (0, import_internals4.normalizeConstraintTagName)(tag.tagName.text);
3064
- if (!TAGS_REQUIRING_RAW_TEXT.has(tagName)) continue;
2932
+ if (!import_internal2.TAGS_REQUIRING_RAW_TEXT.has(tagName)) continue;
3065
2933
  const commentText = getTagCommentText(tag)?.trim() ?? "";
3066
2934
  if (commentText === "") continue;
3067
2935
  const entries = fallbacks.get(tagName) ?? [];
@@ -3116,18 +2984,15 @@ function getTagCommentText(tag) {
3116
2984
  }
3117
2985
  return ts.getTextOfJSDocComment(tag.comment);
3118
2986
  }
3119
- var ts, import_internal2, import_tsdoc, import_internals4, import_internals5, TAGS_REQUIRING_RAW_TEXT, SYNTHETIC_TYPE_FORMAT_FLAGS, parserCache, parseResultCache;
2987
+ var ts, import_internal2, import_internals4, import_internals5, SYNTHETIC_TYPE_FORMAT_FLAGS, parseResultCache;
3120
2988
  var init_tsdoc_parser = __esm({
3121
2989
  "src/analyzer/tsdoc-parser.ts"() {
3122
2990
  "use strict";
3123
2991
  ts = __toESM(require("typescript"), 1);
3124
2992
  import_internal2 = require("@formspec/analysis/internal");
3125
- import_tsdoc = require("@microsoft/tsdoc");
3126
2993
  import_internals4 = require("@formspec/core/internals");
3127
2994
  import_internals5 = require("@formspec/core/internals");
3128
- TAGS_REQUIRING_RAW_TEXT = /* @__PURE__ */ new Set(["pattern", "enumOptions", "defaultValue"]);
3129
2995
  SYNTHETIC_TYPE_FORMAT_FLAGS = ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
3130
- parserCache = /* @__PURE__ */ new Map();
3131
2996
  parseResultCache = /* @__PURE__ */ new Map();
3132
2997
  }
3133
2998
  });
@@ -3193,6 +3058,31 @@ function isObjectType(type) {
3193
3058
  function isIntersectionType(type) {
3194
3059
  return !!(type.flags & ts3.TypeFlags.Intersection);
3195
3060
  }
3061
+ function isIntegerBrandedType(type) {
3062
+ if (!type.isIntersection()) {
3063
+ return false;
3064
+ }
3065
+ const hasNumberBase = type.types.some(
3066
+ (member) => !!(member.flags & ts3.TypeFlags.Number)
3067
+ );
3068
+ if (!hasNumberBase) {
3069
+ return false;
3070
+ }
3071
+ return type.getProperties().some((prop) => {
3072
+ const declaration = prop.valueDeclaration ?? prop.declarations?.[0];
3073
+ if (declaration === void 0) {
3074
+ return false;
3075
+ }
3076
+ if (!ts3.isPropertySignature(declaration) && !ts3.isPropertyDeclaration(declaration)) {
3077
+ return false;
3078
+ }
3079
+ const name = declaration.name;
3080
+ if (!ts3.isComputedPropertyName(name)) {
3081
+ return false;
3082
+ }
3083
+ return ts3.isIdentifier(name.expression) && name.expression.text === "__integerBrand";
3084
+ });
3085
+ }
3196
3086
  function isResolvableObjectLikeAliasTypeNode(typeNode) {
3197
3087
  if (ts3.isParenthesizedTypeNode(typeNode)) {
3198
3088
  return isResolvableObjectLikeAliasTypeNode(typeNode.type);
@@ -4313,6 +4203,9 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
4313
4203
  if (primitiveAlias) {
4314
4204
  return primitiveAlias;
4315
4205
  }
4206
+ if (isIntegerBrandedType(type)) {
4207
+ return { kind: "primitive", primitiveKind: "integer" };
4208
+ }
4316
4209
  if (type.flags & ts3.TypeFlags.String) {
4317
4210
  return { kind: "primitive", primitiveKind: "string" };
4318
4211
  }
@@ -4415,7 +4308,7 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
4415
4308
  return { kind: "primitive", primitiveKind: "string" };
4416
4309
  }
4417
4310
  function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4418
- if (!(type.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null))) {
4311
+ if (!(type.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null)) && !isIntegerBrandedType(type)) {
4419
4312
  return null;
4420
4313
  }
4421
4314
  const aliasDecl = type.aliasSymbol?.declarations?.find(ts3.isTypeAliasDeclaration) ?? getReferencedTypeAliasDeclaration(sourceNode, checker);
@@ -4501,6 +4394,9 @@ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiti
4501
4394
  visitedAliases
4502
4395
  );
4503
4396
  }
4397
+ if (isIntegerBrandedType(type)) {
4398
+ return { kind: "primitive", primitiveKind: "integer" };
4399
+ }
4504
4400
  if (type.flags & ts3.TypeFlags.String) {
4505
4401
  return { kind: "primitive", primitiveKind: "string" };
4506
4402
  }
@@ -4724,7 +4620,7 @@ function typeNodeContainsReference(type, targetName) {
4724
4620
  }
4725
4621
  }
4726
4622
  function shouldEmitResolvedObjectProperty(property, declaration) {
4727
- if (property.name.startsWith("__@")) {
4623
+ if (property.name.startsWith("__")) {
4728
4624
  return false;
4729
4625
  }
4730
4626
  if (declaration !== void 0 && "name" in declaration && declaration.name !== void 0) {
@@ -5754,7 +5650,9 @@ function generateSchemasFromClass(options) {
5754
5650
  classDecl,
5755
5651
  ctx.checker,
5756
5652
  options.filePath,
5653
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5757
5654
  options.extensionRegistry,
5655
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5758
5656
  options.metadata,
5759
5657
  options.discriminator
5760
5658
  );
@@ -5762,9 +5660,13 @@ function generateSchemasFromClass(options) {
5762
5660
  analysis,
5763
5661
  { file: options.filePath },
5764
5662
  {
5663
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5765
5664
  extensionRegistry: options.extensionRegistry,
5665
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5766
5666
  metadata: options.metadata,
5667
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5767
5668
  enumSerialization: options.enumSerialization,
5669
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5768
5670
  vendorPrefix: options.vendorPrefix
5769
5671
  }
5770
5672
  );
@@ -5811,7 +5713,12 @@ function generateSchemasDetailedInternal(options) {
5811
5713
  diagnostics: [createProgramContextFailureDiagnostic(options.filePath, error)]
5812
5714
  };
5813
5715
  }
5814
- return generateSchemasFromDetailedProgramContext(ctx, options.filePath, options.typeName, options);
5716
+ return generateSchemasFromDetailedProgramContext(
5717
+ ctx,
5718
+ options.filePath,
5719
+ options.typeName,
5720
+ options
5721
+ );
5815
5722
  }
5816
5723
  function generateSchemasFromProgramDetailed(options) {
5817
5724
  return generateSchemasFromProgram({
@@ -5829,7 +5736,12 @@ function generateSchemasFromProgramDetailedInternal(options) {
5829
5736
  diagnostics: [createProgramContextFailureDiagnostic(options.filePath, error)]
5830
5737
  };
5831
5738
  }
5832
- return generateSchemasFromDetailedProgramContext(ctx, options.filePath, options.typeName, options);
5739
+ return generateSchemasFromDetailedProgramContext(
5740
+ ctx,
5741
+ options.filePath,
5742
+ options.typeName,
5743
+ options
5744
+ );
5833
5745
  }
5834
5746
  function generateSchemasBatch(options) {
5835
5747
  const contextCache = /* @__PURE__ */ new Map();
@@ -5873,13 +5785,27 @@ function generateSchemasBatchFromProgram(options) {
5873
5785
  );
5874
5786
  });
5875
5787
  }
5788
+ function resolveOptions(options) {
5789
+ const configRegistry = options.config?.extensions !== void 0 ? createExtensionRegistry(options.config.extensions) : void 0;
5790
+ return {
5791
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5792
+ extensionRegistry: options.extensionRegistry ?? configRegistry,
5793
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5794
+ vendorPrefix: options.vendorPrefix ?? options.config?.vendorPrefix,
5795
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5796
+ enumSerialization: options.enumSerialization ?? options.config?.enumSerialization,
5797
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
5798
+ metadata: options.metadata ?? options.config?.metadata
5799
+ };
5800
+ }
5876
5801
  function generateSchemasFromDetailedProgramContext(ctx, filePath, typeName, options) {
5802
+ const resolved = resolveOptions(options);
5877
5803
  const analysisResult = analyzeNamedTypeToIRFromProgramContextDetailed(
5878
5804
  ctx,
5879
5805
  filePath,
5880
5806
  typeName,
5881
- options.extensionRegistry,
5882
- options.metadata,
5807
+ resolved.extensionRegistry,
5808
+ resolved.metadata,
5883
5809
  options.discriminator
5884
5810
  );
5885
5811
  if (!analysisResult.ok) {
@@ -5892,10 +5818,10 @@ function generateSchemasFromDetailedProgramContext(ctx, filePath, typeName, opti
5892
5818
  analysisResult.analysis,
5893
5819
  { file: filePath },
5894
5820
  {
5895
- extensionRegistry: options.extensionRegistry,
5896
- metadata: options.metadata,
5897
- enumSerialization: options.enumSerialization,
5898
- vendorPrefix: options.vendorPrefix
5821
+ extensionRegistry: resolved.extensionRegistry,
5822
+ metadata: resolved.metadata,
5823
+ enumSerialization: resolved.enumSerialization,
5824
+ vendorPrefix: resolved.vendorPrefix
5899
5825
  }
5900
5826
  );
5901
5827
  }
@@ -5929,6 +5855,7 @@ var init_class_schema = __esm({
5929
5855
  init_class_analyzer();
5930
5856
  init_canonicalize();
5931
5857
  init_ir_generator();
5858
+ init_extensions();
5932
5859
  init_ir_generator2();
5933
5860
  init_validate();
5934
5861
  }
@@ -6049,6 +5976,7 @@ function omitApiName(metadata) {
6049
5976
  }
6050
5977
  function enforceRequiredMetadata(metadata, declarationKind, logicalName, options) {
6051
5978
  const declarationPolicy = getDeclarationMetadataPolicy(
5979
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6052
5980
  normalizeMetadataPolicy(options.metadata),
6053
5981
  declarationKind
6054
5982
  );
@@ -6123,6 +6051,7 @@ function toStandaloneJsonSchema(root, typeRegistry, options) {
6123
6051
  provenance: syntheticField.provenance
6124
6052
  },
6125
6053
  {
6054
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6126
6055
  policy: normalizeMetadataPolicy(options?.metadata),
6127
6056
  surface: "tsdoc",
6128
6057
  rootLogicalName: root.name
@@ -6131,8 +6060,11 @@ function toStandaloneJsonSchema(root, typeRegistry, options) {
6131
6060
  const schema = generateJsonSchemaFromIR(
6132
6061
  ir,
6133
6062
  {
6063
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6134
6064
  extensionRegistry: options?.extensionRegistry,
6065
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6135
6066
  enumSerialization: options?.enumSerialization,
6067
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6136
6068
  vendorPrefix: options?.vendorPrefix
6137
6069
  }
6138
6070
  );
@@ -6158,9 +6090,13 @@ function generateSchemasFromAnalysis(analysis, filePath, options) {
6158
6090
  analysis,
6159
6091
  { file: filePath },
6160
6092
  {
6093
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6161
6094
  extensionRegistry: options?.extensionRegistry,
6095
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6162
6096
  enumSerialization: options?.enumSerialization,
6097
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6163
6098
  metadata: options?.metadata,
6099
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6164
6100
  vendorPrefix: options?.vendorPrefix
6165
6101
  }
6166
6102
  ),
@@ -6185,7 +6121,9 @@ function generateSchemasFromResolvedType(options, skipNamedDeclaration = false,
6185
6121
  typeRegistry,
6186
6122
  /* @__PURE__ */ new Set(),
6187
6123
  options.sourceNode,
6124
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6188
6125
  createAnalyzerMetadataPolicy(options.metadata, options.discriminator),
6126
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6189
6127
  options.extensionRegistry,
6190
6128
  diagnostics
6191
6129
  );
@@ -6234,7 +6172,9 @@ function generateSchemasFromDeclaration(options) {
6234
6172
  options.declaration,
6235
6173
  options.context.checker,
6236
6174
  filePath,
6175
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6237
6176
  options.extensionRegistry,
6177
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6238
6178
  options.metadata,
6239
6179
  options.discriminator
6240
6180
  ),
@@ -6248,7 +6188,9 @@ function generateSchemasFromDeclaration(options) {
6248
6188
  options.declaration,
6249
6189
  options.context.checker,
6250
6190
  filePath,
6191
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6251
6192
  options.extensionRegistry,
6193
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6252
6194
  options.metadata,
6253
6195
  options.discriminator
6254
6196
  ),
@@ -6261,7 +6203,9 @@ function generateSchemasFromDeclaration(options) {
6261
6203
  options.declaration,
6262
6204
  options.context.checker,
6263
6205
  filePath,
6206
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6264
6207
  options.extensionRegistry,
6208
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6265
6209
  options.metadata,
6266
6210
  options.discriminator
6267
6211
  );
@@ -6272,7 +6216,9 @@ function generateSchemasFromDeclaration(options) {
6272
6216
  options.declaration,
6273
6217
  options.context.checker,
6274
6218
  filePath,
6219
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6275
6220
  options.extensionRegistry,
6221
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6276
6222
  options.metadata
6277
6223
  );
6278
6224
  if (aliasRootInfo.diagnostics.length > 0) {
@@ -6327,7 +6273,9 @@ function resolveDeclarationMetadata(options) {
6327
6273
  const analysis = (0, import_internal5.analyzeMetadataForNodeWithChecker)({
6328
6274
  checker: options.context.checker,
6329
6275
  node: options.declaration,
6276
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6330
6277
  metadata: options.metadata,
6278
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6331
6279
  extensions: options.extensionRegistry?.extensions,
6332
6280
  buildContext: options.context
6333
6281
  });
@@ -6377,7 +6325,9 @@ function buildMixedAuthoringSchemas(options) {
6377
6325
  const analysis = analyzeNamedTypeToIR(
6378
6326
  filePath,
6379
6327
  typeName,
6328
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6380
6329
  schemaOptions.extensionRegistry,
6330
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6381
6331
  schemaOptions.metadata,
6382
6332
  schemaOptions.discriminator
6383
6333
  );
@@ -6385,6 +6335,7 @@ function buildMixedAuthoringSchemas(options) {
6385
6335
  const ir = canonicalizeTSDoc(
6386
6336
  composedAnalysis,
6387
6337
  { file: filePath },
6338
+ // eslint-disable-next-line @typescript-eslint/no-deprecated -- migration bridge reads deprecated fields
6388
6339
  schemaOptions.metadata !== void 0 ? { metadata: schemaOptions.metadata } : void 0
6389
6340
  );
6390
6341
  return {