@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/cli.js CHANGED
@@ -1854,13 +1854,34 @@ var init_generator2 = __esm({
1854
1854
  });
1855
1855
 
1856
1856
  // src/extensions/registry.ts
1857
+ import {
1858
+ BUILTIN_CONSTRAINT_DEFINITIONS,
1859
+ normalizeConstraintTagName
1860
+ } from "@formspec/core/internals";
1861
+ import {
1862
+ getTagDefinition,
1863
+ normalizeFormSpecTagName
1864
+ } from "@formspec/analysis/internal";
1865
+ function buildConstraintTagSources(extensions) {
1866
+ return extensions.map((extension) => ({
1867
+ extensionId: extension.extensionId,
1868
+ ...extension.constraintTags !== void 0 ? {
1869
+ constraintTags: extension.constraintTags.map((tag) => ({
1870
+ tagName: normalizeFormSpecTagName(tag.tagName)
1871
+ }))
1872
+ } : {}
1873
+ }));
1874
+ }
1857
1875
  function createExtensionRegistry(extensions) {
1876
+ const reservedTagSources = buildConstraintTagSources(extensions);
1858
1877
  const typeMap = /* @__PURE__ */ new Map();
1859
1878
  const typeNameMap = /* @__PURE__ */ new Map();
1860
1879
  const constraintMap = /* @__PURE__ */ new Map();
1861
1880
  const constraintTagMap = /* @__PURE__ */ new Map();
1862
1881
  const builtinBroadeningMap = /* @__PURE__ */ new Map();
1863
1882
  const annotationMap = /* @__PURE__ */ new Map();
1883
+ const metadataSlotMap = /* @__PURE__ */ new Map();
1884
+ const metadataTagMap = /* @__PURE__ */ new Map();
1864
1885
  for (const ext of extensions) {
1865
1886
  if (ext.types !== void 0) {
1866
1887
  for (const type of ext.types) {
@@ -1903,10 +1924,11 @@ function createExtensionRegistry(extensions) {
1903
1924
  }
1904
1925
  if (ext.constraintTags !== void 0) {
1905
1926
  for (const tag of ext.constraintTags) {
1906
- if (constraintTagMap.has(tag.tagName)) {
1907
- throw new Error(`Duplicate custom constraint tag: "@${tag.tagName}"`);
1927
+ const canonicalTagName = normalizeFormSpecTagName(tag.tagName);
1928
+ if (constraintTagMap.has(canonicalTagName)) {
1929
+ throw new Error(`Duplicate custom constraint tag: "@${canonicalTagName}"`);
1908
1930
  }
1909
- constraintTagMap.set(tag.tagName, {
1931
+ constraintTagMap.set(canonicalTagName, {
1910
1932
  extensionId: ext.extensionId,
1911
1933
  registration: tag
1912
1934
  });
@@ -1921,20 +1943,63 @@ function createExtensionRegistry(extensions) {
1921
1943
  annotationMap.set(qualifiedId, annotation);
1922
1944
  }
1923
1945
  }
1946
+ if (ext.metadataSlots !== void 0) {
1947
+ for (const slot of ext.metadataSlots) {
1948
+ if (metadataSlotMap.has(slot.slotId)) {
1949
+ throw new Error(`Duplicate metadata slot ID: "${slot.slotId}"`);
1950
+ }
1951
+ metadataSlotMap.set(slot.slotId, true);
1952
+ const canonicalTagName = normalizeFormSpecTagName(slot.tagName);
1953
+ if (slot.allowBare === false && (slot.qualifiers?.length ?? 0) === 0) {
1954
+ throw new Error(
1955
+ `Metadata tag "@${canonicalTagName}" must allow bare usage or declare at least one qualifier.`
1956
+ );
1957
+ }
1958
+ if (metadataTagMap.has(canonicalTagName)) {
1959
+ throw new Error(`Duplicate metadata tag: "@${canonicalTagName}"`);
1960
+ }
1961
+ if (BUILTIN_METADATA_TAGS.has(canonicalTagName)) {
1962
+ throw new Error(
1963
+ `Metadata tag "@${canonicalTagName}" conflicts with built-in metadata tags.`
1964
+ );
1965
+ }
1966
+ if (constraintTagMap.has(canonicalTagName)) {
1967
+ throw new Error(
1968
+ `Metadata tag "@${canonicalTagName}" conflicts with existing FormSpec tag "@${canonicalTagName}".`
1969
+ );
1970
+ }
1971
+ if (Object.hasOwn(BUILTIN_CONSTRAINT_DEFINITIONS, normalizeConstraintTagName(canonicalTagName))) {
1972
+ throw new Error(
1973
+ `Metadata tag "@${canonicalTagName}" conflicts with existing FormSpec tag "@${normalizeConstraintTagName(canonicalTagName)}".`
1974
+ );
1975
+ }
1976
+ const existingTag = getTagDefinition(canonicalTagName, reservedTagSources);
1977
+ if (existingTag !== null) {
1978
+ throw BUILTIN_METADATA_TAGS.has(existingTag.canonicalName) ? new Error(
1979
+ `Metadata tag "@${canonicalTagName}" conflicts with built-in metadata tags.`
1980
+ ) : new Error(
1981
+ `Metadata tag "@${canonicalTagName}" conflicts with existing FormSpec tag "@${existingTag.canonicalName}".`
1982
+ );
1983
+ }
1984
+ metadataTagMap.set(canonicalTagName, true);
1985
+ }
1986
+ }
1924
1987
  }
1925
1988
  return {
1926
1989
  extensions,
1927
1990
  findType: (typeId) => typeMap.get(typeId),
1928
1991
  findTypeByName: (typeName) => typeNameMap.get(typeName),
1929
1992
  findConstraint: (constraintId) => constraintMap.get(constraintId),
1930
- findConstraintTag: (tagName) => constraintTagMap.get(tagName),
1993
+ findConstraintTag: (tagName) => constraintTagMap.get(normalizeFormSpecTagName(tagName)),
1931
1994
  findBuiltinConstraintBroadening: (typeId, tagName) => builtinBroadeningMap.get(`${typeId}:${tagName}`),
1932
1995
  findAnnotation: (annotationId) => annotationMap.get(annotationId)
1933
1996
  };
1934
1997
  }
1998
+ var BUILTIN_METADATA_TAGS;
1935
1999
  var init_registry = __esm({
1936
2000
  "src/extensions/registry.ts"() {
1937
2001
  "use strict";
2002
+ BUILTIN_METADATA_TAGS = /* @__PURE__ */ new Set(["apiName", "displayName"]);
1938
2003
  }
1939
2004
  });
1940
2005
 
@@ -2019,8 +2084,9 @@ import * as ts from "typescript";
2019
2084
  import {
2020
2085
  checkSyntheticTagApplication,
2021
2086
  extractPathTarget as extractSharedPathTarget,
2022
- getTagDefinition,
2087
+ getTagDefinition as getTagDefinition2,
2023
2088
  hasTypeSemanticCapability,
2089
+ normalizeFormSpecTagName as normalizeFormSpecTagName2,
2024
2090
  parseConstraintTagValue,
2025
2091
  parseDefaultValueTagValue,
2026
2092
  resolveDeclarationPlacement,
@@ -2040,14 +2106,14 @@ import {
2040
2106
  TextRange
2041
2107
  } from "@microsoft/tsdoc";
2042
2108
  import {
2043
- BUILTIN_CONSTRAINT_DEFINITIONS,
2044
- normalizeConstraintTagName,
2109
+ BUILTIN_CONSTRAINT_DEFINITIONS as BUILTIN_CONSTRAINT_DEFINITIONS2,
2110
+ normalizeConstraintTagName as normalizeConstraintTagName2,
2045
2111
  isBuiltinConstraintName
2046
2112
  } from "@formspec/core/internals";
2047
2113
  import "@formspec/core/internals";
2048
2114
  function createFormSpecTSDocConfig(extensionTagNames = []) {
2049
2115
  const config = new TSDocConfiguration();
2050
- for (const tagName of Object.keys(BUILTIN_CONSTRAINT_DEFINITIONS)) {
2116
+ for (const tagName of Object.keys(BUILTIN_CONSTRAINT_DEFINITIONS2)) {
2051
2117
  config.addTagDefinition(
2052
2118
  new TSDocTagDefinition({
2053
2119
  tagName: "@" + tagName,
@@ -2056,7 +2122,7 @@ function createFormSpecTSDocConfig(extensionTagNames = []) {
2056
2122
  })
2057
2123
  );
2058
2124
  }
2059
- for (const tagName of ["displayName", "format", "placeholder"]) {
2125
+ for (const tagName of ["apiName", "displayName", "format", "placeholder"]) {
2060
2126
  config.addTagDefinition(
2061
2127
  new TSDocTagDefinition({
2062
2128
  tagName: "@" + tagName,
@@ -2089,6 +2155,16 @@ function sharedTagValueOptions(options) {
2089
2155
  ...options?.fieldType !== void 0 ? { fieldType: options.fieldType } : {}
2090
2156
  };
2091
2157
  }
2158
+ function getExtensionTypeNames(registry) {
2159
+ if (registry === void 0) {
2160
+ return /* @__PURE__ */ new Set();
2161
+ }
2162
+ return new Set(
2163
+ registry.extensions.flatMap(
2164
+ (ext) => (ext.types ?? []).flatMap((t) => t.tsTypeNames ?? [t.typeName])
2165
+ )
2166
+ );
2167
+ }
2092
2168
  function collectImportedNames(sourceFile) {
2093
2169
  const importedNames = /* @__PURE__ */ new Set();
2094
2170
  for (const statement of sourceFile.statements) {
@@ -2128,6 +2204,9 @@ function isNonReferenceIdentifier(node) {
2128
2204
  return false;
2129
2205
  }
2130
2206
  function statementReferencesImportedName(statement, importedNames) {
2207
+ if (importedNames.size === 0) {
2208
+ return false;
2209
+ }
2131
2210
  let referencesImportedName = false;
2132
2211
  const visit = (node) => {
2133
2212
  if (referencesImportedName) {
@@ -2142,14 +2221,17 @@ function statementReferencesImportedName(statement, importedNames) {
2142
2221
  visit(statement);
2143
2222
  return referencesImportedName;
2144
2223
  }
2145
- function buildSupportingDeclarations(sourceFile) {
2224
+ function buildSupportingDeclarations(sourceFile, extensionTypeNames) {
2146
2225
  const importedNames = collectImportedNames(sourceFile);
2226
+ const importedNamesToSkip = new Set(
2227
+ [...importedNames].filter((name) => !extensionTypeNames.has(name))
2228
+ );
2147
2229
  return sourceFile.statements.filter((statement) => {
2148
2230
  if (ts.isImportDeclaration(statement)) return false;
2149
2231
  if (ts.isImportEqualsDeclaration(statement)) return false;
2150
2232
  if (ts.isExportDeclaration(statement) && statement.moduleSpecifier !== void 0)
2151
2233
  return false;
2152
- if (importedNames.size > 0 && statementReferencesImportedName(statement, importedNames)) {
2234
+ if (statementReferencesImportedName(statement, importedNamesToSkip)) {
2153
2235
  return false;
2154
2236
  }
2155
2237
  return true;
@@ -2302,7 +2384,7 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
2302
2384
  if (placement === null) {
2303
2385
  return [];
2304
2386
  }
2305
- const definition = getTagDefinition(tagName, options?.extensionRegistry?.extensions);
2387
+ const definition = getTagDefinition2(tagName, options?.extensionRegistry?.extensions);
2306
2388
  if (definition === null) {
2307
2389
  return [];
2308
2390
  }
@@ -2406,6 +2488,14 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
2406
2488
  extensionId: extension.extensionId,
2407
2489
  ...extension.constraintTags !== void 0 ? {
2408
2490
  constraintTags: extension.constraintTags.map((tag) => ({ tagName: tag.tagName }))
2491
+ } : {},
2492
+ ...extension.metadataSlots !== void 0 ? {
2493
+ metadataSlots: extension.metadataSlots
2494
+ } : {},
2495
+ ...extension.types !== void 0 ? {
2496
+ customTypes: extension.types.map((t) => ({
2497
+ tsTypeNames: t.tsTypeNames ?? [t.typeName]
2498
+ }))
2409
2499
  } : {}
2410
2500
  }))
2411
2501
  } : {}
@@ -2425,7 +2515,10 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
2425
2515
  function getParser(options) {
2426
2516
  const extensionTagNames = [
2427
2517
  ...options?.extensionRegistry?.extensions.flatMap(
2428
- (extension) => (extension.constraintTags ?? []).map((tag) => tag.tagName)
2518
+ (extension) => (extension.constraintTags ?? []).map((tag) => normalizeFormSpecTagName2(tag.tagName))
2519
+ ) ?? [],
2520
+ ...options?.extensionRegistry?.extensions.flatMap(
2521
+ (extension) => (extension.metadataSlots ?? []).map((slot) => normalizeFormSpecTagName2(slot.tagName))
2429
2522
  ) ?? []
2430
2523
  ].sort();
2431
2524
  const cacheKey = extensionTagNames.join("|");
@@ -2445,7 +2538,16 @@ function getExtensionRegistryCacheKey(registry) {
2445
2538
  (extension) => JSON.stringify({
2446
2539
  extensionId: extension.extensionId,
2447
2540
  typeNames: extension.types?.map((type) => type.typeName) ?? [],
2448
- constraintTags: extension.constraintTags?.map((tag) => tag.tagName) ?? []
2541
+ constraintTags: extension.constraintTags?.map((tag) => normalizeFormSpecTagName2(tag.tagName)) ?? [],
2542
+ metadataSlots: extension.metadataSlots?.map((slot) => ({
2543
+ tagName: normalizeFormSpecTagName2(slot.tagName),
2544
+ declarationKinds: [...slot.declarationKinds].sort(),
2545
+ allowBare: slot.allowBare !== false,
2546
+ qualifiers: (slot.qualifiers ?? []).map((qualifier) => ({
2547
+ qualifier: qualifier.qualifier,
2548
+ ...qualifier.sourceQualifier !== void 0 ? { sourceQualifier: qualifier.sourceQualifier } : {}
2549
+ })).sort((left, right) => left.qualifier.localeCompare(right.qualifier))
2550
+ })) ?? []
2449
2551
  })
2450
2552
  ).join("|");
2451
2553
  }
@@ -2480,7 +2582,8 @@ function parseTSDocTags(node, file = "", options) {
2480
2582
  const rawTextTags = [];
2481
2583
  const sourceFile = node.getSourceFile();
2482
2584
  const sourceText = sourceFile.getFullText();
2483
- const supportingDeclarations = buildSupportingDeclarations(sourceFile);
2585
+ const extensionTypeNames = getExtensionTypeNames(options?.extensionRegistry);
2586
+ const supportingDeclarations = buildSupportingDeclarations(sourceFile, extensionTypeNames);
2484
2587
  const commentRanges = ts.getLeadingCommentRanges(sourceText, node.getFullStart());
2485
2588
  const rawTextFallbacks = collectRawTextFallbacks(node, file);
2486
2589
  if (commentRanges) {
@@ -2518,7 +2621,7 @@ function parseTSDocTags(node, file = "", options) {
2518
2621
  }
2519
2622
  }
2520
2623
  for (const block of docComment.customBlocks) {
2521
- const tagName = normalizeConstraintTagName(block.blockTag.tagName.substring(1));
2624
+ const tagName = normalizeConstraintTagName2(block.blockTag.tagName.substring(1));
2522
2625
  const parsedTag = nextParsedTag(tagName);
2523
2626
  if (tagName === "displayName" || tagName === "format" || tagName === "placeholder") {
2524
2627
  const text2 = getBestBlockPayloadText(parsedTag, commentText, range.pos, block);
@@ -2550,7 +2653,7 @@ function parseTSDocTags(node, file = "", options) {
2550
2653
  }
2551
2654
  if (TAGS_REQUIRING_RAW_TEXT.has(tagName)) continue;
2552
2655
  const text = getBestBlockPayloadText(parsedTag, commentText, range.pos, block);
2553
- const expectedType = isBuiltinConstraintName(tagName) ? BUILTIN_CONSTRAINT_DEFINITIONS[tagName] : void 0;
2656
+ const expectedType = isBuiltinConstraintName(tagName) ? BUILTIN_CONSTRAINT_DEFINITIONS2[tagName] : void 0;
2554
2657
  if (text === "" && expectedType !== "boolean") continue;
2555
2658
  const provenance = parsedTag !== null ? provenanceForParsedTag(parsedTag, sourceFile, file) : provenanceForComment(range, sourceFile, file, tagName);
2556
2659
  const compilerDiagnostics = buildCompilerBackedConstraintDiagnostics(
@@ -2781,7 +2884,7 @@ function getBestBlockPayloadText(tag, commentText, commentOffset, block) {
2781
2884
  function collectRawTextFallbacks(node, file) {
2782
2885
  const fallbacks = /* @__PURE__ */ new Map();
2783
2886
  for (const tag of ts.getJSDocTags(node)) {
2784
- const tagName = normalizeConstraintTagName(tag.tagName.text);
2887
+ const tagName = normalizeConstraintTagName2(tag.tagName.text);
2785
2888
  if (!TAGS_REQUIRING_RAW_TEXT.has(tagName)) continue;
2786
2889
  const commentText = getTagCommentText(tag)?.trim() ?? "";
2787
2890
  if (commentText === "") continue;
@@ -2904,6 +3007,7 @@ var init_jsdoc_constraints = __esm({
2904
3007
  // src/analyzer/class-analyzer.ts
2905
3008
  import * as ts3 from "typescript";
2906
3009
  import {
3010
+ analyzeMetadataForNodeWithChecker,
2907
3011
  parseCommentBlock as parseCommentBlock2
2908
3012
  } from "@formspec/analysis/internal";
2909
3013
  function isObjectType(type) {
@@ -2924,76 +3028,50 @@ function makeParseOptions(extensionRegistry, fieldType, checker, subjectType, ho
2924
3028
  ...hostType !== void 0 && { hostType }
2925
3029
  };
2926
3030
  }
2927
- function makeExplicitScalarMetadata(value) {
2928
- return value === void 0 || value === "" ? void 0 : { value, source: "explicit" };
2929
- }
2930
- function extractExplicitMetadata(node) {
2931
- let apiName;
2932
- let displayName;
2933
- let apiNamePlural;
2934
- let displayNamePlural;
2935
- for (const tag of getLeadingParsedTags(node)) {
2936
- const value = tag.argumentText.trim();
2937
- if (value === "") {
2938
- continue;
2939
- }
2940
- if (tag.normalizedTagName === "apiName") {
2941
- if (tag.target === null) {
2942
- apiName ??= value;
2943
- } else if (tag.target.kind === "variant") {
2944
- if (tag.target.rawText === "singular") {
2945
- apiName ??= value;
2946
- } else if (tag.target.rawText === "plural") {
2947
- apiNamePlural ??= value;
2948
- }
2949
- }
2950
- continue;
2951
- }
2952
- if (tag.normalizedTagName === "displayName") {
2953
- if (tag.target === null) {
2954
- displayName ??= value;
2955
- } else if (tag.target.kind === "variant") {
2956
- if (tag.target.rawText === "singular") {
2957
- displayName ??= value;
2958
- } else if (tag.target.rawText === "plural") {
2959
- displayNamePlural ??= value;
2960
- }
2961
- }
2962
- }
2963
- }
2964
- const resolvedApiName = makeExplicitScalarMetadata(apiName);
2965
- const resolvedDisplayName = makeExplicitScalarMetadata(displayName);
2966
- const resolvedApiNamePlural = makeExplicitScalarMetadata(apiNamePlural);
2967
- const resolvedDisplayNamePlural = makeExplicitScalarMetadata(displayNamePlural);
2968
- const metadata = {
2969
- ...resolvedApiName !== void 0 && { apiName: resolvedApiName },
2970
- ...resolvedDisplayName !== void 0 && { displayName: resolvedDisplayName },
2971
- ...resolvedApiNamePlural !== void 0 && { apiNamePlural: resolvedApiNamePlural },
2972
- ...resolvedDisplayNamePlural !== void 0 && {
2973
- displayNamePlural: resolvedDisplayNamePlural
2974
- }
3031
+ function createAnalyzerMetadataPolicy(input) {
3032
+ return {
3033
+ raw: input,
3034
+ normalized: normalizeMetadataPolicy(input)
2975
3035
  };
2976
- return Object.keys(metadata).length === 0 ? void 0 : metadata;
2977
3036
  }
2978
- function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, buildContext) {
2979
- const explicit = extractExplicitMetadata(node);
2980
- return resolveMetadata(
2981
- {
2982
- ...explicit?.apiName !== void 0 && { apiName: explicit.apiName.value },
2983
- ...explicit?.displayName !== void 0 && { displayName: explicit.displayName.value },
2984
- ...explicit?.apiNamePlural !== void 0 && {
2985
- apiNamePlural: explicit.apiNamePlural.value
2986
- },
2987
- ...explicit?.displayNamePlural !== void 0 && {
2988
- displayNamePlural: explicit.displayNamePlural.value
2989
- }
2990
- },
2991
- getDeclarationMetadataPolicy(metadataPolicy, declarationKind),
2992
- makeMetadataContext("tsdoc", declarationKind, logicalName, buildContext)
3037
+ function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, checker, extensionRegistry, buildContext) {
3038
+ const analysis = analyzeMetadataForNodeWithChecker({
3039
+ checker,
3040
+ node,
3041
+ logicalName,
3042
+ metadata: metadataPolicy.raw,
3043
+ extensions: extensionRegistry?.extensions,
3044
+ ...buildContext !== void 0 && { buildContext }
3045
+ });
3046
+ const resolvedMetadata = analysis?.resolvedMetadata;
3047
+ const declarationPolicy = getDeclarationMetadataPolicy(
3048
+ metadataPolicy.normalized,
3049
+ declarationKind
2993
3050
  );
3051
+ if (resolvedMetadata?.apiName === void 0 && declarationPolicy.apiName.mode === "require-explicit") {
3052
+ throw new Error(
3053
+ `Metadata policy requires explicit apiName for ${declarationKind} "${logicalName}" on the tsdoc surface.`
3054
+ );
3055
+ }
3056
+ if (resolvedMetadata?.displayName === void 0 && declarationPolicy.displayName.mode === "require-explicit") {
3057
+ throw new Error(
3058
+ `Metadata policy requires explicit displayName for ${declarationKind} "${logicalName}" on the tsdoc surface.`
3059
+ );
3060
+ }
3061
+ if (resolvedMetadata?.apiNamePlural === void 0 && declarationPolicy.apiName.pluralization.mode === "require-explicit") {
3062
+ throw new Error(
3063
+ `Metadata policy requires explicit apiNamePlural for ${declarationKind} "${logicalName}" on the tsdoc surface.`
3064
+ );
3065
+ }
3066
+ if (resolvedMetadata?.displayNamePlural === void 0 && declarationPolicy.displayName.pluralization.mode === "require-explicit") {
3067
+ throw new Error(
3068
+ `Metadata policy requires explicit displayNamePlural for ${declarationKind} "${logicalName}" on the tsdoc surface.`
3069
+ );
3070
+ }
3071
+ return resolvedMetadata;
2994
3072
  }
2995
3073
  function analyzeDeclarationRootInfo(declaration, checker, file = "", extensionRegistry, metadataPolicy) {
2996
- const normalizedMetadataPolicy = normalizeMetadataPolicy(metadataPolicy);
3074
+ const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
2997
3075
  const declarationType = checker.getTypeAtLocation(declaration);
2998
3076
  const logicalName = ts3.isClassDeclaration(declaration) ? declaration.name?.text ?? "AnonymousClass" : declaration.name.text;
2999
3077
  const docResult = extractJSDocParseResult(
@@ -3001,12 +3079,20 @@ function analyzeDeclarationRootInfo(declaration, checker, file = "", extensionRe
3001
3079
  file,
3002
3080
  makeParseOptions(extensionRegistry, void 0, checker, declarationType, declarationType)
3003
3081
  );
3004
- const metadata = resolveNodeMetadata(normalizedMetadataPolicy, "type", logicalName, declaration, {
3005
- checker,
3082
+ const metadata = resolveNodeMetadata(
3083
+ normalizedMetadataPolicy,
3084
+ "type",
3085
+ logicalName,
3006
3086
  declaration,
3007
- subjectType: declarationType,
3008
- hostType: declarationType
3009
- });
3087
+ checker,
3088
+ extensionRegistry,
3089
+ {
3090
+ checker,
3091
+ declaration,
3092
+ subjectType: declarationType,
3093
+ hostType: declarationType
3094
+ }
3095
+ );
3010
3096
  return {
3011
3097
  ...metadata !== void 0 && { metadata },
3012
3098
  annotations: docResult.annotations,
@@ -3014,7 +3100,7 @@ function analyzeDeclarationRootInfo(declaration, checker, file = "", extensionRe
3014
3100
  };
3015
3101
  }
3016
3102
  function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, metadataPolicy) {
3017
- const normalizedMetadataPolicy = normalizeMetadataPolicy(metadataPolicy);
3103
+ const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
3018
3104
  const name = classDecl.name?.text ?? "AnonymousClass";
3019
3105
  const fields = [];
3020
3106
  const fieldLayouts = [];
@@ -3069,12 +3155,20 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
3069
3155
  diagnostics,
3070
3156
  normalizedMetadataPolicy
3071
3157
  );
3072
- const metadata = resolveNodeMetadata(normalizedMetadataPolicy, "type", name, classDecl, {
3158
+ const metadata = resolveNodeMetadata(
3159
+ normalizedMetadataPolicy,
3160
+ "type",
3161
+ name,
3162
+ classDecl,
3073
3163
  checker,
3074
- declaration: classDecl,
3075
- subjectType: classType,
3076
- hostType: classType
3077
- });
3164
+ extensionRegistry,
3165
+ {
3166
+ checker,
3167
+ declaration: classDecl,
3168
+ subjectType: classType,
3169
+ hostType: classType
3170
+ }
3171
+ );
3078
3172
  return {
3079
3173
  name,
3080
3174
  ...metadata !== void 0 && { metadata },
@@ -3088,7 +3182,7 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
3088
3182
  };
3089
3183
  }
3090
3184
  function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegistry, metadataPolicy) {
3091
- const normalizedMetadataPolicy = normalizeMetadataPolicy(metadataPolicy);
3185
+ const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
3092
3186
  const name = interfaceDecl.name.text;
3093
3187
  const fields = [];
3094
3188
  const typeRegistry = {};
@@ -3130,12 +3224,20 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
3130
3224
  normalizedMetadataPolicy
3131
3225
  );
3132
3226
  const fieldLayouts = specializedFields.map(() => ({}));
3133
- const metadata = resolveNodeMetadata(normalizedMetadataPolicy, "type", name, interfaceDecl, {
3227
+ const metadata = resolveNodeMetadata(
3228
+ normalizedMetadataPolicy,
3229
+ "type",
3230
+ name,
3231
+ interfaceDecl,
3134
3232
  checker,
3135
- declaration: interfaceDecl,
3136
- subjectType: interfaceType,
3137
- hostType: interfaceType
3138
- });
3233
+ extensionRegistry,
3234
+ {
3235
+ checker,
3236
+ declaration: interfaceDecl,
3237
+ subjectType: interfaceType,
3238
+ hostType: interfaceType
3239
+ }
3240
+ );
3139
3241
  return {
3140
3242
  name,
3141
3243
  ...metadata !== void 0 && { metadata },
@@ -3159,7 +3261,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
3159
3261
  };
3160
3262
  }
3161
3263
  const typeLiteral = typeAlias.type;
3162
- const normalizedMetadataPolicy = normalizeMetadataPolicy(metadataPolicy);
3264
+ const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
3163
3265
  const name = typeAlias.name.text;
3164
3266
  const fields = [];
3165
3267
  const typeRegistry = {};
@@ -3200,12 +3302,20 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
3200
3302
  diagnostics,
3201
3303
  normalizedMetadataPolicy
3202
3304
  );
3203
- const metadata = resolveNodeMetadata(normalizedMetadataPolicy, "type", name, typeAlias, {
3305
+ const metadata = resolveNodeMetadata(
3306
+ normalizedMetadataPolicy,
3307
+ "type",
3308
+ name,
3309
+ typeAlias,
3204
3310
  checker,
3205
- declaration: typeAlias,
3206
- subjectType: aliasType,
3207
- hostType: aliasType
3208
- });
3311
+ extensionRegistry,
3312
+ {
3313
+ checker,
3314
+ declaration: typeAlias,
3315
+ subjectType: aliasType,
3316
+ hostType: aliasType
3317
+ }
3318
+ );
3209
3319
  return {
3210
3320
  ok: true,
3211
3321
  analysis: {
@@ -3458,6 +3568,8 @@ function resolveDiscriminatorApiName(boundType, checker, metadataPolicy) {
3458
3568
  "type",
3459
3569
  getDiscriminatorLogicalName(boundType, declaration, checker),
3460
3570
  declaration,
3571
+ checker,
3572
+ void 0,
3461
3573
  {
3462
3574
  checker,
3463
3575
  declaration,
@@ -3694,12 +3806,20 @@ function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnosti
3694
3806
  annotations.push(defaultAnnotation);
3695
3807
  }
3696
3808
  ({ type, annotations } = applyEnumMemberDisplayNames(type, annotations));
3697
- const metadata = resolveNodeMetadata(metadataPolicy, "field", name, prop, {
3809
+ const metadata = resolveNodeMetadata(
3810
+ metadataPolicy,
3811
+ "field",
3812
+ name,
3813
+ prop,
3698
3814
  checker,
3699
- declaration: prop,
3700
- subjectType: tsType,
3701
- hostType
3702
- });
3815
+ extensionRegistry,
3816
+ {
3817
+ checker,
3818
+ declaration: prop,
3819
+ subjectType: tsType,
3820
+ hostType
3821
+ }
3822
+ );
3703
3823
  return {
3704
3824
  kind: "field",
3705
3825
  name,
@@ -3746,12 +3866,20 @@ function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visitin
3746
3866
  let annotations = [];
3747
3867
  annotations.push(...docResult.annotations);
3748
3868
  ({ type, annotations } = applyEnumMemberDisplayNames(type, annotations));
3749
- const metadata = resolveNodeMetadata(metadataPolicy, "field", name, prop, {
3869
+ const metadata = resolveNodeMetadata(
3870
+ metadataPolicy,
3871
+ "field",
3872
+ name,
3873
+ prop,
3750
3874
  checker,
3751
- declaration: prop,
3752
- subjectType: tsType,
3753
- hostType
3754
- });
3875
+ extensionRegistry,
3876
+ {
3877
+ checker,
3878
+ declaration: prop,
3879
+ subjectType: tsType,
3880
+ hostType
3881
+ }
3882
+ );
3755
3883
  return {
3756
3884
  kind: "field",
3757
3885
  name,
@@ -3880,7 +4008,7 @@ function getTypeNodeRegistrationName(typeNode) {
3880
4008
  }
3881
4009
  return null;
3882
4010
  }
3883
- function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4011
+ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
3884
4012
  const customType = resolveRegisteredCustomType(sourceNode, extensionRegistry, checker);
3885
4013
  if (customType) {
3886
4014
  return customType;
@@ -3970,7 +4098,7 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
3970
4098
  }
3971
4099
  return { kind: "primitive", primitiveKind: "string" };
3972
4100
  }
3973
- function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4101
+ function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
3974
4102
  if (!(type.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null))) {
3975
4103
  return null;
3976
4104
  }
@@ -3990,11 +4118,19 @@ function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiti
3990
4118
  file,
3991
4119
  makeParseOptions(extensionRegistry)
3992
4120
  );
3993
- const metadata = resolveNodeMetadata(metadataPolicy, "type", aliasName, aliasDecl, {
4121
+ const metadata = resolveNodeMetadata(
4122
+ metadataPolicy,
4123
+ "type",
4124
+ aliasName,
4125
+ aliasDecl,
3994
4126
  checker,
3995
- declaration: aliasDecl,
3996
- subjectType: aliasType
3997
- });
4127
+ extensionRegistry,
4128
+ {
4129
+ checker,
4130
+ declaration: aliasDecl,
4131
+ subjectType: aliasType
4132
+ }
4133
+ );
3998
4134
  typeRegistry[aliasName] = {
3999
4135
  name: aliasName,
4000
4136
  ...metadata !== void 0 && { metadata },
@@ -4033,7 +4169,7 @@ function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
4033
4169
  const resolved = checker.getTypeFromTypeNode(aliasDecl.type);
4034
4170
  return !!(resolved.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null));
4035
4171
  }
4036
- function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4172
+ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4037
4173
  const nestedAliasDecl = type.aliasSymbol?.declarations?.find(ts3.isTypeAliasDeclaration);
4038
4174
  if (nestedAliasDecl !== void 0) {
4039
4175
  return resolveAliasedPrimitiveTarget(
@@ -4059,7 +4195,7 @@ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiti
4059
4195
  diagnostics
4060
4196
  );
4061
4197
  }
4062
- function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4198
+ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4063
4199
  const typeName = getNamedTypeName(type);
4064
4200
  const namedDecl = getNamedTypeDeclaration(type);
4065
4201
  if (typeName && typeName in typeRegistry) {
@@ -4094,11 +4230,19 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
4094
4230
  return result;
4095
4231
  }
4096
4232
  const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
4097
- const metadata = namedDecl !== void 0 ? resolveNodeMetadata(metadataPolicy, "type", typeName, namedDecl, {
4233
+ const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
4234
+ metadataPolicy,
4235
+ "type",
4236
+ typeName,
4237
+ namedDecl,
4098
4238
  checker,
4099
- declaration: namedDecl,
4100
- subjectType: type
4101
- }) : void 0;
4239
+ extensionRegistry,
4240
+ {
4241
+ checker,
4242
+ declaration: namedDecl,
4243
+ subjectType: type
4244
+ }
4245
+ ) : void 0;
4102
4246
  typeRegistry[typeName] = {
4103
4247
  name: typeName,
4104
4248
  ...metadata !== void 0 && { metadata },
@@ -4183,7 +4327,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
4183
4327
  }
4184
4328
  return registerNamed({ kind: "union", members });
4185
4329
  }
4186
- function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4330
+ function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4187
4331
  const typeArgs = isTypeReference(type) ? type.typeArguments : void 0;
4188
4332
  const elementType = typeArgs?.[0];
4189
4333
  const elementSourceNode = extractArrayElementTypeNode(sourceNode, checker);
@@ -4200,7 +4344,7 @@ function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNod
4200
4344
  ) : { kind: "primitive", primitiveKind: "string" };
4201
4345
  return { kind: "array", items };
4202
4346
  }
4203
- function tryResolveRecordType(type, checker, file, typeRegistry, visiting, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4347
+ function tryResolveRecordType(type, checker, file, typeRegistry, visiting, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4204
4348
  if (type.getProperties().length > 0) {
4205
4349
  return null;
4206
4350
  }
@@ -4261,7 +4405,7 @@ function shouldEmitResolvedObjectProperty(property, declaration) {
4261
4405
  }
4262
4406
  return true;
4263
4407
  }
4264
- function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = normalizeMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4408
+ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
4265
4409
  const collectedDiagnostics = diagnostics ?? [];
4266
4410
  const typeName = getNamedTypeName(type);
4267
4411
  const namedTypeName = typeName ?? void 0;
@@ -4337,11 +4481,19 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
4337
4481
  return recordNode;
4338
4482
  }
4339
4483
  const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
4340
- const metadata = namedDecl !== void 0 ? resolveNodeMetadata(metadataPolicy, "type", registryTypeName, namedDecl, {
4484
+ const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
4485
+ metadataPolicy,
4486
+ "type",
4487
+ registryTypeName,
4488
+ namedDecl,
4341
4489
  checker,
4342
- declaration: namedDecl,
4343
- subjectType: type
4344
- }) : void 0;
4490
+ extensionRegistry,
4491
+ {
4492
+ checker,
4493
+ declaration: namedDecl,
4494
+ subjectType: type
4495
+ }
4496
+ ) : void 0;
4345
4497
  typeRegistry[registryTypeName] = {
4346
4498
  name: registryTypeName,
4347
4499
  ...metadata !== void 0 && { metadata },
@@ -4437,11 +4589,19 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
4437
4589
  };
4438
4590
  if (registryTypeName !== void 0 && shouldRegisterNamedType) {
4439
4591
  const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
4440
- const metadata = namedDecl !== void 0 ? resolveNodeMetadata(metadataPolicy, "type", registryTypeName, namedDecl, {
4592
+ const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
4593
+ metadataPolicy,
4594
+ "type",
4595
+ registryTypeName,
4596
+ namedDecl,
4441
4597
  checker,
4442
- declaration: namedDecl,
4443
- subjectType: type
4444
- }) : void 0;
4598
+ extensionRegistry,
4599
+ {
4600
+ checker,
4601
+ declaration: namedDecl,
4602
+ subjectType: type
4603
+ }
4604
+ ) : void 0;
4445
4605
  typeRegistry[registryTypeName] = {
4446
4606
  name: registryTypeName,
4447
4607
  ...metadata !== void 0 && { metadata },
@@ -5275,7 +5435,7 @@ function generateSchemasFromResolvedType(options, skipNamedDeclaration = false,
5275
5435
  typeRegistry,
5276
5436
  /* @__PURE__ */ new Set(),
5277
5437
  options.sourceNode,
5278
- normalizeMetadataPolicy(options.metadata),
5438
+ createAnalyzerMetadataPolicy(options.metadata),
5279
5439
  options.extensionRegistry,
5280
5440
  diagnostics
5281
5441
  );