@formspec/build 0.1.0-alpha.32 → 0.1.0-alpha.33

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/index.js CHANGED
@@ -1765,13 +1765,35 @@ import * as fs from "fs";
1765
1765
  import * as path2 from "path";
1766
1766
 
1767
1767
  // src/extensions/registry.ts
1768
+ import {
1769
+ BUILTIN_CONSTRAINT_DEFINITIONS,
1770
+ normalizeConstraintTagName
1771
+ } from "@formspec/core/internals";
1772
+ import {
1773
+ getTagDefinition,
1774
+ normalizeFormSpecTagName
1775
+ } from "@formspec/analysis/internal";
1776
+ var BUILTIN_METADATA_TAGS = /* @__PURE__ */ new Set(["apiName", "displayName"]);
1777
+ function buildConstraintTagSources(extensions) {
1778
+ return extensions.map((extension) => ({
1779
+ extensionId: extension.extensionId,
1780
+ ...extension.constraintTags !== void 0 ? {
1781
+ constraintTags: extension.constraintTags.map((tag) => ({
1782
+ tagName: normalizeFormSpecTagName(tag.tagName)
1783
+ }))
1784
+ } : {}
1785
+ }));
1786
+ }
1768
1787
  function createExtensionRegistry(extensions) {
1788
+ const reservedTagSources = buildConstraintTagSources(extensions);
1769
1789
  const typeMap = /* @__PURE__ */ new Map();
1770
1790
  const typeNameMap = /* @__PURE__ */ new Map();
1771
1791
  const constraintMap = /* @__PURE__ */ new Map();
1772
1792
  const constraintTagMap = /* @__PURE__ */ new Map();
1773
1793
  const builtinBroadeningMap = /* @__PURE__ */ new Map();
1774
1794
  const annotationMap = /* @__PURE__ */ new Map();
1795
+ const metadataSlotMap = /* @__PURE__ */ new Map();
1796
+ const metadataTagMap = /* @__PURE__ */ new Map();
1775
1797
  for (const ext of extensions) {
1776
1798
  if (ext.types !== void 0) {
1777
1799
  for (const type of ext.types) {
@@ -1814,10 +1836,11 @@ function createExtensionRegistry(extensions) {
1814
1836
  }
1815
1837
  if (ext.constraintTags !== void 0) {
1816
1838
  for (const tag of ext.constraintTags) {
1817
- if (constraintTagMap.has(tag.tagName)) {
1818
- throw new Error(`Duplicate custom constraint tag: "@${tag.tagName}"`);
1839
+ const canonicalTagName = normalizeFormSpecTagName(tag.tagName);
1840
+ if (constraintTagMap.has(canonicalTagName)) {
1841
+ throw new Error(`Duplicate custom constraint tag: "@${canonicalTagName}"`);
1819
1842
  }
1820
- constraintTagMap.set(tag.tagName, {
1843
+ constraintTagMap.set(canonicalTagName, {
1821
1844
  extensionId: ext.extensionId,
1822
1845
  registration: tag
1823
1846
  });
@@ -1832,13 +1855,54 @@ function createExtensionRegistry(extensions) {
1832
1855
  annotationMap.set(qualifiedId, annotation);
1833
1856
  }
1834
1857
  }
1858
+ if (ext.metadataSlots !== void 0) {
1859
+ for (const slot of ext.metadataSlots) {
1860
+ if (metadataSlotMap.has(slot.slotId)) {
1861
+ throw new Error(`Duplicate metadata slot ID: "${slot.slotId}"`);
1862
+ }
1863
+ metadataSlotMap.set(slot.slotId, true);
1864
+ const canonicalTagName = normalizeFormSpecTagName(slot.tagName);
1865
+ if (slot.allowBare === false && (slot.qualifiers?.length ?? 0) === 0) {
1866
+ throw new Error(
1867
+ `Metadata tag "@${canonicalTagName}" must allow bare usage or declare at least one qualifier.`
1868
+ );
1869
+ }
1870
+ if (metadataTagMap.has(canonicalTagName)) {
1871
+ throw new Error(`Duplicate metadata tag: "@${canonicalTagName}"`);
1872
+ }
1873
+ if (BUILTIN_METADATA_TAGS.has(canonicalTagName)) {
1874
+ throw new Error(
1875
+ `Metadata tag "@${canonicalTagName}" conflicts with built-in metadata tags.`
1876
+ );
1877
+ }
1878
+ if (constraintTagMap.has(canonicalTagName)) {
1879
+ throw new Error(
1880
+ `Metadata tag "@${canonicalTagName}" conflicts with existing FormSpec tag "@${canonicalTagName}".`
1881
+ );
1882
+ }
1883
+ if (Object.hasOwn(BUILTIN_CONSTRAINT_DEFINITIONS, normalizeConstraintTagName(canonicalTagName))) {
1884
+ throw new Error(
1885
+ `Metadata tag "@${canonicalTagName}" conflicts with existing FormSpec tag "@${normalizeConstraintTagName(canonicalTagName)}".`
1886
+ );
1887
+ }
1888
+ const existingTag = getTagDefinition(canonicalTagName, reservedTagSources);
1889
+ if (existingTag !== null) {
1890
+ throw BUILTIN_METADATA_TAGS.has(existingTag.canonicalName) ? new Error(
1891
+ `Metadata tag "@${canonicalTagName}" conflicts with built-in metadata tags.`
1892
+ ) : new Error(
1893
+ `Metadata tag "@${canonicalTagName}" conflicts with existing FormSpec tag "@${existingTag.canonicalName}".`
1894
+ );
1895
+ }
1896
+ metadataTagMap.set(canonicalTagName, true);
1897
+ }
1898
+ }
1835
1899
  }
1836
1900
  return {
1837
1901
  extensions,
1838
1902
  findType: (typeId) => typeMap.get(typeId),
1839
1903
  findTypeByName: (typeName) => typeNameMap.get(typeName),
1840
1904
  findConstraint: (constraintId) => constraintMap.get(constraintId),
1841
- findConstraintTag: (tagName) => constraintTagMap.get(tagName),
1905
+ findConstraintTag: (tagName) => constraintTagMap.get(normalizeFormSpecTagName(tagName)),
1842
1906
  findBuiltinConstraintBroadening: (typeId, tagName) => builtinBroadeningMap.get(`${typeId}:${tagName}`),
1843
1907
  findAnnotation: (annotationId) => annotationMap.get(annotationId)
1844
1908
  };
@@ -1916,6 +1980,7 @@ import * as path from "path";
1916
1980
  // src/analyzer/class-analyzer.ts
1917
1981
  import * as ts3 from "typescript";
1918
1982
  import {
1983
+ analyzeMetadataForNodeWithChecker,
1919
1984
  parseCommentBlock as parseCommentBlock2
1920
1985
  } from "@formspec/analysis/internal";
1921
1986
 
@@ -1927,8 +1992,9 @@ import * as ts from "typescript";
1927
1992
  import {
1928
1993
  checkSyntheticTagApplication,
1929
1994
  extractPathTarget as extractSharedPathTarget,
1930
- getTagDefinition,
1995
+ getTagDefinition as getTagDefinition2,
1931
1996
  hasTypeSemanticCapability,
1997
+ normalizeFormSpecTagName as normalizeFormSpecTagName2,
1932
1998
  parseConstraintTagValue,
1933
1999
  parseDefaultValueTagValue,
1934
2000
  resolveDeclarationPlacement,
@@ -1948,15 +2014,15 @@ import {
1948
2014
  TextRange
1949
2015
  } from "@microsoft/tsdoc";
1950
2016
  import {
1951
- BUILTIN_CONSTRAINT_DEFINITIONS,
1952
- normalizeConstraintTagName,
2017
+ BUILTIN_CONSTRAINT_DEFINITIONS as BUILTIN_CONSTRAINT_DEFINITIONS2,
2018
+ normalizeConstraintTagName as normalizeConstraintTagName2,
1953
2019
  isBuiltinConstraintName
1954
2020
  } from "@formspec/core/internals";
1955
2021
  import "@formspec/core/internals";
1956
2022
  var TAGS_REQUIRING_RAW_TEXT = /* @__PURE__ */ new Set(["pattern", "enumOptions", "defaultValue"]);
1957
2023
  function createFormSpecTSDocConfig(extensionTagNames = []) {
1958
2024
  const config = new TSDocConfiguration();
1959
- for (const tagName of Object.keys(BUILTIN_CONSTRAINT_DEFINITIONS)) {
2025
+ for (const tagName of Object.keys(BUILTIN_CONSTRAINT_DEFINITIONS2)) {
1960
2026
  config.addTagDefinition(
1961
2027
  new TSDocTagDefinition({
1962
2028
  tagName: "@" + tagName,
@@ -1965,7 +2031,7 @@ function createFormSpecTSDocConfig(extensionTagNames = []) {
1965
2031
  })
1966
2032
  );
1967
2033
  }
1968
- for (const tagName of ["displayName", "format", "placeholder"]) {
2034
+ for (const tagName of ["apiName", "displayName", "format", "placeholder"]) {
1969
2035
  config.addTagDefinition(
1970
2036
  new TSDocTagDefinition({
1971
2037
  tagName: "@" + tagName,
@@ -1999,6 +2065,16 @@ function sharedTagValueOptions(options) {
1999
2065
  };
2000
2066
  }
2001
2067
  var SYNTHETIC_TYPE_FORMAT_FLAGS = ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
2068
+ function getExtensionTypeNames(registry) {
2069
+ if (registry === void 0) {
2070
+ return /* @__PURE__ */ new Set();
2071
+ }
2072
+ return new Set(
2073
+ registry.extensions.flatMap(
2074
+ (ext) => (ext.types ?? []).flatMap((t) => t.tsTypeNames ?? [t.typeName])
2075
+ )
2076
+ );
2077
+ }
2002
2078
  function collectImportedNames(sourceFile) {
2003
2079
  const importedNames = /* @__PURE__ */ new Set();
2004
2080
  for (const statement of sourceFile.statements) {
@@ -2038,6 +2114,9 @@ function isNonReferenceIdentifier(node) {
2038
2114
  return false;
2039
2115
  }
2040
2116
  function statementReferencesImportedName(statement, importedNames) {
2117
+ if (importedNames.size === 0) {
2118
+ return false;
2119
+ }
2041
2120
  let referencesImportedName = false;
2042
2121
  const visit = (node) => {
2043
2122
  if (referencesImportedName) {
@@ -2052,14 +2131,17 @@ function statementReferencesImportedName(statement, importedNames) {
2052
2131
  visit(statement);
2053
2132
  return referencesImportedName;
2054
2133
  }
2055
- function buildSupportingDeclarations(sourceFile) {
2134
+ function buildSupportingDeclarations(sourceFile, extensionTypeNames) {
2056
2135
  const importedNames = collectImportedNames(sourceFile);
2136
+ const importedNamesToSkip = new Set(
2137
+ [...importedNames].filter((name) => !extensionTypeNames.has(name))
2138
+ );
2057
2139
  return sourceFile.statements.filter((statement) => {
2058
2140
  if (ts.isImportDeclaration(statement)) return false;
2059
2141
  if (ts.isImportEqualsDeclaration(statement)) return false;
2060
2142
  if (ts.isExportDeclaration(statement) && statement.moduleSpecifier !== void 0)
2061
2143
  return false;
2062
- if (importedNames.size > 0 && statementReferencesImportedName(statement, importedNames)) {
2144
+ if (statementReferencesImportedName(statement, importedNamesToSkip)) {
2063
2145
  return false;
2064
2146
  }
2065
2147
  return true;
@@ -2212,7 +2294,7 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
2212
2294
  if (placement === null) {
2213
2295
  return [];
2214
2296
  }
2215
- const definition = getTagDefinition(tagName, options?.extensionRegistry?.extensions);
2297
+ const definition = getTagDefinition2(tagName, options?.extensionRegistry?.extensions);
2216
2298
  if (definition === null) {
2217
2299
  return [];
2218
2300
  }
@@ -2316,6 +2398,14 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
2316
2398
  extensionId: extension.extensionId,
2317
2399
  ...extension.constraintTags !== void 0 ? {
2318
2400
  constraintTags: extension.constraintTags.map((tag) => ({ tagName: tag.tagName }))
2401
+ } : {},
2402
+ ...extension.metadataSlots !== void 0 ? {
2403
+ metadataSlots: extension.metadataSlots
2404
+ } : {},
2405
+ ...extension.types !== void 0 ? {
2406
+ customTypes: extension.types.map((t) => ({
2407
+ tsTypeNames: t.tsTypeNames ?? [t.typeName]
2408
+ }))
2319
2409
  } : {}
2320
2410
  }))
2321
2411
  } : {}
@@ -2337,7 +2427,10 @@ var parseResultCache = /* @__PURE__ */ new Map();
2337
2427
  function getParser(options) {
2338
2428
  const extensionTagNames = [
2339
2429
  ...options?.extensionRegistry?.extensions.flatMap(
2340
- (extension) => (extension.constraintTags ?? []).map((tag) => tag.tagName)
2430
+ (extension) => (extension.constraintTags ?? []).map((tag) => normalizeFormSpecTagName2(tag.tagName))
2431
+ ) ?? [],
2432
+ ...options?.extensionRegistry?.extensions.flatMap(
2433
+ (extension) => (extension.metadataSlots ?? []).map((slot) => normalizeFormSpecTagName2(slot.tagName))
2341
2434
  ) ?? []
2342
2435
  ].sort();
2343
2436
  const cacheKey = extensionTagNames.join("|");
@@ -2357,7 +2450,16 @@ function getExtensionRegistryCacheKey(registry) {
2357
2450
  (extension) => JSON.stringify({
2358
2451
  extensionId: extension.extensionId,
2359
2452
  typeNames: extension.types?.map((type) => type.typeName) ?? [],
2360
- constraintTags: extension.constraintTags?.map((tag) => tag.tagName) ?? []
2453
+ constraintTags: extension.constraintTags?.map((tag) => normalizeFormSpecTagName2(tag.tagName)) ?? [],
2454
+ metadataSlots: extension.metadataSlots?.map((slot) => ({
2455
+ tagName: normalizeFormSpecTagName2(slot.tagName),
2456
+ declarationKinds: [...slot.declarationKinds].sort(),
2457
+ allowBare: slot.allowBare !== false,
2458
+ qualifiers: (slot.qualifiers ?? []).map((qualifier) => ({
2459
+ qualifier: qualifier.qualifier,
2460
+ ...qualifier.sourceQualifier !== void 0 ? { sourceQualifier: qualifier.sourceQualifier } : {}
2461
+ })).sort((left, right) => left.qualifier.localeCompare(right.qualifier))
2462
+ })) ?? []
2361
2463
  })
2362
2464
  ).join("|");
2363
2465
  }
@@ -2392,7 +2494,8 @@ function parseTSDocTags(node, file = "", options) {
2392
2494
  const rawTextTags = [];
2393
2495
  const sourceFile = node.getSourceFile();
2394
2496
  const sourceText = sourceFile.getFullText();
2395
- const supportingDeclarations = buildSupportingDeclarations(sourceFile);
2497
+ const extensionTypeNames = getExtensionTypeNames(options?.extensionRegistry);
2498
+ const supportingDeclarations = buildSupportingDeclarations(sourceFile, extensionTypeNames);
2396
2499
  const commentRanges = ts.getLeadingCommentRanges(sourceText, node.getFullStart());
2397
2500
  const rawTextFallbacks = collectRawTextFallbacks(node, file);
2398
2501
  if (commentRanges) {
@@ -2430,7 +2533,7 @@ function parseTSDocTags(node, file = "", options) {
2430
2533
  }
2431
2534
  }
2432
2535
  for (const block of docComment.customBlocks) {
2433
- const tagName = normalizeConstraintTagName(block.blockTag.tagName.substring(1));
2536
+ const tagName = normalizeConstraintTagName2(block.blockTag.tagName.substring(1));
2434
2537
  const parsedTag = nextParsedTag(tagName);
2435
2538
  if (tagName === "displayName" || tagName === "format" || tagName === "placeholder") {
2436
2539
  const text2 = getBestBlockPayloadText(parsedTag, commentText, range.pos, block);
@@ -2462,7 +2565,7 @@ function parseTSDocTags(node, file = "", options) {
2462
2565
  }
2463
2566
  if (TAGS_REQUIRING_RAW_TEXT.has(tagName)) continue;
2464
2567
  const text = getBestBlockPayloadText(parsedTag, commentText, range.pos, block);
2465
- const expectedType = isBuiltinConstraintName(tagName) ? BUILTIN_CONSTRAINT_DEFINITIONS[tagName] : void 0;
2568
+ const expectedType = isBuiltinConstraintName(tagName) ? BUILTIN_CONSTRAINT_DEFINITIONS2[tagName] : void 0;
2466
2569
  if (text === "" && expectedType !== "boolean") continue;
2467
2570
  const provenance = parsedTag !== null ? provenanceForParsedTag(parsedTag, sourceFile, file) : provenanceForComment(range, sourceFile, file, tagName);
2468
2571
  const compilerDiagnostics = buildCompilerBackedConstraintDiagnostics(
@@ -2693,7 +2796,7 @@ function getBestBlockPayloadText(tag, commentText, commentOffset, block) {
2693
2796
  function collectRawTextFallbacks(node, file) {
2694
2797
  const fallbacks = /* @__PURE__ */ new Map();
2695
2798
  for (const tag of ts.getJSDocTags(node)) {
2696
- const tagName = normalizeConstraintTagName(tag.tagName.text);
2799
+ const tagName = normalizeConstraintTagName2(tag.tagName.text);
2697
2800
  if (!TAGS_REQUIRING_RAW_TEXT.has(tagName)) continue;
2698
2801
  const commentText = getTagCommentText(tag)?.trim() ?? "";
2699
2802
  if (commentText === "") continue;
@@ -2820,76 +2923,50 @@ function makeParseOptions(extensionRegistry, fieldType, checker, subjectType, ho
2820
2923
  ...hostType !== void 0 && { hostType }
2821
2924
  };
2822
2925
  }
2823
- function makeExplicitScalarMetadata(value) {
2824
- return value === void 0 || value === "" ? void 0 : { value, source: "explicit" };
2825
- }
2826
- function extractExplicitMetadata(node) {
2827
- let apiName;
2828
- let displayName;
2829
- let apiNamePlural;
2830
- let displayNamePlural;
2831
- for (const tag of getLeadingParsedTags(node)) {
2832
- const value = tag.argumentText.trim();
2833
- if (value === "") {
2834
- continue;
2835
- }
2836
- if (tag.normalizedTagName === "apiName") {
2837
- if (tag.target === null) {
2838
- apiName ??= value;
2839
- } else if (tag.target.kind === "variant") {
2840
- if (tag.target.rawText === "singular") {
2841
- apiName ??= value;
2842
- } else if (tag.target.rawText === "plural") {
2843
- apiNamePlural ??= value;
2844
- }
2845
- }
2846
- continue;
2847
- }
2848
- if (tag.normalizedTagName === "displayName") {
2849
- if (tag.target === null) {
2850
- displayName ??= value;
2851
- } else if (tag.target.kind === "variant") {
2852
- if (tag.target.rawText === "singular") {
2853
- displayName ??= value;
2854
- } else if (tag.target.rawText === "plural") {
2855
- displayNamePlural ??= value;
2856
- }
2857
- }
2858
- }
2859
- }
2860
- const resolvedApiName = makeExplicitScalarMetadata(apiName);
2861
- const resolvedDisplayName = makeExplicitScalarMetadata(displayName);
2862
- const resolvedApiNamePlural = makeExplicitScalarMetadata(apiNamePlural);
2863
- const resolvedDisplayNamePlural = makeExplicitScalarMetadata(displayNamePlural);
2864
- const metadata = {
2865
- ...resolvedApiName !== void 0 && { apiName: resolvedApiName },
2866
- ...resolvedDisplayName !== void 0 && { displayName: resolvedDisplayName },
2867
- ...resolvedApiNamePlural !== void 0 && { apiNamePlural: resolvedApiNamePlural },
2868
- ...resolvedDisplayNamePlural !== void 0 && {
2869
- displayNamePlural: resolvedDisplayNamePlural
2870
- }
2926
+ function createAnalyzerMetadataPolicy(input) {
2927
+ return {
2928
+ raw: input,
2929
+ normalized: normalizeMetadataPolicy(input)
2871
2930
  };
2872
- return Object.keys(metadata).length === 0 ? void 0 : metadata;
2873
2931
  }
2874
- function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, buildContext) {
2875
- const explicit = extractExplicitMetadata(node);
2876
- return resolveMetadata(
2877
- {
2878
- ...explicit?.apiName !== void 0 && { apiName: explicit.apiName.value },
2879
- ...explicit?.displayName !== void 0 && { displayName: explicit.displayName.value },
2880
- ...explicit?.apiNamePlural !== void 0 && {
2881
- apiNamePlural: explicit.apiNamePlural.value
2882
- },
2883
- ...explicit?.displayNamePlural !== void 0 && {
2884
- displayNamePlural: explicit.displayNamePlural.value
2885
- }
2886
- },
2887
- getDeclarationMetadataPolicy(metadataPolicy, declarationKind),
2888
- makeMetadataContext("tsdoc", declarationKind, logicalName, buildContext)
2932
+ function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, checker, extensionRegistry, buildContext) {
2933
+ const analysis = analyzeMetadataForNodeWithChecker({
2934
+ checker,
2935
+ node,
2936
+ logicalName,
2937
+ metadata: metadataPolicy.raw,
2938
+ extensions: extensionRegistry?.extensions,
2939
+ ...buildContext !== void 0 && { buildContext }
2940
+ });
2941
+ const resolvedMetadata = analysis?.resolvedMetadata;
2942
+ const declarationPolicy = getDeclarationMetadataPolicy(
2943
+ metadataPolicy.normalized,
2944
+ declarationKind
2889
2945
  );
2946
+ if (resolvedMetadata?.apiName === void 0 && declarationPolicy.apiName.mode === "require-explicit") {
2947
+ throw new Error(
2948
+ `Metadata policy requires explicit apiName for ${declarationKind} "${logicalName}" on the tsdoc surface.`
2949
+ );
2950
+ }
2951
+ if (resolvedMetadata?.displayName === void 0 && declarationPolicy.displayName.mode === "require-explicit") {
2952
+ throw new Error(
2953
+ `Metadata policy requires explicit displayName for ${declarationKind} "${logicalName}" on the tsdoc surface.`
2954
+ );
2955
+ }
2956
+ if (resolvedMetadata?.apiNamePlural === void 0 && declarationPolicy.apiName.pluralization.mode === "require-explicit") {
2957
+ throw new Error(
2958
+ `Metadata policy requires explicit apiNamePlural for ${declarationKind} "${logicalName}" on the tsdoc surface.`
2959
+ );
2960
+ }
2961
+ if (resolvedMetadata?.displayNamePlural === void 0 && declarationPolicy.displayName.pluralization.mode === "require-explicit") {
2962
+ throw new Error(
2963
+ `Metadata policy requires explicit displayNamePlural for ${declarationKind} "${logicalName}" on the tsdoc surface.`
2964
+ );
2965
+ }
2966
+ return resolvedMetadata;
2890
2967
  }
2891
2968
  function analyzeDeclarationRootInfo(declaration, checker, file = "", extensionRegistry, metadataPolicy) {
2892
- const normalizedMetadataPolicy = normalizeMetadataPolicy(metadataPolicy);
2969
+ const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
2893
2970
  const declarationType = checker.getTypeAtLocation(declaration);
2894
2971
  const logicalName = ts3.isClassDeclaration(declaration) ? declaration.name?.text ?? "AnonymousClass" : declaration.name.text;
2895
2972
  const docResult = extractJSDocParseResult(
@@ -2897,12 +2974,20 @@ function analyzeDeclarationRootInfo(declaration, checker, file = "", extensionRe
2897
2974
  file,
2898
2975
  makeParseOptions(extensionRegistry, void 0, checker, declarationType, declarationType)
2899
2976
  );
2900
- const metadata = resolveNodeMetadata(normalizedMetadataPolicy, "type", logicalName, declaration, {
2901
- checker,
2977
+ const metadata = resolveNodeMetadata(
2978
+ normalizedMetadataPolicy,
2979
+ "type",
2980
+ logicalName,
2902
2981
  declaration,
2903
- subjectType: declarationType,
2904
- hostType: declarationType
2905
- });
2982
+ checker,
2983
+ extensionRegistry,
2984
+ {
2985
+ checker,
2986
+ declaration,
2987
+ subjectType: declarationType,
2988
+ hostType: declarationType
2989
+ }
2990
+ );
2906
2991
  return {
2907
2992
  ...metadata !== void 0 && { metadata },
2908
2993
  annotations: docResult.annotations,
@@ -2910,7 +2995,7 @@ function analyzeDeclarationRootInfo(declaration, checker, file = "", extensionRe
2910
2995
  };
2911
2996
  }
2912
2997
  function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, metadataPolicy) {
2913
- const normalizedMetadataPolicy = normalizeMetadataPolicy(metadataPolicy);
2998
+ const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
2914
2999
  const name = classDecl.name?.text ?? "AnonymousClass";
2915
3000
  const fields = [];
2916
3001
  const fieldLayouts = [];
@@ -2965,12 +3050,20 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
2965
3050
  diagnostics,
2966
3051
  normalizedMetadataPolicy
2967
3052
  );
2968
- const metadata = resolveNodeMetadata(normalizedMetadataPolicy, "type", name, classDecl, {
3053
+ const metadata = resolveNodeMetadata(
3054
+ normalizedMetadataPolicy,
3055
+ "type",
3056
+ name,
3057
+ classDecl,
2969
3058
  checker,
2970
- declaration: classDecl,
2971
- subjectType: classType,
2972
- hostType: classType
2973
- });
3059
+ extensionRegistry,
3060
+ {
3061
+ checker,
3062
+ declaration: classDecl,
3063
+ subjectType: classType,
3064
+ hostType: classType
3065
+ }
3066
+ );
2974
3067
  return {
2975
3068
  name,
2976
3069
  ...metadata !== void 0 && { metadata },
@@ -2984,7 +3077,7 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
2984
3077
  };
2985
3078
  }
2986
3079
  function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegistry, metadataPolicy) {
2987
- const normalizedMetadataPolicy = normalizeMetadataPolicy(metadataPolicy);
3080
+ const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
2988
3081
  const name = interfaceDecl.name.text;
2989
3082
  const fields = [];
2990
3083
  const typeRegistry = {};
@@ -3026,12 +3119,20 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
3026
3119
  normalizedMetadataPolicy
3027
3120
  );
3028
3121
  const fieldLayouts = specializedFields.map(() => ({}));
3029
- const metadata = resolveNodeMetadata(normalizedMetadataPolicy, "type", name, interfaceDecl, {
3122
+ const metadata = resolveNodeMetadata(
3123
+ normalizedMetadataPolicy,
3124
+ "type",
3125
+ name,
3126
+ interfaceDecl,
3030
3127
  checker,
3031
- declaration: interfaceDecl,
3032
- subjectType: interfaceType,
3033
- hostType: interfaceType
3034
- });
3128
+ extensionRegistry,
3129
+ {
3130
+ checker,
3131
+ declaration: interfaceDecl,
3132
+ subjectType: interfaceType,
3133
+ hostType: interfaceType
3134
+ }
3135
+ );
3035
3136
  return {
3036
3137
  name,
3037
3138
  ...metadata !== void 0 && { metadata },
@@ -3055,7 +3156,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
3055
3156
  };
3056
3157
  }
3057
3158
  const typeLiteral = typeAlias.type;
3058
- const normalizedMetadataPolicy = normalizeMetadataPolicy(metadataPolicy);
3159
+ const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
3059
3160
  const name = typeAlias.name.text;
3060
3161
  const fields = [];
3061
3162
  const typeRegistry = {};
@@ -3096,12 +3197,20 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
3096
3197
  diagnostics,
3097
3198
  normalizedMetadataPolicy
3098
3199
  );
3099
- const metadata = resolveNodeMetadata(normalizedMetadataPolicy, "type", name, typeAlias, {
3200
+ const metadata = resolveNodeMetadata(
3201
+ normalizedMetadataPolicy,
3202
+ "type",
3203
+ name,
3204
+ typeAlias,
3100
3205
  checker,
3101
- declaration: typeAlias,
3102
- subjectType: aliasType,
3103
- hostType: aliasType
3104
- });
3206
+ extensionRegistry,
3207
+ {
3208
+ checker,
3209
+ declaration: typeAlias,
3210
+ subjectType: aliasType,
3211
+ hostType: aliasType
3212
+ }
3213
+ );
3105
3214
  return {
3106
3215
  ok: true,
3107
3216
  analysis: {
@@ -3354,6 +3463,8 @@ function resolveDiscriminatorApiName(boundType, checker, metadataPolicy) {
3354
3463
  "type",
3355
3464
  getDiscriminatorLogicalName(boundType, declaration, checker),
3356
3465
  declaration,
3466
+ checker,
3467
+ void 0,
3357
3468
  {
3358
3469
  checker,
3359
3470
  declaration,
@@ -3590,12 +3701,20 @@ function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnosti
3590
3701
  annotations.push(defaultAnnotation);
3591
3702
  }
3592
3703
  ({ type, annotations } = applyEnumMemberDisplayNames(type, annotations));
3593
- const metadata = resolveNodeMetadata(metadataPolicy, "field", name, prop, {
3704
+ const metadata = resolveNodeMetadata(
3705
+ metadataPolicy,
3706
+ "field",
3707
+ name,
3708
+ prop,
3594
3709
  checker,
3595
- declaration: prop,
3596
- subjectType: tsType,
3597
- hostType
3598
- });
3710
+ extensionRegistry,
3711
+ {
3712
+ checker,
3713
+ declaration: prop,
3714
+ subjectType: tsType,
3715
+ hostType
3716
+ }
3717
+ );
3599
3718
  return {
3600
3719
  kind: "field",
3601
3720
  name,
@@ -3642,12 +3761,20 @@ function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visitin
3642
3761
  let annotations = [];
3643
3762
  annotations.push(...docResult.annotations);
3644
3763
  ({ type, annotations } = applyEnumMemberDisplayNames(type, annotations));
3645
- const metadata = resolveNodeMetadata(metadataPolicy, "field", name, prop, {
3764
+ const metadata = resolveNodeMetadata(
3765
+ metadataPolicy,
3766
+ "field",
3767
+ name,
3768
+ prop,
3646
3769
  checker,
3647
- declaration: prop,
3648
- subjectType: tsType,
3649
- hostType
3650
- });
3770
+ extensionRegistry,
3771
+ {
3772
+ checker,
3773
+ declaration: prop,
3774
+ subjectType: tsType,
3775
+ hostType
3776
+ }
3777
+ );
3651
3778
  return {
3652
3779
  kind: "field",
3653
3780
  name,
@@ -3776,7 +3903,7 @@ function getTypeNodeRegistrationName(typeNode) {
3776
3903
  }
3777
3904
  return null;
3778
3905
  }
3779
- function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
3906
+ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
3780
3907
  const customType = resolveRegisteredCustomType(sourceNode, extensionRegistry, checker);
3781
3908
  if (customType) {
3782
3909
  return customType;
@@ -3866,7 +3993,7 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
3866
3993
  }
3867
3994
  return { kind: "primitive", primitiveKind: "string" };
3868
3995
  }
3869
- function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
3996
+ function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
3870
3997
  if (!(type.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null))) {
3871
3998
  return null;
3872
3999
  }
@@ -3886,11 +4013,19 @@ function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiti
3886
4013
  file,
3887
4014
  makeParseOptions(extensionRegistry)
3888
4015
  );
3889
- const metadata = resolveNodeMetadata(metadataPolicy, "type", aliasName, aliasDecl, {
4016
+ const metadata = resolveNodeMetadata(
4017
+ metadataPolicy,
4018
+ "type",
4019
+ aliasName,
4020
+ aliasDecl,
3890
4021
  checker,
3891
- declaration: aliasDecl,
3892
- subjectType: aliasType
3893
- });
4022
+ extensionRegistry,
4023
+ {
4024
+ checker,
4025
+ declaration: aliasDecl,
4026
+ subjectType: aliasType
4027
+ }
4028
+ );
3894
4029
  typeRegistry[aliasName] = {
3895
4030
  name: aliasName,
3896
4031
  ...metadata !== void 0 && { metadata },
@@ -3929,7 +4064,7 @@ function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
3929
4064
  const resolved = checker.getTypeFromTypeNode(aliasDecl.type);
3930
4065
  return !!(resolved.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null));
3931
4066
  }
3932
- function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4067
+ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
3933
4068
  const nestedAliasDecl = type.aliasSymbol?.declarations?.find(ts3.isTypeAliasDeclaration);
3934
4069
  if (nestedAliasDecl !== void 0) {
3935
4070
  return resolveAliasedPrimitiveTarget(
@@ -3955,7 +4090,7 @@ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiti
3955
4090
  diagnostics
3956
4091
  );
3957
4092
  }
3958
- function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4093
+ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
3959
4094
  const typeName = getNamedTypeName(type);
3960
4095
  const namedDecl = getNamedTypeDeclaration(type);
3961
4096
  if (typeName && typeName in typeRegistry) {
@@ -3990,11 +4125,19 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
3990
4125
  return result;
3991
4126
  }
3992
4127
  const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
3993
- const metadata = namedDecl !== void 0 ? resolveNodeMetadata(metadataPolicy, "type", typeName, namedDecl, {
4128
+ const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
4129
+ metadataPolicy,
4130
+ "type",
4131
+ typeName,
4132
+ namedDecl,
3994
4133
  checker,
3995
- declaration: namedDecl,
3996
- subjectType: type
3997
- }) : void 0;
4134
+ extensionRegistry,
4135
+ {
4136
+ checker,
4137
+ declaration: namedDecl,
4138
+ subjectType: type
4139
+ }
4140
+ ) : void 0;
3998
4141
  typeRegistry[typeName] = {
3999
4142
  name: typeName,
4000
4143
  ...metadata !== void 0 && { metadata },
@@ -4079,7 +4222,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
4079
4222
  }
4080
4223
  return registerNamed({ kind: "union", members });
4081
4224
  }
4082
- function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4225
+ function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4083
4226
  const typeArgs = isTypeReference(type) ? type.typeArguments : void 0;
4084
4227
  const elementType = typeArgs?.[0];
4085
4228
  const elementSourceNode = extractArrayElementTypeNode(sourceNode, checker);
@@ -4096,7 +4239,7 @@ function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNod
4096
4239
  ) : { kind: "primitive", primitiveKind: "string" };
4097
4240
  return { kind: "array", items };
4098
4241
  }
4099
- function tryResolveRecordType(type, checker, file, typeRegistry, visiting, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4242
+ function tryResolveRecordType(type, checker, file, typeRegistry, visiting, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4100
4243
  if (type.getProperties().length > 0) {
4101
4244
  return null;
4102
4245
  }
@@ -4157,7 +4300,7 @@ function shouldEmitResolvedObjectProperty(property, declaration) {
4157
4300
  }
4158
4301
  return true;
4159
4302
  }
4160
- function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4303
+ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4161
4304
  const collectedDiagnostics = diagnostics ?? [];
4162
4305
  const typeName = getNamedTypeName(type);
4163
4306
  const namedTypeName = typeName ?? void 0;
@@ -4233,11 +4376,19 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
4233
4376
  return recordNode;
4234
4377
  }
4235
4378
  const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
4236
- const metadata = namedDecl !== void 0 ? resolveNodeMetadata(metadataPolicy, "type", registryTypeName, namedDecl, {
4379
+ const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
4380
+ metadataPolicy,
4381
+ "type",
4382
+ registryTypeName,
4383
+ namedDecl,
4237
4384
  checker,
4238
- declaration: namedDecl,
4239
- subjectType: type
4240
- }) : void 0;
4385
+ extensionRegistry,
4386
+ {
4387
+ checker,
4388
+ declaration: namedDecl,
4389
+ subjectType: type
4390
+ }
4391
+ ) : void 0;
4241
4392
  typeRegistry[registryTypeName] = {
4242
4393
  name: registryTypeName,
4243
4394
  ...metadata !== void 0 && { metadata },
@@ -4333,11 +4484,19 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
4333
4484
  };
4334
4485
  if (registryTypeName !== void 0 && shouldRegisterNamedType) {
4335
4486
  const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
4336
- const metadata = namedDecl !== void 0 ? resolveNodeMetadata(metadataPolicy, "type", registryTypeName, namedDecl, {
4487
+ const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
4488
+ metadataPolicy,
4489
+ "type",
4490
+ registryTypeName,
4491
+ namedDecl,
4337
4492
  checker,
4338
- declaration: namedDecl,
4339
- subjectType: type
4340
- }) : void 0;
4493
+ extensionRegistry,
4494
+ {
4495
+ checker,
4496
+ declaration: namedDecl,
4497
+ subjectType: type
4498
+ }
4499
+ ) : void 0;
4341
4500
  typeRegistry[registryTypeName] = {
4342
4501
  name: registryTypeName,
4343
4502
  ...metadata !== void 0 && { metadata },
@@ -5118,7 +5277,7 @@ function generateSchemasFromResolvedType(options, skipNamedDeclaration = false,
5118
5277
  typeRegistry,
5119
5278
  /* @__PURE__ */ new Set(),
5120
5279
  options.sourceNode,
5121
- normalizeMetadataPolicy(options.metadata),
5280
+ createAnalyzerMetadataPolicy(options.metadata),
5122
5281
  options.extensionRegistry,
5123
5282
  diagnostics
5124
5283
  );