@formspec/build 0.1.0-alpha.32 → 0.1.0-alpha.34
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/analyzer/class-analyzer.d.ts +23 -4
- package/dist/analyzer/class-analyzer.d.ts.map +1 -1
- package/dist/analyzer/program.d.ts +3 -3
- package/dist/analyzer/program.d.ts.map +1 -1
- package/dist/analyzer/tsdoc-parser.d.ts +6 -3
- package/dist/analyzer/tsdoc-parser.d.ts.map +1 -1
- package/dist/browser.cjs +65 -7
- package/dist/browser.cjs.map +1 -1
- package/dist/browser.js +68 -4
- package/dist/browser.js.map +1 -1
- package/dist/build-alpha.d.ts +17 -0
- package/dist/build-beta.d.ts +17 -0
- package/dist/build-internal.d.ts +17 -0
- package/dist/build.d.ts +17 -0
- package/dist/cli.cjs +483 -211
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +466 -186
- package/dist/cli.js.map +1 -1
- package/dist/extensions/registry.d.ts.map +1 -1
- package/dist/generators/class-schema.d.ts +4 -1
- package/dist/generators/class-schema.d.ts.map +1 -1
- package/dist/generators/discovered-schema.d.ts.map +1 -1
- package/dist/generators/mixed-authoring.d.ts.map +1 -1
- package/dist/index.cjs +478 -207
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +465 -186
- package/dist/index.js.map +1 -1
- package/dist/internals.cjs +421 -165
- package/dist/internals.cjs.map +1 -1
- package/dist/internals.d.ts +1 -1
- package/dist/internals.d.ts.map +1 -1
- package/dist/internals.js +427 -163
- package/dist/internals.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -1819,13 +1819,29 @@ var fs = __toESM(require("fs"), 1);
|
|
|
1819
1819
|
var path2 = __toESM(require("path"), 1);
|
|
1820
1820
|
|
|
1821
1821
|
// src/extensions/registry.ts
|
|
1822
|
+
var import_internals3 = require("@formspec/core/internals");
|
|
1823
|
+
var import_internal = require("@formspec/analysis/internal");
|
|
1824
|
+
var BUILTIN_METADATA_TAGS = /* @__PURE__ */ new Set(["apiName", "displayName"]);
|
|
1825
|
+
function buildConstraintTagSources(extensions) {
|
|
1826
|
+
return extensions.map((extension) => ({
|
|
1827
|
+
extensionId: extension.extensionId,
|
|
1828
|
+
...extension.constraintTags !== void 0 ? {
|
|
1829
|
+
constraintTags: extension.constraintTags.map((tag) => ({
|
|
1830
|
+
tagName: (0, import_internal.normalizeFormSpecTagName)(tag.tagName)
|
|
1831
|
+
}))
|
|
1832
|
+
} : {}
|
|
1833
|
+
}));
|
|
1834
|
+
}
|
|
1822
1835
|
function createExtensionRegistry(extensions) {
|
|
1836
|
+
const reservedTagSources = buildConstraintTagSources(extensions);
|
|
1823
1837
|
const typeMap = /* @__PURE__ */ new Map();
|
|
1824
1838
|
const typeNameMap = /* @__PURE__ */ new Map();
|
|
1825
1839
|
const constraintMap = /* @__PURE__ */ new Map();
|
|
1826
1840
|
const constraintTagMap = /* @__PURE__ */ new Map();
|
|
1827
1841
|
const builtinBroadeningMap = /* @__PURE__ */ new Map();
|
|
1828
1842
|
const annotationMap = /* @__PURE__ */ new Map();
|
|
1843
|
+
const metadataSlotMap = /* @__PURE__ */ new Map();
|
|
1844
|
+
const metadataTagMap = /* @__PURE__ */ new Map();
|
|
1829
1845
|
for (const ext of extensions) {
|
|
1830
1846
|
if (ext.types !== void 0) {
|
|
1831
1847
|
for (const type of ext.types) {
|
|
@@ -1868,10 +1884,11 @@ function createExtensionRegistry(extensions) {
|
|
|
1868
1884
|
}
|
|
1869
1885
|
if (ext.constraintTags !== void 0) {
|
|
1870
1886
|
for (const tag of ext.constraintTags) {
|
|
1871
|
-
|
|
1872
|
-
|
|
1887
|
+
const canonicalTagName = (0, import_internal.normalizeFormSpecTagName)(tag.tagName);
|
|
1888
|
+
if (constraintTagMap.has(canonicalTagName)) {
|
|
1889
|
+
throw new Error(`Duplicate custom constraint tag: "@${canonicalTagName}"`);
|
|
1873
1890
|
}
|
|
1874
|
-
constraintTagMap.set(
|
|
1891
|
+
constraintTagMap.set(canonicalTagName, {
|
|
1875
1892
|
extensionId: ext.extensionId,
|
|
1876
1893
|
registration: tag
|
|
1877
1894
|
});
|
|
@@ -1886,13 +1903,54 @@ function createExtensionRegistry(extensions) {
|
|
|
1886
1903
|
annotationMap.set(qualifiedId, annotation);
|
|
1887
1904
|
}
|
|
1888
1905
|
}
|
|
1906
|
+
if (ext.metadataSlots !== void 0) {
|
|
1907
|
+
for (const slot of ext.metadataSlots) {
|
|
1908
|
+
if (metadataSlotMap.has(slot.slotId)) {
|
|
1909
|
+
throw new Error(`Duplicate metadata slot ID: "${slot.slotId}"`);
|
|
1910
|
+
}
|
|
1911
|
+
metadataSlotMap.set(slot.slotId, true);
|
|
1912
|
+
const canonicalTagName = (0, import_internal.normalizeFormSpecTagName)(slot.tagName);
|
|
1913
|
+
if (slot.allowBare === false && (slot.qualifiers?.length ?? 0) === 0) {
|
|
1914
|
+
throw new Error(
|
|
1915
|
+
`Metadata tag "@${canonicalTagName}" must allow bare usage or declare at least one qualifier.`
|
|
1916
|
+
);
|
|
1917
|
+
}
|
|
1918
|
+
if (metadataTagMap.has(canonicalTagName)) {
|
|
1919
|
+
throw new Error(`Duplicate metadata tag: "@${canonicalTagName}"`);
|
|
1920
|
+
}
|
|
1921
|
+
if (BUILTIN_METADATA_TAGS.has(canonicalTagName)) {
|
|
1922
|
+
throw new Error(
|
|
1923
|
+
`Metadata tag "@${canonicalTagName}" conflicts with built-in metadata tags.`
|
|
1924
|
+
);
|
|
1925
|
+
}
|
|
1926
|
+
if (constraintTagMap.has(canonicalTagName)) {
|
|
1927
|
+
throw new Error(
|
|
1928
|
+
`Metadata tag "@${canonicalTagName}" conflicts with existing FormSpec tag "@${canonicalTagName}".`
|
|
1929
|
+
);
|
|
1930
|
+
}
|
|
1931
|
+
if (Object.hasOwn(import_internals3.BUILTIN_CONSTRAINT_DEFINITIONS, (0, import_internals3.normalizeConstraintTagName)(canonicalTagName))) {
|
|
1932
|
+
throw new Error(
|
|
1933
|
+
`Metadata tag "@${canonicalTagName}" conflicts with existing FormSpec tag "@${(0, import_internals3.normalizeConstraintTagName)(canonicalTagName)}".`
|
|
1934
|
+
);
|
|
1935
|
+
}
|
|
1936
|
+
const existingTag = (0, import_internal.getTagDefinition)(canonicalTagName, reservedTagSources);
|
|
1937
|
+
if (existingTag !== null) {
|
|
1938
|
+
throw BUILTIN_METADATA_TAGS.has(existingTag.canonicalName) ? new Error(
|
|
1939
|
+
`Metadata tag "@${canonicalTagName}" conflicts with built-in metadata tags.`
|
|
1940
|
+
) : new Error(
|
|
1941
|
+
`Metadata tag "@${canonicalTagName}" conflicts with existing FormSpec tag "@${existingTag.canonicalName}".`
|
|
1942
|
+
);
|
|
1943
|
+
}
|
|
1944
|
+
metadataTagMap.set(canonicalTagName, true);
|
|
1945
|
+
}
|
|
1946
|
+
}
|
|
1889
1947
|
}
|
|
1890
1948
|
return {
|
|
1891
1949
|
extensions,
|
|
1892
1950
|
findType: (typeId) => typeMap.get(typeId),
|
|
1893
1951
|
findTypeByName: (typeName) => typeNameMap.get(typeName),
|
|
1894
1952
|
findConstraint: (constraintId) => constraintMap.get(constraintId),
|
|
1895
|
-
findConstraintTag: (tagName) => constraintTagMap.get(tagName),
|
|
1953
|
+
findConstraintTag: (tagName) => constraintTagMap.get((0, import_internal.normalizeFormSpecTagName)(tagName)),
|
|
1896
1954
|
findBuiltinConstraintBroadening: (typeId, tagName) => builtinBroadeningMap.get(`${typeId}:${tagName}`),
|
|
1897
1955
|
findAnnotation: (annotationId) => annotationMap.get(annotationId)
|
|
1898
1956
|
};
|
|
@@ -1969,21 +2027,21 @@ var path = __toESM(require("path"), 1);
|
|
|
1969
2027
|
|
|
1970
2028
|
// src/analyzer/class-analyzer.ts
|
|
1971
2029
|
var ts3 = __toESM(require("typescript"), 1);
|
|
1972
|
-
var
|
|
2030
|
+
var import_internal3 = require("@formspec/analysis/internal");
|
|
1973
2031
|
|
|
1974
2032
|
// src/analyzer/jsdoc-constraints.ts
|
|
1975
2033
|
var ts2 = __toESM(require("typescript"), 1);
|
|
1976
2034
|
|
|
1977
2035
|
// src/analyzer/tsdoc-parser.ts
|
|
1978
2036
|
var ts = __toESM(require("typescript"), 1);
|
|
1979
|
-
var
|
|
2037
|
+
var import_internal2 = require("@formspec/analysis/internal");
|
|
1980
2038
|
var import_tsdoc = require("@microsoft/tsdoc");
|
|
1981
|
-
var import_internals3 = require("@formspec/core/internals");
|
|
1982
2039
|
var import_internals4 = require("@formspec/core/internals");
|
|
2040
|
+
var import_internals5 = require("@formspec/core/internals");
|
|
1983
2041
|
var TAGS_REQUIRING_RAW_TEXT = /* @__PURE__ */ new Set(["pattern", "enumOptions", "defaultValue"]);
|
|
1984
2042
|
function createFormSpecTSDocConfig(extensionTagNames = []) {
|
|
1985
2043
|
const config = new import_tsdoc.TSDocConfiguration();
|
|
1986
|
-
for (const tagName of Object.keys(
|
|
2044
|
+
for (const tagName of Object.keys(import_internals4.BUILTIN_CONSTRAINT_DEFINITIONS)) {
|
|
1987
2045
|
config.addTagDefinition(
|
|
1988
2046
|
new import_tsdoc.TSDocTagDefinition({
|
|
1989
2047
|
tagName: "@" + tagName,
|
|
@@ -1992,7 +2050,7 @@ function createFormSpecTSDocConfig(extensionTagNames = []) {
|
|
|
1992
2050
|
})
|
|
1993
2051
|
);
|
|
1994
2052
|
}
|
|
1995
|
-
for (const tagName of ["displayName", "format", "placeholder"]) {
|
|
2053
|
+
for (const tagName of ["apiName", "displayName", "format", "placeholder"]) {
|
|
1996
2054
|
config.addTagDefinition(
|
|
1997
2055
|
new import_tsdoc.TSDocTagDefinition({
|
|
1998
2056
|
tagName: "@" + tagName,
|
|
@@ -2026,6 +2084,16 @@ function sharedTagValueOptions(options) {
|
|
|
2026
2084
|
};
|
|
2027
2085
|
}
|
|
2028
2086
|
var SYNTHETIC_TYPE_FORMAT_FLAGS = ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
|
|
2087
|
+
function getExtensionTypeNames(registry) {
|
|
2088
|
+
if (registry === void 0) {
|
|
2089
|
+
return /* @__PURE__ */ new Set();
|
|
2090
|
+
}
|
|
2091
|
+
return new Set(
|
|
2092
|
+
registry.extensions.flatMap(
|
|
2093
|
+
(ext) => (ext.types ?? []).flatMap((t) => t.tsTypeNames ?? [t.typeName])
|
|
2094
|
+
)
|
|
2095
|
+
);
|
|
2096
|
+
}
|
|
2029
2097
|
function collectImportedNames(sourceFile) {
|
|
2030
2098
|
const importedNames = /* @__PURE__ */ new Set();
|
|
2031
2099
|
for (const statement of sourceFile.statements) {
|
|
@@ -2065,6 +2133,9 @@ function isNonReferenceIdentifier(node) {
|
|
|
2065
2133
|
return false;
|
|
2066
2134
|
}
|
|
2067
2135
|
function statementReferencesImportedName(statement, importedNames) {
|
|
2136
|
+
if (importedNames.size === 0) {
|
|
2137
|
+
return false;
|
|
2138
|
+
}
|
|
2068
2139
|
let referencesImportedName = false;
|
|
2069
2140
|
const visit = (node) => {
|
|
2070
2141
|
if (referencesImportedName) {
|
|
@@ -2079,14 +2150,17 @@ function statementReferencesImportedName(statement, importedNames) {
|
|
|
2079
2150
|
visit(statement);
|
|
2080
2151
|
return referencesImportedName;
|
|
2081
2152
|
}
|
|
2082
|
-
function buildSupportingDeclarations(sourceFile) {
|
|
2153
|
+
function buildSupportingDeclarations(sourceFile, extensionTypeNames) {
|
|
2083
2154
|
const importedNames = collectImportedNames(sourceFile);
|
|
2155
|
+
const importedNamesToSkip = new Set(
|
|
2156
|
+
[...importedNames].filter((name) => !extensionTypeNames.has(name))
|
|
2157
|
+
);
|
|
2084
2158
|
return sourceFile.statements.filter((statement) => {
|
|
2085
2159
|
if (ts.isImportDeclaration(statement)) return false;
|
|
2086
2160
|
if (ts.isImportEqualsDeclaration(statement)) return false;
|
|
2087
2161
|
if (ts.isExportDeclaration(statement) && statement.moduleSpecifier !== void 0)
|
|
2088
2162
|
return false;
|
|
2089
|
-
if (
|
|
2163
|
+
if (statementReferencesImportedName(statement, importedNamesToSkip)) {
|
|
2090
2164
|
return false;
|
|
2091
2165
|
}
|
|
2092
2166
|
return true;
|
|
@@ -2132,12 +2206,12 @@ function supportsConstraintCapability(type, checker, capability) {
|
|
|
2132
2206
|
if (capability === void 0) {
|
|
2133
2207
|
return true;
|
|
2134
2208
|
}
|
|
2135
|
-
if ((0,
|
|
2209
|
+
if ((0, import_internal2.hasTypeSemanticCapability)(type, checker, capability)) {
|
|
2136
2210
|
return true;
|
|
2137
2211
|
}
|
|
2138
2212
|
if (capability === "string-like") {
|
|
2139
2213
|
const itemType = getArrayElementType(type, checker);
|
|
2140
|
-
return itemType !== null && (0,
|
|
2214
|
+
return itemType !== null && (0, import_internal2.hasTypeSemanticCapability)(itemType, checker, capability);
|
|
2141
2215
|
}
|
|
2142
2216
|
return false;
|
|
2143
2217
|
}
|
|
@@ -2227,7 +2301,7 @@ function hasBuiltinConstraintBroadening(tagName, options) {
|
|
|
2227
2301
|
return broadenedTypeId !== void 0 && options?.extensionRegistry?.findBuiltinConstraintBroadening(broadenedTypeId, tagName) !== void 0;
|
|
2228
2302
|
}
|
|
2229
2303
|
function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, parsedTag, provenance, supportingDeclarations, options) {
|
|
2230
|
-
if (!(0,
|
|
2304
|
+
if (!(0, import_internals4.isBuiltinConstraintName)(tagName)) {
|
|
2231
2305
|
return [];
|
|
2232
2306
|
}
|
|
2233
2307
|
const checker = options?.checker;
|
|
@@ -2235,11 +2309,11 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2235
2309
|
if (checker === void 0 || subjectType === void 0) {
|
|
2236
2310
|
return [];
|
|
2237
2311
|
}
|
|
2238
|
-
const placement = (0,
|
|
2312
|
+
const placement = (0, import_internal2.resolveDeclarationPlacement)(node);
|
|
2239
2313
|
if (placement === null) {
|
|
2240
2314
|
return [];
|
|
2241
2315
|
}
|
|
2242
|
-
const definition = (0,
|
|
2316
|
+
const definition = (0, import_internal2.getTagDefinition)(tagName, options?.extensionRegistry?.extensions);
|
|
2243
2317
|
if (definition === null) {
|
|
2244
2318
|
return [];
|
|
2245
2319
|
}
|
|
@@ -2273,7 +2347,7 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2273
2347
|
)
|
|
2274
2348
|
];
|
|
2275
2349
|
}
|
|
2276
|
-
const resolution = (0,
|
|
2350
|
+
const resolution = (0, import_internal2.resolvePathTargetType)(subjectType, checker, target.path.segments);
|
|
2277
2351
|
if (resolution.kind === "missing-property") {
|
|
2278
2352
|
return [
|
|
2279
2353
|
makeDiagnostic(
|
|
@@ -2330,7 +2404,7 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2330
2404
|
const subjectTypeText = checker.typeToString(subjectType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
|
|
2331
2405
|
const hostType = options?.hostType ?? subjectType;
|
|
2332
2406
|
const hostTypeText = checker.typeToString(hostType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
|
|
2333
|
-
const result = (0,
|
|
2407
|
+
const result = (0, import_internal2.checkSyntheticTagApplication)({
|
|
2334
2408
|
tagName,
|
|
2335
2409
|
placement,
|
|
2336
2410
|
hostType: hostTypeText,
|
|
@@ -2343,6 +2417,14 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2343
2417
|
extensionId: extension.extensionId,
|
|
2344
2418
|
...extension.constraintTags !== void 0 ? {
|
|
2345
2419
|
constraintTags: extension.constraintTags.map((tag) => ({ tagName: tag.tagName }))
|
|
2420
|
+
} : {},
|
|
2421
|
+
...extension.metadataSlots !== void 0 ? {
|
|
2422
|
+
metadataSlots: extension.metadataSlots
|
|
2423
|
+
} : {},
|
|
2424
|
+
...extension.types !== void 0 ? {
|
|
2425
|
+
customTypes: extension.types.map((t) => ({
|
|
2426
|
+
tsTypeNames: t.tsTypeNames ?? [t.typeName]
|
|
2427
|
+
}))
|
|
2346
2428
|
} : {}
|
|
2347
2429
|
}))
|
|
2348
2430
|
} : {}
|
|
@@ -2364,7 +2446,10 @@ var parseResultCache = /* @__PURE__ */ new Map();
|
|
|
2364
2446
|
function getParser(options) {
|
|
2365
2447
|
const extensionTagNames = [
|
|
2366
2448
|
...options?.extensionRegistry?.extensions.flatMap(
|
|
2367
|
-
(extension) => (extension.constraintTags ?? []).map((tag) => tag.tagName)
|
|
2449
|
+
(extension) => (extension.constraintTags ?? []).map((tag) => (0, import_internal2.normalizeFormSpecTagName)(tag.tagName))
|
|
2450
|
+
) ?? [],
|
|
2451
|
+
...options?.extensionRegistry?.extensions.flatMap(
|
|
2452
|
+
(extension) => (extension.metadataSlots ?? []).map((slot) => (0, import_internal2.normalizeFormSpecTagName)(slot.tagName))
|
|
2368
2453
|
) ?? []
|
|
2369
2454
|
].sort();
|
|
2370
2455
|
const cacheKey = extensionTagNames.join("|");
|
|
@@ -2384,7 +2469,16 @@ function getExtensionRegistryCacheKey(registry) {
|
|
|
2384
2469
|
(extension) => JSON.stringify({
|
|
2385
2470
|
extensionId: extension.extensionId,
|
|
2386
2471
|
typeNames: extension.types?.map((type) => type.typeName) ?? [],
|
|
2387
|
-
constraintTags: extension.constraintTags?.map((tag) => tag.tagName) ?? []
|
|
2472
|
+
constraintTags: extension.constraintTags?.map((tag) => (0, import_internal2.normalizeFormSpecTagName)(tag.tagName)) ?? [],
|
|
2473
|
+
metadataSlots: extension.metadataSlots?.map((slot) => ({
|
|
2474
|
+
tagName: (0, import_internal2.normalizeFormSpecTagName)(slot.tagName),
|
|
2475
|
+
declarationKinds: [...slot.declarationKinds].sort(),
|
|
2476
|
+
allowBare: slot.allowBare !== false,
|
|
2477
|
+
qualifiers: (slot.qualifiers ?? []).map((qualifier) => ({
|
|
2478
|
+
qualifier: qualifier.qualifier,
|
|
2479
|
+
...qualifier.sourceQualifier !== void 0 ? { sourceQualifier: qualifier.sourceQualifier } : {}
|
|
2480
|
+
})).sort((left, right) => left.qualifier.localeCompare(right.qualifier))
|
|
2481
|
+
})) ?? []
|
|
2388
2482
|
})
|
|
2389
2483
|
).join("|");
|
|
2390
2484
|
}
|
|
@@ -2419,7 +2513,8 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
2419
2513
|
const rawTextTags = [];
|
|
2420
2514
|
const sourceFile = node.getSourceFile();
|
|
2421
2515
|
const sourceText = sourceFile.getFullText();
|
|
2422
|
-
const
|
|
2516
|
+
const extensionTypeNames = getExtensionTypeNames(options?.extensionRegistry);
|
|
2517
|
+
const supportingDeclarations = buildSupportingDeclarations(sourceFile, extensionTypeNames);
|
|
2423
2518
|
const commentRanges = ts.getLeadingCommentRanges(sourceText, node.getFullStart());
|
|
2424
2519
|
const rawTextFallbacks = collectRawTextFallbacks(node, file);
|
|
2425
2520
|
if (commentRanges) {
|
|
@@ -2436,7 +2531,7 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
2436
2531
|
import_tsdoc.TextRange.fromStringRange(sourceText, range.pos, range.end)
|
|
2437
2532
|
);
|
|
2438
2533
|
const docComment = parserContext.docComment;
|
|
2439
|
-
const parsedComment = (0,
|
|
2534
|
+
const parsedComment = (0, import_internal2.parseCommentBlock)(
|
|
2440
2535
|
commentText,
|
|
2441
2536
|
sharedCommentSyntaxOptions(options, range.pos)
|
|
2442
2537
|
);
|
|
@@ -2457,7 +2552,7 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
2457
2552
|
}
|
|
2458
2553
|
}
|
|
2459
2554
|
for (const block of docComment.customBlocks) {
|
|
2460
|
-
const tagName = (0,
|
|
2555
|
+
const tagName = (0, import_internals4.normalizeConstraintTagName)(block.blockTag.tagName.substring(1));
|
|
2461
2556
|
const parsedTag = nextParsedTag(tagName);
|
|
2462
2557
|
if (tagName === "displayName" || tagName === "format" || tagName === "placeholder") {
|
|
2463
2558
|
const text2 = getBestBlockPayloadText(parsedTag, commentText, range.pos, block);
|
|
@@ -2489,7 +2584,7 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
2489
2584
|
}
|
|
2490
2585
|
if (TAGS_REQUIRING_RAW_TEXT.has(tagName)) continue;
|
|
2491
2586
|
const text = getBestBlockPayloadText(parsedTag, commentText, range.pos, block);
|
|
2492
|
-
const expectedType = (0,
|
|
2587
|
+
const expectedType = (0, import_internals4.isBuiltinConstraintName)(tagName) ? import_internals4.BUILTIN_CONSTRAINT_DEFINITIONS[tagName] : void 0;
|
|
2493
2588
|
if (text === "" && expectedType !== "boolean") continue;
|
|
2494
2589
|
const provenance = parsedTag !== null ? provenanceForParsedTag(parsedTag, sourceFile, file) : provenanceForComment(range, sourceFile, file, tagName);
|
|
2495
2590
|
const compilerDiagnostics = buildCompilerBackedConstraintDiagnostics(
|
|
@@ -2505,7 +2600,7 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
2505
2600
|
diagnostics.push(...compilerDiagnostics);
|
|
2506
2601
|
continue;
|
|
2507
2602
|
}
|
|
2508
|
-
const constraintNode = (0,
|
|
2603
|
+
const constraintNode = (0, import_internal2.parseConstraintTagValue)(
|
|
2509
2604
|
tagName,
|
|
2510
2605
|
text,
|
|
2511
2606
|
provenance,
|
|
@@ -2575,7 +2670,7 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
2575
2670
|
if (text === "") continue;
|
|
2576
2671
|
const provenance = provenanceForParsedTag(rawTextTag.tag, sourceFile, file);
|
|
2577
2672
|
if (rawTextTag.tag.normalizedTagName === "defaultValue") {
|
|
2578
|
-
const defaultValueNode = (0,
|
|
2673
|
+
const defaultValueNode = (0, import_internal2.parseDefaultValueTagValue)(text, provenance);
|
|
2579
2674
|
annotations.push(defaultValueNode);
|
|
2580
2675
|
continue;
|
|
2581
2676
|
}
|
|
@@ -2592,7 +2687,7 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
2592
2687
|
diagnostics.push(...compilerDiagnostics);
|
|
2593
2688
|
continue;
|
|
2594
2689
|
}
|
|
2595
|
-
const constraintNode = (0,
|
|
2690
|
+
const constraintNode = (0, import_internal2.parseConstraintTagValue)(
|
|
2596
2691
|
rawTextTag.tag.normalizedTagName,
|
|
2597
2692
|
text,
|
|
2598
2693
|
provenance,
|
|
@@ -2609,7 +2704,7 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
2609
2704
|
if (text === "") continue;
|
|
2610
2705
|
const provenance = fallback.provenance;
|
|
2611
2706
|
if (tagName === "defaultValue") {
|
|
2612
|
-
const defaultValueNode = (0,
|
|
2707
|
+
const defaultValueNode = (0, import_internal2.parseDefaultValueTagValue)(text, provenance);
|
|
2613
2708
|
annotations.push(defaultValueNode);
|
|
2614
2709
|
continue;
|
|
2615
2710
|
}
|
|
@@ -2626,7 +2721,7 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
2626
2721
|
diagnostics.push(...compilerDiagnostics);
|
|
2627
2722
|
continue;
|
|
2628
2723
|
}
|
|
2629
|
-
const constraintNode = (0,
|
|
2724
|
+
const constraintNode = (0, import_internal2.parseConstraintTagValue)(
|
|
2630
2725
|
tagName,
|
|
2631
2726
|
text,
|
|
2632
2727
|
provenance,
|
|
@@ -2652,7 +2747,7 @@ function extractDisplayNameMetadata(node) {
|
|
|
2652
2747
|
if (range.kind !== ts.SyntaxKind.MultiLineCommentTrivia) continue;
|
|
2653
2748
|
const commentText = sourceText.substring(range.pos, range.end);
|
|
2654
2749
|
if (!commentText.startsWith("/**")) continue;
|
|
2655
|
-
const parsed = (0,
|
|
2750
|
+
const parsed = (0, import_internal2.parseCommentBlock)(commentText);
|
|
2656
2751
|
for (const tag of parsed.tags) {
|
|
2657
2752
|
if (tag.normalizedTagName !== "displayName") {
|
|
2658
2753
|
continue;
|
|
@@ -2708,7 +2803,7 @@ function getSharedPayloadText(tag, commentText, commentOffset) {
|
|
|
2708
2803
|
if (tag.payloadSpan === null) {
|
|
2709
2804
|
return "";
|
|
2710
2805
|
}
|
|
2711
|
-
return (0,
|
|
2806
|
+
return (0, import_internal2.sliceCommentSpan)(commentText, tag.payloadSpan, {
|
|
2712
2807
|
offset: commentOffset
|
|
2713
2808
|
}).trim();
|
|
2714
2809
|
}
|
|
@@ -2720,7 +2815,7 @@ function getBestBlockPayloadText(tag, commentText, commentOffset, block) {
|
|
|
2720
2815
|
function collectRawTextFallbacks(node, file) {
|
|
2721
2816
|
const fallbacks = /* @__PURE__ */ new Map();
|
|
2722
2817
|
for (const tag of ts.getJSDocTags(node)) {
|
|
2723
|
-
const tagName = (0,
|
|
2818
|
+
const tagName = (0, import_internals4.normalizeConstraintTagName)(tag.tagName.text);
|
|
2724
2819
|
if (!TAGS_REQUIRING_RAW_TEXT.has(tagName)) continue;
|
|
2725
2820
|
const commentText = getTagCommentText(tag)?.trim() ?? "";
|
|
2726
2821
|
if (commentText === "") continue;
|
|
@@ -2734,7 +2829,7 @@ function collectRawTextFallbacks(node, file) {
|
|
|
2734
2829
|
return fallbacks;
|
|
2735
2830
|
}
|
|
2736
2831
|
function isMemberTargetDisplayName(text) {
|
|
2737
|
-
return (0,
|
|
2832
|
+
return (0, import_internal2.parseTagSyntax)("displayName", text).target !== null;
|
|
2738
2833
|
}
|
|
2739
2834
|
function provenanceForComment(range, sourceFile, file, tagName) {
|
|
2740
2835
|
const { line, character } = sourceFile.getLineAndCharacterOfPosition(range.pos);
|
|
@@ -2827,6 +2922,9 @@ function extractDefaultValueAnnotation(initializer, file = "") {
|
|
|
2827
2922
|
function isObjectType(type) {
|
|
2828
2923
|
return !!(type.flags & ts3.TypeFlags.Object);
|
|
2829
2924
|
}
|
|
2925
|
+
function isIntersectionType(type) {
|
|
2926
|
+
return !!(type.flags & ts3.TypeFlags.Intersection);
|
|
2927
|
+
}
|
|
2830
2928
|
function isTypeReference(type) {
|
|
2831
2929
|
return !!(type.flags & ts3.TypeFlags.Object) && !!(type.objectFlags & ts3.ObjectFlags.Reference);
|
|
2832
2930
|
}
|
|
@@ -2847,76 +2945,51 @@ function makeParseOptions(extensionRegistry, fieldType, checker, subjectType, ho
|
|
|
2847
2945
|
...hostType !== void 0 && { hostType }
|
|
2848
2946
|
};
|
|
2849
2947
|
}
|
|
2850
|
-
function
|
|
2851
|
-
return
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
let displayName;
|
|
2856
|
-
let apiNamePlural;
|
|
2857
|
-
let displayNamePlural;
|
|
2858
|
-
for (const tag of getLeadingParsedTags(node)) {
|
|
2859
|
-
const value = tag.argumentText.trim();
|
|
2860
|
-
if (value === "") {
|
|
2861
|
-
continue;
|
|
2862
|
-
}
|
|
2863
|
-
if (tag.normalizedTagName === "apiName") {
|
|
2864
|
-
if (tag.target === null) {
|
|
2865
|
-
apiName ??= value;
|
|
2866
|
-
} else if (tag.target.kind === "variant") {
|
|
2867
|
-
if (tag.target.rawText === "singular") {
|
|
2868
|
-
apiName ??= value;
|
|
2869
|
-
} else if (tag.target.rawText === "plural") {
|
|
2870
|
-
apiNamePlural ??= value;
|
|
2871
|
-
}
|
|
2872
|
-
}
|
|
2873
|
-
continue;
|
|
2874
|
-
}
|
|
2875
|
-
if (tag.normalizedTagName === "displayName") {
|
|
2876
|
-
if (tag.target === null) {
|
|
2877
|
-
displayName ??= value;
|
|
2878
|
-
} else if (tag.target.kind === "variant") {
|
|
2879
|
-
if (tag.target.rawText === "singular") {
|
|
2880
|
-
displayName ??= value;
|
|
2881
|
-
} else if (tag.target.rawText === "plural") {
|
|
2882
|
-
displayNamePlural ??= value;
|
|
2883
|
-
}
|
|
2884
|
-
}
|
|
2885
|
-
}
|
|
2886
|
-
}
|
|
2887
|
-
const resolvedApiName = makeExplicitScalarMetadata(apiName);
|
|
2888
|
-
const resolvedDisplayName = makeExplicitScalarMetadata(displayName);
|
|
2889
|
-
const resolvedApiNamePlural = makeExplicitScalarMetadata(apiNamePlural);
|
|
2890
|
-
const resolvedDisplayNamePlural = makeExplicitScalarMetadata(displayNamePlural);
|
|
2891
|
-
const metadata = {
|
|
2892
|
-
...resolvedApiName !== void 0 && { apiName: resolvedApiName },
|
|
2893
|
-
...resolvedDisplayName !== void 0 && { displayName: resolvedDisplayName },
|
|
2894
|
-
...resolvedApiNamePlural !== void 0 && { apiNamePlural: resolvedApiNamePlural },
|
|
2895
|
-
...resolvedDisplayNamePlural !== void 0 && {
|
|
2896
|
-
displayNamePlural: resolvedDisplayNamePlural
|
|
2897
|
-
}
|
|
2948
|
+
function createAnalyzerMetadataPolicy(input, discriminator) {
|
|
2949
|
+
return {
|
|
2950
|
+
raw: input,
|
|
2951
|
+
normalized: normalizeMetadataPolicy(input),
|
|
2952
|
+
discriminator
|
|
2898
2953
|
};
|
|
2899
|
-
return Object.keys(metadata).length === 0 ? void 0 : metadata;
|
|
2900
2954
|
}
|
|
2901
|
-
function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, buildContext) {
|
|
2902
|
-
const
|
|
2903
|
-
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
getDeclarationMetadataPolicy(metadataPolicy, declarationKind),
|
|
2915
|
-
makeMetadataContext("tsdoc", declarationKind, logicalName, buildContext)
|
|
2955
|
+
function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, checker, extensionRegistry, buildContext) {
|
|
2956
|
+
const analysis = (0, import_internal3.analyzeMetadataForNodeWithChecker)({
|
|
2957
|
+
checker,
|
|
2958
|
+
node,
|
|
2959
|
+
logicalName,
|
|
2960
|
+
metadata: metadataPolicy.raw,
|
|
2961
|
+
extensions: extensionRegistry?.extensions,
|
|
2962
|
+
...buildContext !== void 0 && { buildContext }
|
|
2963
|
+
});
|
|
2964
|
+
const resolvedMetadata = analysis?.resolvedMetadata;
|
|
2965
|
+
const declarationPolicy = getDeclarationMetadataPolicy(
|
|
2966
|
+
metadataPolicy.normalized,
|
|
2967
|
+
declarationKind
|
|
2916
2968
|
);
|
|
2969
|
+
if (resolvedMetadata?.apiName === void 0 && declarationPolicy.apiName.mode === "require-explicit") {
|
|
2970
|
+
throw new Error(
|
|
2971
|
+
`Metadata policy requires explicit apiName for ${declarationKind} "${logicalName}" on the tsdoc surface.`
|
|
2972
|
+
);
|
|
2973
|
+
}
|
|
2974
|
+
if (resolvedMetadata?.displayName === void 0 && declarationPolicy.displayName.mode === "require-explicit") {
|
|
2975
|
+
throw new Error(
|
|
2976
|
+
`Metadata policy requires explicit displayName for ${declarationKind} "${logicalName}" on the tsdoc surface.`
|
|
2977
|
+
);
|
|
2978
|
+
}
|
|
2979
|
+
if (resolvedMetadata?.apiNamePlural === void 0 && declarationPolicy.apiName.pluralization.mode === "require-explicit") {
|
|
2980
|
+
throw new Error(
|
|
2981
|
+
`Metadata policy requires explicit apiNamePlural for ${declarationKind} "${logicalName}" on the tsdoc surface.`
|
|
2982
|
+
);
|
|
2983
|
+
}
|
|
2984
|
+
if (resolvedMetadata?.displayNamePlural === void 0 && declarationPolicy.displayName.pluralization.mode === "require-explicit") {
|
|
2985
|
+
throw new Error(
|
|
2986
|
+
`Metadata policy requires explicit displayNamePlural for ${declarationKind} "${logicalName}" on the tsdoc surface.`
|
|
2987
|
+
);
|
|
2988
|
+
}
|
|
2989
|
+
return resolvedMetadata;
|
|
2917
2990
|
}
|
|
2918
2991
|
function analyzeDeclarationRootInfo(declaration, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
2919
|
-
const normalizedMetadataPolicy =
|
|
2992
|
+
const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
|
|
2920
2993
|
const declarationType = checker.getTypeAtLocation(declaration);
|
|
2921
2994
|
const logicalName = ts3.isClassDeclaration(declaration) ? declaration.name?.text ?? "AnonymousClass" : declaration.name.text;
|
|
2922
2995
|
const docResult = extractJSDocParseResult(
|
|
@@ -2924,20 +2997,31 @@ function analyzeDeclarationRootInfo(declaration, checker, file = "", extensionRe
|
|
|
2924
2997
|
file,
|
|
2925
2998
|
makeParseOptions(extensionRegistry, void 0, checker, declarationType, declarationType)
|
|
2926
2999
|
);
|
|
2927
|
-
const metadata = resolveNodeMetadata(
|
|
2928
|
-
|
|
3000
|
+
const metadata = resolveNodeMetadata(
|
|
3001
|
+
normalizedMetadataPolicy,
|
|
3002
|
+
"type",
|
|
3003
|
+
logicalName,
|
|
2929
3004
|
declaration,
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
3005
|
+
checker,
|
|
3006
|
+
extensionRegistry,
|
|
3007
|
+
{
|
|
3008
|
+
checker,
|
|
3009
|
+
declaration,
|
|
3010
|
+
subjectType: declarationType,
|
|
3011
|
+
hostType: declarationType
|
|
3012
|
+
}
|
|
3013
|
+
);
|
|
2933
3014
|
return {
|
|
2934
3015
|
...metadata !== void 0 && { metadata },
|
|
2935
3016
|
annotations: docResult.annotations,
|
|
2936
3017
|
diagnostics: docResult.diagnostics
|
|
2937
3018
|
};
|
|
2938
3019
|
}
|
|
2939
|
-
function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
2940
|
-
const normalizedMetadataPolicy =
|
|
3020
|
+
function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, metadataPolicy, discriminatorOptions) {
|
|
3021
|
+
const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(
|
|
3022
|
+
metadataPolicy,
|
|
3023
|
+
discriminatorOptions
|
|
3024
|
+
);
|
|
2941
3025
|
const name = classDecl.name?.text ?? "AnonymousClass";
|
|
2942
3026
|
const fields = [];
|
|
2943
3027
|
const fieldLayouts = [];
|
|
@@ -2992,12 +3076,20 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
|
|
|
2992
3076
|
diagnostics,
|
|
2993
3077
|
normalizedMetadataPolicy
|
|
2994
3078
|
);
|
|
2995
|
-
const metadata = resolveNodeMetadata(
|
|
3079
|
+
const metadata = resolveNodeMetadata(
|
|
3080
|
+
normalizedMetadataPolicy,
|
|
3081
|
+
"type",
|
|
3082
|
+
name,
|
|
3083
|
+
classDecl,
|
|
2996
3084
|
checker,
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3085
|
+
extensionRegistry,
|
|
3086
|
+
{
|
|
3087
|
+
checker,
|
|
3088
|
+
declaration: classDecl,
|
|
3089
|
+
subjectType: classType,
|
|
3090
|
+
hostType: classType
|
|
3091
|
+
}
|
|
3092
|
+
);
|
|
3001
3093
|
return {
|
|
3002
3094
|
name,
|
|
3003
3095
|
...metadata !== void 0 && { metadata },
|
|
@@ -3010,8 +3102,11 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
|
|
|
3010
3102
|
staticMethods
|
|
3011
3103
|
};
|
|
3012
3104
|
}
|
|
3013
|
-
function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
3014
|
-
const normalizedMetadataPolicy =
|
|
3105
|
+
function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegistry, metadataPolicy, discriminatorOptions) {
|
|
3106
|
+
const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(
|
|
3107
|
+
metadataPolicy,
|
|
3108
|
+
discriminatorOptions
|
|
3109
|
+
);
|
|
3015
3110
|
const name = interfaceDecl.name.text;
|
|
3016
3111
|
const fields = [];
|
|
3017
3112
|
const typeRegistry = {};
|
|
@@ -3053,12 +3148,20 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
|
|
|
3053
3148
|
normalizedMetadataPolicy
|
|
3054
3149
|
);
|
|
3055
3150
|
const fieldLayouts = specializedFields.map(() => ({}));
|
|
3056
|
-
const metadata = resolveNodeMetadata(
|
|
3151
|
+
const metadata = resolveNodeMetadata(
|
|
3152
|
+
normalizedMetadataPolicy,
|
|
3153
|
+
"type",
|
|
3154
|
+
name,
|
|
3155
|
+
interfaceDecl,
|
|
3057
3156
|
checker,
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3157
|
+
extensionRegistry,
|
|
3158
|
+
{
|
|
3159
|
+
checker,
|
|
3160
|
+
declaration: interfaceDecl,
|
|
3161
|
+
subjectType: interfaceType,
|
|
3162
|
+
hostType: interfaceType
|
|
3163
|
+
}
|
|
3164
|
+
);
|
|
3062
3165
|
return {
|
|
3063
3166
|
name,
|
|
3064
3167
|
...metadata !== void 0 && { metadata },
|
|
@@ -3071,19 +3174,31 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
|
|
|
3071
3174
|
staticMethods: []
|
|
3072
3175
|
};
|
|
3073
3176
|
}
|
|
3074
|
-
function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
3075
|
-
|
|
3177
|
+
function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry, metadataPolicy, discriminatorOptions) {
|
|
3178
|
+
const members = getObjectLikeTypeAliasMembers(typeAlias.type);
|
|
3179
|
+
if (members === null) {
|
|
3076
3180
|
const sourceFile = typeAlias.getSourceFile();
|
|
3077
3181
|
const { line } = sourceFile.getLineAndCharacterOfPosition(typeAlias.getStart());
|
|
3078
3182
|
const kindDesc = ts3.SyntaxKind[typeAlias.type.kind] ?? "unknown";
|
|
3079
3183
|
return {
|
|
3080
3184
|
ok: false,
|
|
3081
|
-
error: `Type alias "${typeAlias.name.text}" at line ${String(line + 1)} is not an object type
|
|
3185
|
+
error: `Type alias "${typeAlias.name.text}" at line ${String(line + 1)} is not an object-like type alias (found ${kindDesc})`
|
|
3082
3186
|
};
|
|
3083
3187
|
}
|
|
3084
|
-
const
|
|
3085
|
-
|
|
3188
|
+
const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(
|
|
3189
|
+
metadataPolicy,
|
|
3190
|
+
discriminatorOptions
|
|
3191
|
+
);
|
|
3086
3192
|
const name = typeAlias.name.text;
|
|
3193
|
+
const duplicatePropertyNames = findDuplicateObjectLikeTypeAliasPropertyNames(members);
|
|
3194
|
+
if (duplicatePropertyNames.length > 0) {
|
|
3195
|
+
const sourceFile = typeAlias.getSourceFile();
|
|
3196
|
+
const { line } = sourceFile.getLineAndCharacterOfPosition(typeAlias.getStart());
|
|
3197
|
+
return {
|
|
3198
|
+
ok: false,
|
|
3199
|
+
error: `Type alias "${name}" at line ${String(line + 1)} contains duplicate property names across object-like members: ${duplicatePropertyNames.join(", ")}`
|
|
3200
|
+
};
|
|
3201
|
+
}
|
|
3087
3202
|
const fields = [];
|
|
3088
3203
|
const typeRegistry = {};
|
|
3089
3204
|
const diagnostics = [];
|
|
@@ -3096,7 +3211,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
|
|
|
3096
3211
|
const annotations = [...typeAliasDoc.annotations];
|
|
3097
3212
|
diagnostics.push(...typeAliasDoc.diagnostics);
|
|
3098
3213
|
const visiting = /* @__PURE__ */ new Set();
|
|
3099
|
-
for (const member of
|
|
3214
|
+
for (const member of members) {
|
|
3100
3215
|
if (ts3.isPropertySignature(member)) {
|
|
3101
3216
|
const fieldNode = analyzeInterfacePropertyToIR(
|
|
3102
3217
|
member,
|
|
@@ -3123,12 +3238,20 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
|
|
|
3123
3238
|
diagnostics,
|
|
3124
3239
|
normalizedMetadataPolicy
|
|
3125
3240
|
);
|
|
3126
|
-
const metadata = resolveNodeMetadata(
|
|
3241
|
+
const metadata = resolveNodeMetadata(
|
|
3242
|
+
normalizedMetadataPolicy,
|
|
3243
|
+
"type",
|
|
3244
|
+
name,
|
|
3245
|
+
typeAlias,
|
|
3127
3246
|
checker,
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3247
|
+
extensionRegistry,
|
|
3248
|
+
{
|
|
3249
|
+
checker,
|
|
3250
|
+
declaration: typeAlias,
|
|
3251
|
+
subjectType: aliasType,
|
|
3252
|
+
hostType: aliasType
|
|
3253
|
+
}
|
|
3254
|
+
);
|
|
3132
3255
|
return {
|
|
3133
3256
|
ok: true,
|
|
3134
3257
|
analysis: {
|
|
@@ -3169,7 +3292,7 @@ function getLeadingParsedTags(node) {
|
|
|
3169
3292
|
if (!commentText.startsWith("/**")) {
|
|
3170
3293
|
continue;
|
|
3171
3294
|
}
|
|
3172
|
-
parsedTags.push(...(0,
|
|
3295
|
+
parsedTags.push(...(0, import_internal3.parseCommentBlock)(commentText, { offset: range.pos }).tags);
|
|
3173
3296
|
}
|
|
3174
3297
|
return parsedTags;
|
|
3175
3298
|
}
|
|
@@ -3197,15 +3320,43 @@ function isNullishSemanticType(type) {
|
|
|
3197
3320
|
}
|
|
3198
3321
|
return type.isUnion() && type.types.some((member) => isNullishSemanticType(member));
|
|
3199
3322
|
}
|
|
3200
|
-
function isStringLikeSemanticType(type) {
|
|
3323
|
+
function isStringLikeSemanticType(type, checker, seen = /* @__PURE__ */ new Set()) {
|
|
3324
|
+
if (seen.has(type)) {
|
|
3325
|
+
return false;
|
|
3326
|
+
}
|
|
3327
|
+
seen.add(type);
|
|
3201
3328
|
if (type.flags & ts3.TypeFlags.StringLike) {
|
|
3202
3329
|
return true;
|
|
3203
3330
|
}
|
|
3204
3331
|
if (type.isUnion()) {
|
|
3205
|
-
return type.types.length > 0 && type.types.every((member) => isStringLikeSemanticType(member));
|
|
3332
|
+
return type.types.length > 0 && type.types.every((member) => isStringLikeSemanticType(member, checker, seen));
|
|
3333
|
+
}
|
|
3334
|
+
const baseConstraint = checker.getBaseConstraintOfType(type);
|
|
3335
|
+
if (baseConstraint !== void 0 && baseConstraint !== type) {
|
|
3336
|
+
return isStringLikeSemanticType(baseConstraint, checker, seen);
|
|
3206
3337
|
}
|
|
3207
3338
|
return false;
|
|
3208
3339
|
}
|
|
3340
|
+
function getObjectLikeTypeAliasMembers(typeNode) {
|
|
3341
|
+
if (ts3.isParenthesizedTypeNode(typeNode)) {
|
|
3342
|
+
return getObjectLikeTypeAliasMembers(typeNode.type);
|
|
3343
|
+
}
|
|
3344
|
+
if (ts3.isTypeLiteralNode(typeNode)) {
|
|
3345
|
+
return [...typeNode.members];
|
|
3346
|
+
}
|
|
3347
|
+
if (ts3.isIntersectionTypeNode(typeNode)) {
|
|
3348
|
+
const members = [];
|
|
3349
|
+
for (const intersectionMember of typeNode.types) {
|
|
3350
|
+
const resolvedMembers = getObjectLikeTypeAliasMembers(intersectionMember);
|
|
3351
|
+
if (resolvedMembers === null) {
|
|
3352
|
+
return null;
|
|
3353
|
+
}
|
|
3354
|
+
members.push(...resolvedMembers);
|
|
3355
|
+
}
|
|
3356
|
+
return members;
|
|
3357
|
+
}
|
|
3358
|
+
return null;
|
|
3359
|
+
}
|
|
3209
3360
|
function extractDiscriminatorDirective(node, file, diagnostics) {
|
|
3210
3361
|
const discriminatorTags = getLeadingParsedTags(node).filter(
|
|
3211
3362
|
(tag) => tag.normalizedTagName === "discriminator"
|
|
@@ -3312,7 +3463,7 @@ function validateDiscriminatorDirective(node, checker, file, diagnostics) {
|
|
|
3312
3463
|
);
|
|
3313
3464
|
return null;
|
|
3314
3465
|
}
|
|
3315
|
-
if (!isStringLikeSemanticType(property.type)) {
|
|
3466
|
+
if (!isStringLikeSemanticType(property.type, checker)) {
|
|
3316
3467
|
diagnostics.push(
|
|
3317
3468
|
makeAnalysisDiagnostic(
|
|
3318
3469
|
"TYPE_MISMATCH",
|
|
@@ -3339,8 +3490,8 @@ function getConcreteTypeArgumentForDiscriminator(node, subjectType, checker, typ
|
|
|
3339
3490
|
const localTypeParameter = node.typeParameters?.[typeParameterIndex];
|
|
3340
3491
|
return localTypeParameter === void 0 ? null : checker.getTypeAtLocation(localTypeParameter);
|
|
3341
3492
|
}
|
|
3342
|
-
function resolveLiteralDiscriminatorPropertyValue(boundType,
|
|
3343
|
-
const propertySymbol = boundType.getProperty(
|
|
3493
|
+
function resolveLiteralDiscriminatorPropertyValue(boundType, propertyName, checker, provenance, diagnostics) {
|
|
3494
|
+
const propertySymbol = boundType.getProperty(propertyName);
|
|
3344
3495
|
if (propertySymbol === void 0) {
|
|
3345
3496
|
return void 0;
|
|
3346
3497
|
}
|
|
@@ -3371,6 +3522,9 @@ function resolveLiteralDiscriminatorPropertyValue(boundType, fieldName, checker,
|
|
|
3371
3522
|
}
|
|
3372
3523
|
return void 0;
|
|
3373
3524
|
}
|
|
3525
|
+
function getDiscriminatorIdentityPropertyNames(fieldName) {
|
|
3526
|
+
return fieldName === "object" ? ["object"] : [fieldName, "object"];
|
|
3527
|
+
}
|
|
3374
3528
|
function resolveDiscriminatorApiName(boundType, checker, metadataPolicy) {
|
|
3375
3529
|
const declaration = resolveNamedDiscriminatorDeclaration(boundType, checker);
|
|
3376
3530
|
if (declaration === null) {
|
|
@@ -3381,6 +3535,8 @@ function resolveDiscriminatorApiName(boundType, checker, metadataPolicy) {
|
|
|
3381
3535
|
"type",
|
|
3382
3536
|
getDiscriminatorLogicalName(boundType, declaration, checker),
|
|
3383
3537
|
declaration,
|
|
3538
|
+
checker,
|
|
3539
|
+
void 0,
|
|
3384
3540
|
{
|
|
3385
3541
|
checker,
|
|
3386
3542
|
declaration,
|
|
@@ -3389,6 +3545,10 @@ function resolveDiscriminatorApiName(boundType, checker, metadataPolicy) {
|
|
|
3389
3545
|
);
|
|
3390
3546
|
return metadata?.apiName;
|
|
3391
3547
|
}
|
|
3548
|
+
function applyDiscriminatorApiNamePrefix(value, discriminatorOptions) {
|
|
3549
|
+
const prefix = discriminatorOptions?.apiNamePrefix;
|
|
3550
|
+
return prefix === void 0 || prefix === "" ? value : `${prefix}${value}`;
|
|
3551
|
+
}
|
|
3392
3552
|
function resolveNamedDiscriminatorDeclaration(type, checker, seen = /* @__PURE__ */ new Set()) {
|
|
3393
3553
|
if (seen.has(type)) {
|
|
3394
3554
|
return null;
|
|
@@ -3443,22 +3603,27 @@ function resolveDiscriminatorValue(boundType, fieldName, checker, provenance, di
|
|
|
3443
3603
|
return null;
|
|
3444
3604
|
}
|
|
3445
3605
|
}
|
|
3446
|
-
const
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3606
|
+
for (const identityPropertyName of getDiscriminatorIdentityPropertyNames(fieldName)) {
|
|
3607
|
+
const literalIdentityValue = resolveLiteralDiscriminatorPropertyValue(
|
|
3608
|
+
boundType,
|
|
3609
|
+
identityPropertyName,
|
|
3610
|
+
checker,
|
|
3611
|
+
provenance,
|
|
3612
|
+
diagnostics
|
|
3613
|
+
);
|
|
3614
|
+
if (literalIdentityValue === null) {
|
|
3615
|
+
return null;
|
|
3616
|
+
}
|
|
3617
|
+
if (literalIdentityValue !== void 0) {
|
|
3618
|
+
return literalIdentityValue;
|
|
3619
|
+
}
|
|
3455
3620
|
}
|
|
3456
3621
|
const apiName = resolveDiscriminatorApiName(boundType, checker, metadataPolicy);
|
|
3457
3622
|
if (apiName?.source === "explicit") {
|
|
3458
|
-
return apiName.value;
|
|
3623
|
+
return applyDiscriminatorApiNamePrefix(apiName.value, metadataPolicy.discriminator);
|
|
3459
3624
|
}
|
|
3460
3625
|
if (apiName?.source === "inferred") {
|
|
3461
|
-
return apiName.value;
|
|
3626
|
+
return applyDiscriminatorApiNamePrefix(apiName.value, metadataPolicy.discriminator);
|
|
3462
3627
|
}
|
|
3463
3628
|
diagnostics.push(
|
|
3464
3629
|
makeAnalysisDiagnostic(
|
|
@@ -3521,15 +3686,20 @@ function buildInstantiatedReferenceName(baseName, typeArguments, checker) {
|
|
|
3521
3686
|
return renderedArguments.length === 0 ? baseName : `${baseName}__${renderedArguments.join("__")}`;
|
|
3522
3687
|
}
|
|
3523
3688
|
function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy, extensionRegistry, diagnostics) {
|
|
3524
|
-
const
|
|
3525
|
-
if (
|
|
3689
|
+
const sourceTypeNode = sourceNode === void 0 ? void 0 : extractTypeNodeFromSource(sourceNode);
|
|
3690
|
+
if (sourceTypeNode === void 0) {
|
|
3526
3691
|
return [];
|
|
3527
3692
|
}
|
|
3528
|
-
const
|
|
3529
|
-
|
|
3693
|
+
const unwrapParentheses = (typeNode) => ts3.isParenthesizedTypeNode(typeNode) ? unwrapParentheses(typeNode.type) : typeNode;
|
|
3694
|
+
const directTypeNode = unwrapParentheses(sourceTypeNode);
|
|
3695
|
+
const referenceTypeNode = ts3.isTypeReferenceNode(directTypeNode) ? directTypeNode : (() => {
|
|
3696
|
+
const resolvedTypeNode = resolveAliasedTypeNode(directTypeNode, checker);
|
|
3697
|
+
return ts3.isTypeReferenceNode(resolvedTypeNode) ? resolvedTypeNode : null;
|
|
3698
|
+
})();
|
|
3699
|
+
if (referenceTypeNode?.typeArguments === void 0) {
|
|
3530
3700
|
return [];
|
|
3531
3701
|
}
|
|
3532
|
-
return
|
|
3702
|
+
return referenceTypeNode.typeArguments.map((argumentNode) => {
|
|
3533
3703
|
const argumentType = checker.getTypeFromTypeNode(argumentNode);
|
|
3534
3704
|
return {
|
|
3535
3705
|
tsType: argumentType,
|
|
@@ -3617,12 +3787,20 @@ function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnosti
|
|
|
3617
3787
|
annotations.push(defaultAnnotation);
|
|
3618
3788
|
}
|
|
3619
3789
|
({ type, annotations } = applyEnumMemberDisplayNames(type, annotations));
|
|
3620
|
-
const metadata = resolveNodeMetadata(
|
|
3790
|
+
const metadata = resolveNodeMetadata(
|
|
3791
|
+
metadataPolicy,
|
|
3792
|
+
"field",
|
|
3793
|
+
name,
|
|
3794
|
+
prop,
|
|
3621
3795
|
checker,
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3796
|
+
extensionRegistry,
|
|
3797
|
+
{
|
|
3798
|
+
checker,
|
|
3799
|
+
declaration: prop,
|
|
3800
|
+
subjectType: tsType,
|
|
3801
|
+
hostType
|
|
3802
|
+
}
|
|
3803
|
+
);
|
|
3626
3804
|
return {
|
|
3627
3805
|
kind: "field",
|
|
3628
3806
|
name,
|
|
@@ -3635,10 +3813,10 @@ function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnosti
|
|
|
3635
3813
|
};
|
|
3636
3814
|
}
|
|
3637
3815
|
function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visiting, diagnostics, hostType, metadataPolicy, extensionRegistry) {
|
|
3638
|
-
|
|
3816
|
+
const name = getAnalyzableObjectLikePropertyName(prop.name);
|
|
3817
|
+
if (name === null) {
|
|
3639
3818
|
return null;
|
|
3640
3819
|
}
|
|
3641
|
-
const name = prop.name.text;
|
|
3642
3820
|
const tsType = checker.getTypeAtLocation(prop);
|
|
3643
3821
|
const optional = prop.questionToken !== void 0;
|
|
3644
3822
|
const provenance = provenanceForNode(prop, file);
|
|
@@ -3669,12 +3847,20 @@ function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visitin
|
|
|
3669
3847
|
let annotations = [];
|
|
3670
3848
|
annotations.push(...docResult.annotations);
|
|
3671
3849
|
({ type, annotations } = applyEnumMemberDisplayNames(type, annotations));
|
|
3672
|
-
const metadata = resolveNodeMetadata(
|
|
3850
|
+
const metadata = resolveNodeMetadata(
|
|
3851
|
+
metadataPolicy,
|
|
3852
|
+
"field",
|
|
3853
|
+
name,
|
|
3854
|
+
prop,
|
|
3673
3855
|
checker,
|
|
3674
|
-
|
|
3675
|
-
|
|
3676
|
-
|
|
3677
|
-
|
|
3856
|
+
extensionRegistry,
|
|
3857
|
+
{
|
|
3858
|
+
checker,
|
|
3859
|
+
declaration: prop,
|
|
3860
|
+
subjectType: tsType,
|
|
3861
|
+
hostType
|
|
3862
|
+
}
|
|
3863
|
+
);
|
|
3678
3864
|
return {
|
|
3679
3865
|
kind: "field",
|
|
3680
3866
|
name,
|
|
@@ -3686,6 +3872,31 @@ function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visitin
|
|
|
3686
3872
|
provenance
|
|
3687
3873
|
};
|
|
3688
3874
|
}
|
|
3875
|
+
function findDuplicateObjectLikeTypeAliasPropertyNames(members) {
|
|
3876
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3877
|
+
const duplicates = /* @__PURE__ */ new Set();
|
|
3878
|
+
for (const member of members) {
|
|
3879
|
+
if (!ts3.isPropertySignature(member)) {
|
|
3880
|
+
continue;
|
|
3881
|
+
}
|
|
3882
|
+
const name = getAnalyzableObjectLikePropertyName(member.name);
|
|
3883
|
+
if (name === null) {
|
|
3884
|
+
continue;
|
|
3885
|
+
}
|
|
3886
|
+
if (seen.has(name)) {
|
|
3887
|
+
duplicates.add(name);
|
|
3888
|
+
continue;
|
|
3889
|
+
}
|
|
3890
|
+
seen.add(name);
|
|
3891
|
+
}
|
|
3892
|
+
return [...duplicates].sort();
|
|
3893
|
+
}
|
|
3894
|
+
function getAnalyzableObjectLikePropertyName(name) {
|
|
3895
|
+
if (!ts3.isIdentifier(name)) {
|
|
3896
|
+
return null;
|
|
3897
|
+
}
|
|
3898
|
+
return name.text;
|
|
3899
|
+
}
|
|
3689
3900
|
function applyEnumMemberDisplayNames(type, annotations) {
|
|
3690
3901
|
if (!annotations.some(
|
|
3691
3902
|
(annotation) => annotation.annotationKind === "displayName" && annotation.value.trim().startsWith(":")
|
|
@@ -3803,7 +4014,7 @@ function getTypeNodeRegistrationName(typeNode) {
|
|
|
3803
4014
|
}
|
|
3804
4015
|
return null;
|
|
3805
4016
|
}
|
|
3806
|
-
function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
4017
|
+
function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
3807
4018
|
const customType = resolveRegisteredCustomType(sourceNode, extensionRegistry, checker);
|
|
3808
4019
|
if (customType) {
|
|
3809
4020
|
return customType;
|
|
@@ -3878,6 +4089,23 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
|
|
|
3878
4089
|
diagnostics
|
|
3879
4090
|
);
|
|
3880
4091
|
}
|
|
4092
|
+
if (isIntersectionType(type)) {
|
|
4093
|
+
const sourceTypeNode = sourceNode === void 0 ? void 0 : extractTypeNodeFromSource(sourceNode);
|
|
4094
|
+
const resolvedSourceTypeNode = sourceTypeNode === void 0 ? void 0 : resolveAliasedTypeNode(sourceTypeNode, checker);
|
|
4095
|
+
if (resolvedSourceTypeNode !== void 0 && getObjectLikeTypeAliasMembers(resolvedSourceTypeNode) !== null) {
|
|
4096
|
+
return resolveObjectType(
|
|
4097
|
+
type,
|
|
4098
|
+
checker,
|
|
4099
|
+
file,
|
|
4100
|
+
typeRegistry,
|
|
4101
|
+
visiting,
|
|
4102
|
+
sourceNode,
|
|
4103
|
+
metadataPolicy,
|
|
4104
|
+
extensionRegistry,
|
|
4105
|
+
diagnostics
|
|
4106
|
+
);
|
|
4107
|
+
}
|
|
4108
|
+
}
|
|
3881
4109
|
if (isObjectType(type)) {
|
|
3882
4110
|
return resolveObjectType(
|
|
3883
4111
|
type,
|
|
@@ -3893,7 +4121,7 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
|
|
|
3893
4121
|
}
|
|
3894
4122
|
return { kind: "primitive", primitiveKind: "string" };
|
|
3895
4123
|
}
|
|
3896
|
-
function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
4124
|
+
function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
3897
4125
|
if (!(type.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null))) {
|
|
3898
4126
|
return null;
|
|
3899
4127
|
}
|
|
@@ -3913,11 +4141,19 @@ function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiti
|
|
|
3913
4141
|
file,
|
|
3914
4142
|
makeParseOptions(extensionRegistry)
|
|
3915
4143
|
);
|
|
3916
|
-
const metadata = resolveNodeMetadata(
|
|
4144
|
+
const metadata = resolveNodeMetadata(
|
|
4145
|
+
metadataPolicy,
|
|
4146
|
+
"type",
|
|
4147
|
+
aliasName,
|
|
4148
|
+
aliasDecl,
|
|
3917
4149
|
checker,
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
4150
|
+
extensionRegistry,
|
|
4151
|
+
{
|
|
4152
|
+
checker,
|
|
4153
|
+
declaration: aliasDecl,
|
|
4154
|
+
subjectType: aliasType
|
|
4155
|
+
}
|
|
4156
|
+
);
|
|
3921
4157
|
typeRegistry[aliasName] = {
|
|
3922
4158
|
name: aliasName,
|
|
3923
4159
|
...metadata !== void 0 && { metadata },
|
|
@@ -3956,7 +4192,7 @@ function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
|
|
|
3956
4192
|
const resolved = checker.getTypeFromTypeNode(aliasDecl.type);
|
|
3957
4193
|
return !!(resolved.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null));
|
|
3958
4194
|
}
|
|
3959
|
-
function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy =
|
|
4195
|
+
function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
3960
4196
|
const nestedAliasDecl = type.aliasSymbol?.declarations?.find(ts3.isTypeAliasDeclaration);
|
|
3961
4197
|
if (nestedAliasDecl !== void 0) {
|
|
3962
4198
|
return resolveAliasedPrimitiveTarget(
|
|
@@ -3982,7 +4218,7 @@ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiti
|
|
|
3982
4218
|
diagnostics
|
|
3983
4219
|
);
|
|
3984
4220
|
}
|
|
3985
|
-
function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
4221
|
+
function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
3986
4222
|
const typeName = getNamedTypeName(type);
|
|
3987
4223
|
const namedDecl = getNamedTypeDeclaration(type);
|
|
3988
4224
|
if (typeName && typeName in typeRegistry) {
|
|
@@ -4017,11 +4253,19 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
4017
4253
|
return result;
|
|
4018
4254
|
}
|
|
4019
4255
|
const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
|
|
4020
|
-
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
4256
|
+
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
4257
|
+
metadataPolicy,
|
|
4258
|
+
"type",
|
|
4259
|
+
typeName,
|
|
4260
|
+
namedDecl,
|
|
4021
4261
|
checker,
|
|
4022
|
-
|
|
4023
|
-
|
|
4024
|
-
|
|
4262
|
+
extensionRegistry,
|
|
4263
|
+
{
|
|
4264
|
+
checker,
|
|
4265
|
+
declaration: namedDecl,
|
|
4266
|
+
subjectType: type
|
|
4267
|
+
}
|
|
4268
|
+
) : void 0;
|
|
4025
4269
|
typeRegistry[typeName] = {
|
|
4026
4270
|
name: typeName,
|
|
4027
4271
|
...metadata !== void 0 && { metadata },
|
|
@@ -4106,7 +4350,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
4106
4350
|
}
|
|
4107
4351
|
return registerNamed({ kind: "union", members });
|
|
4108
4352
|
}
|
|
4109
|
-
function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
4353
|
+
function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
4110
4354
|
const typeArgs = isTypeReference(type) ? type.typeArguments : void 0;
|
|
4111
4355
|
const elementType = typeArgs?.[0];
|
|
4112
4356
|
const elementSourceNode = extractArrayElementTypeNode(sourceNode, checker);
|
|
@@ -4123,7 +4367,7 @@ function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
4123
4367
|
) : { kind: "primitive", primitiveKind: "string" };
|
|
4124
4368
|
return { kind: "array", items };
|
|
4125
4369
|
}
|
|
4126
|
-
function tryResolveRecordType(type, checker, file, typeRegistry, visiting, metadataPolicy =
|
|
4370
|
+
function tryResolveRecordType(type, checker, file, typeRegistry, visiting, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
4127
4371
|
if (type.getProperties().length > 0) {
|
|
4128
4372
|
return null;
|
|
4129
4373
|
}
|
|
@@ -4184,7 +4428,7 @@ function shouldEmitResolvedObjectProperty(property, declaration) {
|
|
|
4184
4428
|
}
|
|
4185
4429
|
return true;
|
|
4186
4430
|
}
|
|
4187
|
-
function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
4431
|
+
function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
4188
4432
|
const collectedDiagnostics = diagnostics ?? [];
|
|
4189
4433
|
const typeName = getNamedTypeName(type);
|
|
4190
4434
|
const namedTypeName = typeName ?? void 0;
|
|
@@ -4241,7 +4485,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
4241
4485
|
};
|
|
4242
4486
|
}
|
|
4243
4487
|
}
|
|
4244
|
-
const recordNode = tryResolveRecordType(
|
|
4488
|
+
const recordNode = isObjectType(type) ? tryResolveRecordType(
|
|
4245
4489
|
type,
|
|
4246
4490
|
checker,
|
|
4247
4491
|
file,
|
|
@@ -4250,7 +4494,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
4250
4494
|
metadataPolicy,
|
|
4251
4495
|
extensionRegistry,
|
|
4252
4496
|
collectedDiagnostics
|
|
4253
|
-
);
|
|
4497
|
+
) : null;
|
|
4254
4498
|
if (recordNode) {
|
|
4255
4499
|
visiting.delete(type);
|
|
4256
4500
|
if (registryTypeName !== void 0 && shouldRegisterNamedType) {
|
|
@@ -4260,11 +4504,19 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
4260
4504
|
return recordNode;
|
|
4261
4505
|
}
|
|
4262
4506
|
const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
|
|
4263
|
-
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
4507
|
+
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
4508
|
+
metadataPolicy,
|
|
4509
|
+
"type",
|
|
4510
|
+
registryTypeName,
|
|
4511
|
+
namedDecl,
|
|
4264
4512
|
checker,
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4513
|
+
extensionRegistry,
|
|
4514
|
+
{
|
|
4515
|
+
checker,
|
|
4516
|
+
declaration: namedDecl,
|
|
4517
|
+
subjectType: type
|
|
4518
|
+
}
|
|
4519
|
+
) : void 0;
|
|
4268
4520
|
typeRegistry[registryTypeName] = {
|
|
4269
4521
|
name: registryTypeName,
|
|
4270
4522
|
...metadata !== void 0 && { metadata },
|
|
@@ -4360,11 +4612,19 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
4360
4612
|
};
|
|
4361
4613
|
if (registryTypeName !== void 0 && shouldRegisterNamedType) {
|
|
4362
4614
|
const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
|
|
4363
|
-
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
4615
|
+
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
4616
|
+
metadataPolicy,
|
|
4617
|
+
"type",
|
|
4618
|
+
registryTypeName,
|
|
4619
|
+
namedDecl,
|
|
4364
4620
|
checker,
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
|
|
4621
|
+
extensionRegistry,
|
|
4622
|
+
{
|
|
4623
|
+
checker,
|
|
4624
|
+
declaration: namedDecl,
|
|
4625
|
+
subjectType: type
|
|
4626
|
+
}
|
|
4627
|
+
) : void 0;
|
|
4368
4628
|
typeRegistry[registryTypeName] = {
|
|
4369
4629
|
name: registryTypeName,
|
|
4370
4630
|
...metadata !== void 0 && { metadata },
|
|
@@ -4431,9 +4691,10 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
|
|
|
4431
4691
|
);
|
|
4432
4692
|
}
|
|
4433
4693
|
const typeAliasDecl = declarations.find(ts3.isTypeAliasDeclaration);
|
|
4434
|
-
|
|
4694
|
+
const typeAliasMembers = typeAliasDecl === void 0 ? null : getObjectLikeTypeAliasMembers(typeAliasDecl.type);
|
|
4695
|
+
if (typeAliasDecl && typeAliasMembers !== null) {
|
|
4435
4696
|
return buildFieldNodeInfoMap(
|
|
4436
|
-
|
|
4697
|
+
typeAliasMembers,
|
|
4437
4698
|
checker,
|
|
4438
4699
|
file,
|
|
4439
4700
|
typeRegistry,
|
|
@@ -4724,17 +4985,18 @@ function findInterfaceByName(sourceFile, interfaceName) {
|
|
|
4724
4985
|
function findTypeAliasByName(sourceFile, aliasName) {
|
|
4725
4986
|
return findNodeByName(sourceFile, aliasName, ts4.isTypeAliasDeclaration, (n) => n.name.text);
|
|
4726
4987
|
}
|
|
4727
|
-
function analyzeNamedTypeToIR(filePath, typeName, extensionRegistry, metadataPolicy) {
|
|
4988
|
+
function analyzeNamedTypeToIR(filePath, typeName, extensionRegistry, metadataPolicy, discriminatorOptions) {
|
|
4728
4989
|
const ctx = createProgramContext(filePath);
|
|
4729
4990
|
return analyzeNamedTypeToIRFromProgramContext(
|
|
4730
4991
|
ctx,
|
|
4731
4992
|
filePath,
|
|
4732
4993
|
typeName,
|
|
4733
4994
|
extensionRegistry,
|
|
4734
|
-
metadataPolicy
|
|
4995
|
+
metadataPolicy,
|
|
4996
|
+
discriminatorOptions
|
|
4735
4997
|
);
|
|
4736
4998
|
}
|
|
4737
|
-
function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensionRegistry, metadataPolicy) {
|
|
4999
|
+
function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensionRegistry, metadataPolicy, discriminatorOptions) {
|
|
4738
5000
|
const analysisFilePath = path.resolve(filePath);
|
|
4739
5001
|
const classDecl = findClassByName(ctx.sourceFile, typeName);
|
|
4740
5002
|
if (classDecl !== null) {
|
|
@@ -4743,7 +5005,8 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
|
|
|
4743
5005
|
ctx.checker,
|
|
4744
5006
|
analysisFilePath,
|
|
4745
5007
|
extensionRegistry,
|
|
4746
|
-
metadataPolicy
|
|
5008
|
+
metadataPolicy,
|
|
5009
|
+
discriminatorOptions
|
|
4747
5010
|
);
|
|
4748
5011
|
}
|
|
4749
5012
|
const interfaceDecl = findInterfaceByName(ctx.sourceFile, typeName);
|
|
@@ -4753,7 +5016,8 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
|
|
|
4753
5016
|
ctx.checker,
|
|
4754
5017
|
analysisFilePath,
|
|
4755
5018
|
extensionRegistry,
|
|
4756
|
-
metadataPolicy
|
|
5019
|
+
metadataPolicy,
|
|
5020
|
+
discriminatorOptions
|
|
4757
5021
|
);
|
|
4758
5022
|
}
|
|
4759
5023
|
const typeAlias = findTypeAliasByName(ctx.sourceFile, typeName);
|
|
@@ -4763,7 +5027,8 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
|
|
|
4763
5027
|
ctx.checker,
|
|
4764
5028
|
analysisFilePath,
|
|
4765
5029
|
extensionRegistry,
|
|
4766
|
-
metadataPolicy
|
|
5030
|
+
metadataPolicy,
|
|
5031
|
+
discriminatorOptions
|
|
4767
5032
|
);
|
|
4768
5033
|
if (result.ok) {
|
|
4769
5034
|
return result.analysis;
|
|
@@ -4776,9 +5041,9 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
|
|
|
4776
5041
|
}
|
|
4777
5042
|
|
|
4778
5043
|
// src/validate/constraint-validator.ts
|
|
4779
|
-
var
|
|
5044
|
+
var import_internal4 = require("@formspec/analysis/internal");
|
|
4780
5045
|
function validateFieldNode(ctx, field) {
|
|
4781
|
-
const analysis = (0,
|
|
5046
|
+
const analysis = (0, import_internal4.analyzeConstraintTargets)(
|
|
4782
5047
|
field.name,
|
|
4783
5048
|
field.type,
|
|
4784
5049
|
field.constraints,
|
|
@@ -4796,7 +5061,7 @@ function validateFieldNode(ctx, field) {
|
|
|
4796
5061
|
}
|
|
4797
5062
|
function validateObjectProperty(ctx, parentName, property) {
|
|
4798
5063
|
const qualifiedName = `${parentName}.${property.name}`;
|
|
4799
|
-
const analysis = (0,
|
|
5064
|
+
const analysis = (0, import_internal4.analyzeConstraintTargets)(
|
|
4800
5065
|
qualifiedName,
|
|
4801
5066
|
property.type,
|
|
4802
5067
|
property.constraints,
|
|
@@ -4898,7 +5163,8 @@ function generateSchemasFromClass(options) {
|
|
|
4898
5163
|
ctx.checker,
|
|
4899
5164
|
options.filePath,
|
|
4900
5165
|
options.extensionRegistry,
|
|
4901
|
-
options.metadata
|
|
5166
|
+
options.metadata,
|
|
5167
|
+
options.discriminator
|
|
4902
5168
|
);
|
|
4903
5169
|
return generateClassSchemas(
|
|
4904
5170
|
analysis,
|
|
@@ -4924,7 +5190,8 @@ function generateSchemasFromProgram(options) {
|
|
|
4924
5190
|
options.filePath,
|
|
4925
5191
|
options.typeName,
|
|
4926
5192
|
options.extensionRegistry,
|
|
4927
|
-
options.metadata
|
|
5193
|
+
options.metadata,
|
|
5194
|
+
options.discriminator
|
|
4928
5195
|
);
|
|
4929
5196
|
return generateClassSchemas(
|
|
4930
5197
|
analysis,
|
|
@@ -4972,7 +5239,7 @@ function resolveModuleExportDeclaration(context, exportName = "default") {
|
|
|
4972
5239
|
|
|
4973
5240
|
// src/generators/discovered-schema.ts
|
|
4974
5241
|
var ts7 = __toESM(require("typescript"), 1);
|
|
4975
|
-
var
|
|
5242
|
+
var import_internals6 = require("@formspec/core/internals");
|
|
4976
5243
|
function toDiscoveredTypeSchemas(result) {
|
|
4977
5244
|
return result;
|
|
4978
5245
|
}
|
|
@@ -5084,7 +5351,7 @@ function toStandaloneJsonSchema(root, typeRegistry, options) {
|
|
|
5084
5351
|
{
|
|
5085
5352
|
kind: "form-ir",
|
|
5086
5353
|
name: root.name,
|
|
5087
|
-
irVersion:
|
|
5354
|
+
irVersion: import_internals6.IR_VERSION,
|
|
5088
5355
|
elements: [syntheticField],
|
|
5089
5356
|
...root.metadata !== void 0 && { metadata: root.metadata },
|
|
5090
5357
|
...root.annotations !== void 0 && root.annotations.length > 0 && { rootAnnotations: root.annotations },
|
|
@@ -5143,7 +5410,7 @@ function generateSchemasFromResolvedType(options, skipNamedDeclaration = false,
|
|
|
5143
5410
|
typeRegistry,
|
|
5144
5411
|
/* @__PURE__ */ new Set(),
|
|
5145
5412
|
options.sourceNode,
|
|
5146
|
-
|
|
5413
|
+
createAnalyzerMetadataPolicy(options.metadata, options.discriminator),
|
|
5147
5414
|
options.extensionRegistry,
|
|
5148
5415
|
diagnostics
|
|
5149
5416
|
);
|
|
@@ -5192,7 +5459,8 @@ function generateSchemasFromDeclaration(options) {
|
|
|
5192
5459
|
options.context.checker,
|
|
5193
5460
|
filePath,
|
|
5194
5461
|
options.extensionRegistry,
|
|
5195
|
-
options.metadata
|
|
5462
|
+
options.metadata,
|
|
5463
|
+
options.discriminator
|
|
5196
5464
|
),
|
|
5197
5465
|
filePath,
|
|
5198
5466
|
options
|
|
@@ -5205,7 +5473,8 @@ function generateSchemasFromDeclaration(options) {
|
|
|
5205
5473
|
options.context.checker,
|
|
5206
5474
|
filePath,
|
|
5207
5475
|
options.extensionRegistry,
|
|
5208
|
-
options.metadata
|
|
5476
|
+
options.metadata,
|
|
5477
|
+
options.discriminator
|
|
5209
5478
|
),
|
|
5210
5479
|
filePath,
|
|
5211
5480
|
options
|
|
@@ -5217,7 +5486,8 @@ function generateSchemasFromDeclaration(options) {
|
|
|
5217
5486
|
options.context.checker,
|
|
5218
5487
|
filePath,
|
|
5219
5488
|
options.extensionRegistry,
|
|
5220
|
-
options.metadata
|
|
5489
|
+
options.metadata,
|
|
5490
|
+
options.discriminator
|
|
5221
5491
|
);
|
|
5222
5492
|
if (analyzedAlias.ok) {
|
|
5223
5493
|
return generateSchemasFromAnalysis(analyzedAlias.analysis, filePath, options);
|
|
@@ -5283,7 +5553,8 @@ function buildMixedAuthoringSchemas(options) {
|
|
|
5283
5553
|
filePath,
|
|
5284
5554
|
typeName,
|
|
5285
5555
|
schemaOptions.extensionRegistry,
|
|
5286
|
-
schemaOptions.metadata
|
|
5556
|
+
schemaOptions.metadata,
|
|
5557
|
+
schemaOptions.discriminator
|
|
5287
5558
|
);
|
|
5288
5559
|
const composedAnalysis = composeAnalysisWithOverlays(analysis, overlays, schemaOptions.metadata);
|
|
5289
5560
|
const ir = canonicalizeTSDoc(
|