@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/cli.cjs
CHANGED
|
@@ -1877,13 +1877,26 @@ var init_generator2 = __esm({
|
|
|
1877
1877
|
});
|
|
1878
1878
|
|
|
1879
1879
|
// src/extensions/registry.ts
|
|
1880
|
+
function buildConstraintTagSources(extensions) {
|
|
1881
|
+
return extensions.map((extension) => ({
|
|
1882
|
+
extensionId: extension.extensionId,
|
|
1883
|
+
...extension.constraintTags !== void 0 ? {
|
|
1884
|
+
constraintTags: extension.constraintTags.map((tag) => ({
|
|
1885
|
+
tagName: (0, import_internal.normalizeFormSpecTagName)(tag.tagName)
|
|
1886
|
+
}))
|
|
1887
|
+
} : {}
|
|
1888
|
+
}));
|
|
1889
|
+
}
|
|
1880
1890
|
function createExtensionRegistry(extensions) {
|
|
1891
|
+
const reservedTagSources = buildConstraintTagSources(extensions);
|
|
1881
1892
|
const typeMap = /* @__PURE__ */ new Map();
|
|
1882
1893
|
const typeNameMap = /* @__PURE__ */ new Map();
|
|
1883
1894
|
const constraintMap = /* @__PURE__ */ new Map();
|
|
1884
1895
|
const constraintTagMap = /* @__PURE__ */ new Map();
|
|
1885
1896
|
const builtinBroadeningMap = /* @__PURE__ */ new Map();
|
|
1886
1897
|
const annotationMap = /* @__PURE__ */ new Map();
|
|
1898
|
+
const metadataSlotMap = /* @__PURE__ */ new Map();
|
|
1899
|
+
const metadataTagMap = /* @__PURE__ */ new Map();
|
|
1887
1900
|
for (const ext of extensions) {
|
|
1888
1901
|
if (ext.types !== void 0) {
|
|
1889
1902
|
for (const type of ext.types) {
|
|
@@ -1926,10 +1939,11 @@ function createExtensionRegistry(extensions) {
|
|
|
1926
1939
|
}
|
|
1927
1940
|
if (ext.constraintTags !== void 0) {
|
|
1928
1941
|
for (const tag of ext.constraintTags) {
|
|
1929
|
-
|
|
1930
|
-
|
|
1942
|
+
const canonicalTagName = (0, import_internal.normalizeFormSpecTagName)(tag.tagName);
|
|
1943
|
+
if (constraintTagMap.has(canonicalTagName)) {
|
|
1944
|
+
throw new Error(`Duplicate custom constraint tag: "@${canonicalTagName}"`);
|
|
1931
1945
|
}
|
|
1932
|
-
constraintTagMap.set(
|
|
1946
|
+
constraintTagMap.set(canonicalTagName, {
|
|
1933
1947
|
extensionId: ext.extensionId,
|
|
1934
1948
|
registration: tag
|
|
1935
1949
|
});
|
|
@@ -1944,20 +1958,65 @@ function createExtensionRegistry(extensions) {
|
|
|
1944
1958
|
annotationMap.set(qualifiedId, annotation);
|
|
1945
1959
|
}
|
|
1946
1960
|
}
|
|
1961
|
+
if (ext.metadataSlots !== void 0) {
|
|
1962
|
+
for (const slot of ext.metadataSlots) {
|
|
1963
|
+
if (metadataSlotMap.has(slot.slotId)) {
|
|
1964
|
+
throw new Error(`Duplicate metadata slot ID: "${slot.slotId}"`);
|
|
1965
|
+
}
|
|
1966
|
+
metadataSlotMap.set(slot.slotId, true);
|
|
1967
|
+
const canonicalTagName = (0, import_internal.normalizeFormSpecTagName)(slot.tagName);
|
|
1968
|
+
if (slot.allowBare === false && (slot.qualifiers?.length ?? 0) === 0) {
|
|
1969
|
+
throw new Error(
|
|
1970
|
+
`Metadata tag "@${canonicalTagName}" must allow bare usage or declare at least one qualifier.`
|
|
1971
|
+
);
|
|
1972
|
+
}
|
|
1973
|
+
if (metadataTagMap.has(canonicalTagName)) {
|
|
1974
|
+
throw new Error(`Duplicate metadata tag: "@${canonicalTagName}"`);
|
|
1975
|
+
}
|
|
1976
|
+
if (BUILTIN_METADATA_TAGS.has(canonicalTagName)) {
|
|
1977
|
+
throw new Error(
|
|
1978
|
+
`Metadata tag "@${canonicalTagName}" conflicts with built-in metadata tags.`
|
|
1979
|
+
);
|
|
1980
|
+
}
|
|
1981
|
+
if (constraintTagMap.has(canonicalTagName)) {
|
|
1982
|
+
throw new Error(
|
|
1983
|
+
`Metadata tag "@${canonicalTagName}" conflicts with existing FormSpec tag "@${canonicalTagName}".`
|
|
1984
|
+
);
|
|
1985
|
+
}
|
|
1986
|
+
if (Object.hasOwn(import_internals3.BUILTIN_CONSTRAINT_DEFINITIONS, (0, import_internals3.normalizeConstraintTagName)(canonicalTagName))) {
|
|
1987
|
+
throw new Error(
|
|
1988
|
+
`Metadata tag "@${canonicalTagName}" conflicts with existing FormSpec tag "@${(0, import_internals3.normalizeConstraintTagName)(canonicalTagName)}".`
|
|
1989
|
+
);
|
|
1990
|
+
}
|
|
1991
|
+
const existingTag = (0, import_internal.getTagDefinition)(canonicalTagName, reservedTagSources);
|
|
1992
|
+
if (existingTag !== null) {
|
|
1993
|
+
throw BUILTIN_METADATA_TAGS.has(existingTag.canonicalName) ? new Error(
|
|
1994
|
+
`Metadata tag "@${canonicalTagName}" conflicts with built-in metadata tags.`
|
|
1995
|
+
) : new Error(
|
|
1996
|
+
`Metadata tag "@${canonicalTagName}" conflicts with existing FormSpec tag "@${existingTag.canonicalName}".`
|
|
1997
|
+
);
|
|
1998
|
+
}
|
|
1999
|
+
metadataTagMap.set(canonicalTagName, true);
|
|
2000
|
+
}
|
|
2001
|
+
}
|
|
1947
2002
|
}
|
|
1948
2003
|
return {
|
|
1949
2004
|
extensions,
|
|
1950
2005
|
findType: (typeId) => typeMap.get(typeId),
|
|
1951
2006
|
findTypeByName: (typeName) => typeNameMap.get(typeName),
|
|
1952
2007
|
findConstraint: (constraintId) => constraintMap.get(constraintId),
|
|
1953
|
-
findConstraintTag: (tagName) => constraintTagMap.get(tagName),
|
|
2008
|
+
findConstraintTag: (tagName) => constraintTagMap.get((0, import_internal.normalizeFormSpecTagName)(tagName)),
|
|
1954
2009
|
findBuiltinConstraintBroadening: (typeId, tagName) => builtinBroadeningMap.get(`${typeId}:${tagName}`),
|
|
1955
2010
|
findAnnotation: (annotationId) => annotationMap.get(annotationId)
|
|
1956
2011
|
};
|
|
1957
2012
|
}
|
|
2013
|
+
var import_internals3, import_internal, BUILTIN_METADATA_TAGS;
|
|
1958
2014
|
var init_registry = __esm({
|
|
1959
2015
|
"src/extensions/registry.ts"() {
|
|
1960
2016
|
"use strict";
|
|
2017
|
+
import_internals3 = require("@formspec/core/internals");
|
|
2018
|
+
import_internal = require("@formspec/analysis/internal");
|
|
2019
|
+
BUILTIN_METADATA_TAGS = /* @__PURE__ */ new Set(["apiName", "displayName"]);
|
|
1961
2020
|
}
|
|
1962
2021
|
});
|
|
1963
2022
|
|
|
@@ -2040,7 +2099,7 @@ var init_schema2 = __esm({
|
|
|
2040
2099
|
// src/analyzer/tsdoc-parser.ts
|
|
2041
2100
|
function createFormSpecTSDocConfig(extensionTagNames = []) {
|
|
2042
2101
|
const config = new import_tsdoc.TSDocConfiguration();
|
|
2043
|
-
for (const tagName of Object.keys(
|
|
2102
|
+
for (const tagName of Object.keys(import_internals4.BUILTIN_CONSTRAINT_DEFINITIONS)) {
|
|
2044
2103
|
config.addTagDefinition(
|
|
2045
2104
|
new import_tsdoc.TSDocTagDefinition({
|
|
2046
2105
|
tagName: "@" + tagName,
|
|
@@ -2049,7 +2108,7 @@ function createFormSpecTSDocConfig(extensionTagNames = []) {
|
|
|
2049
2108
|
})
|
|
2050
2109
|
);
|
|
2051
2110
|
}
|
|
2052
|
-
for (const tagName of ["displayName", "format", "placeholder"]) {
|
|
2111
|
+
for (const tagName of ["apiName", "displayName", "format", "placeholder"]) {
|
|
2053
2112
|
config.addTagDefinition(
|
|
2054
2113
|
new import_tsdoc.TSDocTagDefinition({
|
|
2055
2114
|
tagName: "@" + tagName,
|
|
@@ -2082,6 +2141,16 @@ function sharedTagValueOptions(options) {
|
|
|
2082
2141
|
...options?.fieldType !== void 0 ? { fieldType: options.fieldType } : {}
|
|
2083
2142
|
};
|
|
2084
2143
|
}
|
|
2144
|
+
function getExtensionTypeNames(registry) {
|
|
2145
|
+
if (registry === void 0) {
|
|
2146
|
+
return /* @__PURE__ */ new Set();
|
|
2147
|
+
}
|
|
2148
|
+
return new Set(
|
|
2149
|
+
registry.extensions.flatMap(
|
|
2150
|
+
(ext) => (ext.types ?? []).flatMap((t) => t.tsTypeNames ?? [t.typeName])
|
|
2151
|
+
)
|
|
2152
|
+
);
|
|
2153
|
+
}
|
|
2085
2154
|
function collectImportedNames(sourceFile) {
|
|
2086
2155
|
const importedNames = /* @__PURE__ */ new Set();
|
|
2087
2156
|
for (const statement of sourceFile.statements) {
|
|
@@ -2121,6 +2190,9 @@ function isNonReferenceIdentifier(node) {
|
|
|
2121
2190
|
return false;
|
|
2122
2191
|
}
|
|
2123
2192
|
function statementReferencesImportedName(statement, importedNames) {
|
|
2193
|
+
if (importedNames.size === 0) {
|
|
2194
|
+
return false;
|
|
2195
|
+
}
|
|
2124
2196
|
let referencesImportedName = false;
|
|
2125
2197
|
const visit = (node) => {
|
|
2126
2198
|
if (referencesImportedName) {
|
|
@@ -2135,14 +2207,17 @@ function statementReferencesImportedName(statement, importedNames) {
|
|
|
2135
2207
|
visit(statement);
|
|
2136
2208
|
return referencesImportedName;
|
|
2137
2209
|
}
|
|
2138
|
-
function buildSupportingDeclarations(sourceFile) {
|
|
2210
|
+
function buildSupportingDeclarations(sourceFile, extensionTypeNames) {
|
|
2139
2211
|
const importedNames = collectImportedNames(sourceFile);
|
|
2212
|
+
const importedNamesToSkip = new Set(
|
|
2213
|
+
[...importedNames].filter((name) => !extensionTypeNames.has(name))
|
|
2214
|
+
);
|
|
2140
2215
|
return sourceFile.statements.filter((statement) => {
|
|
2141
2216
|
if (ts.isImportDeclaration(statement)) return false;
|
|
2142
2217
|
if (ts.isImportEqualsDeclaration(statement)) return false;
|
|
2143
2218
|
if (ts.isExportDeclaration(statement) && statement.moduleSpecifier !== void 0)
|
|
2144
2219
|
return false;
|
|
2145
|
-
if (
|
|
2220
|
+
if (statementReferencesImportedName(statement, importedNamesToSkip)) {
|
|
2146
2221
|
return false;
|
|
2147
2222
|
}
|
|
2148
2223
|
return true;
|
|
@@ -2188,12 +2263,12 @@ function supportsConstraintCapability(type, checker, capability) {
|
|
|
2188
2263
|
if (capability === void 0) {
|
|
2189
2264
|
return true;
|
|
2190
2265
|
}
|
|
2191
|
-
if ((0,
|
|
2266
|
+
if ((0, import_internal2.hasTypeSemanticCapability)(type, checker, capability)) {
|
|
2192
2267
|
return true;
|
|
2193
2268
|
}
|
|
2194
2269
|
if (capability === "string-like") {
|
|
2195
2270
|
const itemType = getArrayElementType(type, checker);
|
|
2196
|
-
return itemType !== null && (0,
|
|
2271
|
+
return itemType !== null && (0, import_internal2.hasTypeSemanticCapability)(itemType, checker, capability);
|
|
2197
2272
|
}
|
|
2198
2273
|
return false;
|
|
2199
2274
|
}
|
|
@@ -2283,7 +2358,7 @@ function hasBuiltinConstraintBroadening(tagName, options) {
|
|
|
2283
2358
|
return broadenedTypeId !== void 0 && options?.extensionRegistry?.findBuiltinConstraintBroadening(broadenedTypeId, tagName) !== void 0;
|
|
2284
2359
|
}
|
|
2285
2360
|
function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, parsedTag, provenance, supportingDeclarations, options) {
|
|
2286
|
-
if (!(0,
|
|
2361
|
+
if (!(0, import_internals4.isBuiltinConstraintName)(tagName)) {
|
|
2287
2362
|
return [];
|
|
2288
2363
|
}
|
|
2289
2364
|
const checker = options?.checker;
|
|
@@ -2291,11 +2366,11 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2291
2366
|
if (checker === void 0 || subjectType === void 0) {
|
|
2292
2367
|
return [];
|
|
2293
2368
|
}
|
|
2294
|
-
const placement = (0,
|
|
2369
|
+
const placement = (0, import_internal2.resolveDeclarationPlacement)(node);
|
|
2295
2370
|
if (placement === null) {
|
|
2296
2371
|
return [];
|
|
2297
2372
|
}
|
|
2298
|
-
const definition = (0,
|
|
2373
|
+
const definition = (0, import_internal2.getTagDefinition)(tagName, options?.extensionRegistry?.extensions);
|
|
2299
2374
|
if (definition === null) {
|
|
2300
2375
|
return [];
|
|
2301
2376
|
}
|
|
@@ -2329,7 +2404,7 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2329
2404
|
)
|
|
2330
2405
|
];
|
|
2331
2406
|
}
|
|
2332
|
-
const resolution = (0,
|
|
2407
|
+
const resolution = (0, import_internal2.resolvePathTargetType)(subjectType, checker, target.path.segments);
|
|
2333
2408
|
if (resolution.kind === "missing-property") {
|
|
2334
2409
|
return [
|
|
2335
2410
|
makeDiagnostic(
|
|
@@ -2386,7 +2461,7 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2386
2461
|
const subjectTypeText = checker.typeToString(subjectType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
|
|
2387
2462
|
const hostType = options?.hostType ?? subjectType;
|
|
2388
2463
|
const hostTypeText = checker.typeToString(hostType, node, SYNTHETIC_TYPE_FORMAT_FLAGS);
|
|
2389
|
-
const result = (0,
|
|
2464
|
+
const result = (0, import_internal2.checkSyntheticTagApplication)({
|
|
2390
2465
|
tagName,
|
|
2391
2466
|
placement,
|
|
2392
2467
|
hostType: hostTypeText,
|
|
@@ -2399,6 +2474,14 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2399
2474
|
extensionId: extension.extensionId,
|
|
2400
2475
|
...extension.constraintTags !== void 0 ? {
|
|
2401
2476
|
constraintTags: extension.constraintTags.map((tag) => ({ tagName: tag.tagName }))
|
|
2477
|
+
} : {},
|
|
2478
|
+
...extension.metadataSlots !== void 0 ? {
|
|
2479
|
+
metadataSlots: extension.metadataSlots
|
|
2480
|
+
} : {},
|
|
2481
|
+
...extension.types !== void 0 ? {
|
|
2482
|
+
customTypes: extension.types.map((t) => ({
|
|
2483
|
+
tsTypeNames: t.tsTypeNames ?? [t.typeName]
|
|
2484
|
+
}))
|
|
2402
2485
|
} : {}
|
|
2403
2486
|
}))
|
|
2404
2487
|
} : {}
|
|
@@ -2418,7 +2501,10 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
2418
2501
|
function getParser(options) {
|
|
2419
2502
|
const extensionTagNames = [
|
|
2420
2503
|
...options?.extensionRegistry?.extensions.flatMap(
|
|
2421
|
-
(extension) => (extension.constraintTags ?? []).map((tag) => tag.tagName)
|
|
2504
|
+
(extension) => (extension.constraintTags ?? []).map((tag) => (0, import_internal2.normalizeFormSpecTagName)(tag.tagName))
|
|
2505
|
+
) ?? [],
|
|
2506
|
+
...options?.extensionRegistry?.extensions.flatMap(
|
|
2507
|
+
(extension) => (extension.metadataSlots ?? []).map((slot) => (0, import_internal2.normalizeFormSpecTagName)(slot.tagName))
|
|
2422
2508
|
) ?? []
|
|
2423
2509
|
].sort();
|
|
2424
2510
|
const cacheKey = extensionTagNames.join("|");
|
|
@@ -2438,7 +2524,16 @@ function getExtensionRegistryCacheKey(registry) {
|
|
|
2438
2524
|
(extension) => JSON.stringify({
|
|
2439
2525
|
extensionId: extension.extensionId,
|
|
2440
2526
|
typeNames: extension.types?.map((type) => type.typeName) ?? [],
|
|
2441
|
-
constraintTags: extension.constraintTags?.map((tag) => tag.tagName) ?? []
|
|
2527
|
+
constraintTags: extension.constraintTags?.map((tag) => (0, import_internal2.normalizeFormSpecTagName)(tag.tagName)) ?? [],
|
|
2528
|
+
metadataSlots: extension.metadataSlots?.map((slot) => ({
|
|
2529
|
+
tagName: (0, import_internal2.normalizeFormSpecTagName)(slot.tagName),
|
|
2530
|
+
declarationKinds: [...slot.declarationKinds].sort(),
|
|
2531
|
+
allowBare: slot.allowBare !== false,
|
|
2532
|
+
qualifiers: (slot.qualifiers ?? []).map((qualifier) => ({
|
|
2533
|
+
qualifier: qualifier.qualifier,
|
|
2534
|
+
...qualifier.sourceQualifier !== void 0 ? { sourceQualifier: qualifier.sourceQualifier } : {}
|
|
2535
|
+
})).sort((left, right) => left.qualifier.localeCompare(right.qualifier))
|
|
2536
|
+
})) ?? []
|
|
2442
2537
|
})
|
|
2443
2538
|
).join("|");
|
|
2444
2539
|
}
|
|
@@ -2473,7 +2568,8 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
2473
2568
|
const rawTextTags = [];
|
|
2474
2569
|
const sourceFile = node.getSourceFile();
|
|
2475
2570
|
const sourceText = sourceFile.getFullText();
|
|
2476
|
-
const
|
|
2571
|
+
const extensionTypeNames = getExtensionTypeNames(options?.extensionRegistry);
|
|
2572
|
+
const supportingDeclarations = buildSupportingDeclarations(sourceFile, extensionTypeNames);
|
|
2477
2573
|
const commentRanges = ts.getLeadingCommentRanges(sourceText, node.getFullStart());
|
|
2478
2574
|
const rawTextFallbacks = collectRawTextFallbacks(node, file);
|
|
2479
2575
|
if (commentRanges) {
|
|
@@ -2490,7 +2586,7 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
2490
2586
|
import_tsdoc.TextRange.fromStringRange(sourceText, range.pos, range.end)
|
|
2491
2587
|
);
|
|
2492
2588
|
const docComment = parserContext.docComment;
|
|
2493
|
-
const parsedComment = (0,
|
|
2589
|
+
const parsedComment = (0, import_internal2.parseCommentBlock)(
|
|
2494
2590
|
commentText,
|
|
2495
2591
|
sharedCommentSyntaxOptions(options, range.pos)
|
|
2496
2592
|
);
|
|
@@ -2511,7 +2607,7 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
2511
2607
|
}
|
|
2512
2608
|
}
|
|
2513
2609
|
for (const block of docComment.customBlocks) {
|
|
2514
|
-
const tagName = (0,
|
|
2610
|
+
const tagName = (0, import_internals4.normalizeConstraintTagName)(block.blockTag.tagName.substring(1));
|
|
2515
2611
|
const parsedTag = nextParsedTag(tagName);
|
|
2516
2612
|
if (tagName === "displayName" || tagName === "format" || tagName === "placeholder") {
|
|
2517
2613
|
const text2 = getBestBlockPayloadText(parsedTag, commentText, range.pos, block);
|
|
@@ -2543,7 +2639,7 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
2543
2639
|
}
|
|
2544
2640
|
if (TAGS_REQUIRING_RAW_TEXT.has(tagName)) continue;
|
|
2545
2641
|
const text = getBestBlockPayloadText(parsedTag, commentText, range.pos, block);
|
|
2546
|
-
const expectedType = (0,
|
|
2642
|
+
const expectedType = (0, import_internals4.isBuiltinConstraintName)(tagName) ? import_internals4.BUILTIN_CONSTRAINT_DEFINITIONS[tagName] : void 0;
|
|
2547
2643
|
if (text === "" && expectedType !== "boolean") continue;
|
|
2548
2644
|
const provenance = parsedTag !== null ? provenanceForParsedTag(parsedTag, sourceFile, file) : provenanceForComment(range, sourceFile, file, tagName);
|
|
2549
2645
|
const compilerDiagnostics = buildCompilerBackedConstraintDiagnostics(
|
|
@@ -2559,7 +2655,7 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
2559
2655
|
diagnostics.push(...compilerDiagnostics);
|
|
2560
2656
|
continue;
|
|
2561
2657
|
}
|
|
2562
|
-
const constraintNode = (0,
|
|
2658
|
+
const constraintNode = (0, import_internal2.parseConstraintTagValue)(
|
|
2563
2659
|
tagName,
|
|
2564
2660
|
text,
|
|
2565
2661
|
provenance,
|
|
@@ -2629,7 +2725,7 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
2629
2725
|
if (text === "") continue;
|
|
2630
2726
|
const provenance = provenanceForParsedTag(rawTextTag.tag, sourceFile, file);
|
|
2631
2727
|
if (rawTextTag.tag.normalizedTagName === "defaultValue") {
|
|
2632
|
-
const defaultValueNode = (0,
|
|
2728
|
+
const defaultValueNode = (0, import_internal2.parseDefaultValueTagValue)(text, provenance);
|
|
2633
2729
|
annotations.push(defaultValueNode);
|
|
2634
2730
|
continue;
|
|
2635
2731
|
}
|
|
@@ -2646,7 +2742,7 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
2646
2742
|
diagnostics.push(...compilerDiagnostics);
|
|
2647
2743
|
continue;
|
|
2648
2744
|
}
|
|
2649
|
-
const constraintNode = (0,
|
|
2745
|
+
const constraintNode = (0, import_internal2.parseConstraintTagValue)(
|
|
2650
2746
|
rawTextTag.tag.normalizedTagName,
|
|
2651
2747
|
text,
|
|
2652
2748
|
provenance,
|
|
@@ -2663,7 +2759,7 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
2663
2759
|
if (text === "") continue;
|
|
2664
2760
|
const provenance = fallback.provenance;
|
|
2665
2761
|
if (tagName === "defaultValue") {
|
|
2666
|
-
const defaultValueNode = (0,
|
|
2762
|
+
const defaultValueNode = (0, import_internal2.parseDefaultValueTagValue)(text, provenance);
|
|
2667
2763
|
annotations.push(defaultValueNode);
|
|
2668
2764
|
continue;
|
|
2669
2765
|
}
|
|
@@ -2680,7 +2776,7 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
2680
2776
|
diagnostics.push(...compilerDiagnostics);
|
|
2681
2777
|
continue;
|
|
2682
2778
|
}
|
|
2683
|
-
const constraintNode = (0,
|
|
2779
|
+
const constraintNode = (0, import_internal2.parseConstraintTagValue)(
|
|
2684
2780
|
tagName,
|
|
2685
2781
|
text,
|
|
2686
2782
|
provenance,
|
|
@@ -2706,7 +2802,7 @@ function extractDisplayNameMetadata(node) {
|
|
|
2706
2802
|
if (range.kind !== ts.SyntaxKind.MultiLineCommentTrivia) continue;
|
|
2707
2803
|
const commentText = sourceText.substring(range.pos, range.end);
|
|
2708
2804
|
if (!commentText.startsWith("/**")) continue;
|
|
2709
|
-
const parsed = (0,
|
|
2805
|
+
const parsed = (0, import_internal2.parseCommentBlock)(commentText);
|
|
2710
2806
|
for (const tag of parsed.tags) {
|
|
2711
2807
|
if (tag.normalizedTagName !== "displayName") {
|
|
2712
2808
|
continue;
|
|
@@ -2762,7 +2858,7 @@ function getSharedPayloadText(tag, commentText, commentOffset) {
|
|
|
2762
2858
|
if (tag.payloadSpan === null) {
|
|
2763
2859
|
return "";
|
|
2764
2860
|
}
|
|
2765
|
-
return (0,
|
|
2861
|
+
return (0, import_internal2.sliceCommentSpan)(commentText, tag.payloadSpan, {
|
|
2766
2862
|
offset: commentOffset
|
|
2767
2863
|
}).trim();
|
|
2768
2864
|
}
|
|
@@ -2774,7 +2870,7 @@ function getBestBlockPayloadText(tag, commentText, commentOffset, block) {
|
|
|
2774
2870
|
function collectRawTextFallbacks(node, file) {
|
|
2775
2871
|
const fallbacks = /* @__PURE__ */ new Map();
|
|
2776
2872
|
for (const tag of ts.getJSDocTags(node)) {
|
|
2777
|
-
const tagName = (0,
|
|
2873
|
+
const tagName = (0, import_internals4.normalizeConstraintTagName)(tag.tagName.text);
|
|
2778
2874
|
if (!TAGS_REQUIRING_RAW_TEXT.has(tagName)) continue;
|
|
2779
2875
|
const commentText = getTagCommentText(tag)?.trim() ?? "";
|
|
2780
2876
|
if (commentText === "") continue;
|
|
@@ -2788,7 +2884,7 @@ function collectRawTextFallbacks(node, file) {
|
|
|
2788
2884
|
return fallbacks;
|
|
2789
2885
|
}
|
|
2790
2886
|
function isMemberTargetDisplayName(text) {
|
|
2791
|
-
return (0,
|
|
2887
|
+
return (0, import_internal2.parseTagSyntax)("displayName", text).target !== null;
|
|
2792
2888
|
}
|
|
2793
2889
|
function provenanceForComment(range, sourceFile, file, tagName) {
|
|
2794
2890
|
const { line, character } = sourceFile.getLineAndCharacterOfPosition(range.pos);
|
|
@@ -2830,15 +2926,15 @@ function getTagCommentText(tag) {
|
|
|
2830
2926
|
}
|
|
2831
2927
|
return ts.getTextOfJSDocComment(tag.comment);
|
|
2832
2928
|
}
|
|
2833
|
-
var ts,
|
|
2929
|
+
var ts, import_internal2, import_tsdoc, import_internals4, import_internals5, TAGS_REQUIRING_RAW_TEXT, SYNTHETIC_TYPE_FORMAT_FLAGS, parserCache, parseResultCache;
|
|
2834
2930
|
var init_tsdoc_parser = __esm({
|
|
2835
2931
|
"src/analyzer/tsdoc-parser.ts"() {
|
|
2836
2932
|
"use strict";
|
|
2837
2933
|
ts = __toESM(require("typescript"), 1);
|
|
2838
|
-
|
|
2934
|
+
import_internal2 = require("@formspec/analysis/internal");
|
|
2839
2935
|
import_tsdoc = require("@microsoft/tsdoc");
|
|
2840
|
-
import_internals3 = require("@formspec/core/internals");
|
|
2841
2936
|
import_internals4 = require("@formspec/core/internals");
|
|
2937
|
+
import_internals5 = require("@formspec/core/internals");
|
|
2842
2938
|
TAGS_REQUIRING_RAW_TEXT = /* @__PURE__ */ new Set(["pattern", "enumOptions", "defaultValue"]);
|
|
2843
2939
|
SYNTHETIC_TYPE_FORMAT_FLAGS = ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
|
|
2844
2940
|
parserCache = /* @__PURE__ */ new Map();
|
|
@@ -2904,6 +3000,9 @@ var init_jsdoc_constraints = __esm({
|
|
|
2904
3000
|
function isObjectType(type) {
|
|
2905
3001
|
return !!(type.flags & ts3.TypeFlags.Object);
|
|
2906
3002
|
}
|
|
3003
|
+
function isIntersectionType(type) {
|
|
3004
|
+
return !!(type.flags & ts3.TypeFlags.Intersection);
|
|
3005
|
+
}
|
|
2907
3006
|
function isTypeReference(type) {
|
|
2908
3007
|
return !!(type.flags & ts3.TypeFlags.Object) && !!(type.objectFlags & ts3.ObjectFlags.Reference);
|
|
2909
3008
|
}
|
|
@@ -2919,76 +3018,51 @@ function makeParseOptions(extensionRegistry, fieldType, checker, subjectType, ho
|
|
|
2919
3018
|
...hostType !== void 0 && { hostType }
|
|
2920
3019
|
};
|
|
2921
3020
|
}
|
|
2922
|
-
function
|
|
2923
|
-
return
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
let displayName;
|
|
2928
|
-
let apiNamePlural;
|
|
2929
|
-
let displayNamePlural;
|
|
2930
|
-
for (const tag of getLeadingParsedTags(node)) {
|
|
2931
|
-
const value = tag.argumentText.trim();
|
|
2932
|
-
if (value === "") {
|
|
2933
|
-
continue;
|
|
2934
|
-
}
|
|
2935
|
-
if (tag.normalizedTagName === "apiName") {
|
|
2936
|
-
if (tag.target === null) {
|
|
2937
|
-
apiName ??= value;
|
|
2938
|
-
} else if (tag.target.kind === "variant") {
|
|
2939
|
-
if (tag.target.rawText === "singular") {
|
|
2940
|
-
apiName ??= value;
|
|
2941
|
-
} else if (tag.target.rawText === "plural") {
|
|
2942
|
-
apiNamePlural ??= value;
|
|
2943
|
-
}
|
|
2944
|
-
}
|
|
2945
|
-
continue;
|
|
2946
|
-
}
|
|
2947
|
-
if (tag.normalizedTagName === "displayName") {
|
|
2948
|
-
if (tag.target === null) {
|
|
2949
|
-
displayName ??= value;
|
|
2950
|
-
} else if (tag.target.kind === "variant") {
|
|
2951
|
-
if (tag.target.rawText === "singular") {
|
|
2952
|
-
displayName ??= value;
|
|
2953
|
-
} else if (tag.target.rawText === "plural") {
|
|
2954
|
-
displayNamePlural ??= value;
|
|
2955
|
-
}
|
|
2956
|
-
}
|
|
2957
|
-
}
|
|
2958
|
-
}
|
|
2959
|
-
const resolvedApiName = makeExplicitScalarMetadata(apiName);
|
|
2960
|
-
const resolvedDisplayName = makeExplicitScalarMetadata(displayName);
|
|
2961
|
-
const resolvedApiNamePlural = makeExplicitScalarMetadata(apiNamePlural);
|
|
2962
|
-
const resolvedDisplayNamePlural = makeExplicitScalarMetadata(displayNamePlural);
|
|
2963
|
-
const metadata = {
|
|
2964
|
-
...resolvedApiName !== void 0 && { apiName: resolvedApiName },
|
|
2965
|
-
...resolvedDisplayName !== void 0 && { displayName: resolvedDisplayName },
|
|
2966
|
-
...resolvedApiNamePlural !== void 0 && { apiNamePlural: resolvedApiNamePlural },
|
|
2967
|
-
...resolvedDisplayNamePlural !== void 0 && {
|
|
2968
|
-
displayNamePlural: resolvedDisplayNamePlural
|
|
2969
|
-
}
|
|
3021
|
+
function createAnalyzerMetadataPolicy(input, discriminator) {
|
|
3022
|
+
return {
|
|
3023
|
+
raw: input,
|
|
3024
|
+
normalized: normalizeMetadataPolicy(input),
|
|
3025
|
+
discriminator
|
|
2970
3026
|
};
|
|
2971
|
-
return Object.keys(metadata).length === 0 ? void 0 : metadata;
|
|
2972
3027
|
}
|
|
2973
|
-
function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, buildContext) {
|
|
2974
|
-
const
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
getDeclarationMetadataPolicy(metadataPolicy, declarationKind),
|
|
2987
|
-
makeMetadataContext("tsdoc", declarationKind, logicalName, buildContext)
|
|
3028
|
+
function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, checker, extensionRegistry, buildContext) {
|
|
3029
|
+
const analysis = (0, import_internal3.analyzeMetadataForNodeWithChecker)({
|
|
3030
|
+
checker,
|
|
3031
|
+
node,
|
|
3032
|
+
logicalName,
|
|
3033
|
+
metadata: metadataPolicy.raw,
|
|
3034
|
+
extensions: extensionRegistry?.extensions,
|
|
3035
|
+
...buildContext !== void 0 && { buildContext }
|
|
3036
|
+
});
|
|
3037
|
+
const resolvedMetadata = analysis?.resolvedMetadata;
|
|
3038
|
+
const declarationPolicy = getDeclarationMetadataPolicy(
|
|
3039
|
+
metadataPolicy.normalized,
|
|
3040
|
+
declarationKind
|
|
2988
3041
|
);
|
|
3042
|
+
if (resolvedMetadata?.apiName === void 0 && declarationPolicy.apiName.mode === "require-explicit") {
|
|
3043
|
+
throw new Error(
|
|
3044
|
+
`Metadata policy requires explicit apiName for ${declarationKind} "${logicalName}" on the tsdoc surface.`
|
|
3045
|
+
);
|
|
3046
|
+
}
|
|
3047
|
+
if (resolvedMetadata?.displayName === void 0 && declarationPolicy.displayName.mode === "require-explicit") {
|
|
3048
|
+
throw new Error(
|
|
3049
|
+
`Metadata policy requires explicit displayName for ${declarationKind} "${logicalName}" on the tsdoc surface.`
|
|
3050
|
+
);
|
|
3051
|
+
}
|
|
3052
|
+
if (resolvedMetadata?.apiNamePlural === void 0 && declarationPolicy.apiName.pluralization.mode === "require-explicit") {
|
|
3053
|
+
throw new Error(
|
|
3054
|
+
`Metadata policy requires explicit apiNamePlural for ${declarationKind} "${logicalName}" on the tsdoc surface.`
|
|
3055
|
+
);
|
|
3056
|
+
}
|
|
3057
|
+
if (resolvedMetadata?.displayNamePlural === void 0 && declarationPolicy.displayName.pluralization.mode === "require-explicit") {
|
|
3058
|
+
throw new Error(
|
|
3059
|
+
`Metadata policy requires explicit displayNamePlural for ${declarationKind} "${logicalName}" on the tsdoc surface.`
|
|
3060
|
+
);
|
|
3061
|
+
}
|
|
3062
|
+
return resolvedMetadata;
|
|
2989
3063
|
}
|
|
2990
3064
|
function analyzeDeclarationRootInfo(declaration, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
2991
|
-
const normalizedMetadataPolicy =
|
|
3065
|
+
const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
|
|
2992
3066
|
const declarationType = checker.getTypeAtLocation(declaration);
|
|
2993
3067
|
const logicalName = ts3.isClassDeclaration(declaration) ? declaration.name?.text ?? "AnonymousClass" : declaration.name.text;
|
|
2994
3068
|
const docResult = extractJSDocParseResult(
|
|
@@ -2996,20 +3070,31 @@ function analyzeDeclarationRootInfo(declaration, checker, file = "", extensionRe
|
|
|
2996
3070
|
file,
|
|
2997
3071
|
makeParseOptions(extensionRegistry, void 0, checker, declarationType, declarationType)
|
|
2998
3072
|
);
|
|
2999
|
-
const metadata = resolveNodeMetadata(
|
|
3000
|
-
|
|
3073
|
+
const metadata = resolveNodeMetadata(
|
|
3074
|
+
normalizedMetadataPolicy,
|
|
3075
|
+
"type",
|
|
3076
|
+
logicalName,
|
|
3001
3077
|
declaration,
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3078
|
+
checker,
|
|
3079
|
+
extensionRegistry,
|
|
3080
|
+
{
|
|
3081
|
+
checker,
|
|
3082
|
+
declaration,
|
|
3083
|
+
subjectType: declarationType,
|
|
3084
|
+
hostType: declarationType
|
|
3085
|
+
}
|
|
3086
|
+
);
|
|
3005
3087
|
return {
|
|
3006
3088
|
...metadata !== void 0 && { metadata },
|
|
3007
3089
|
annotations: docResult.annotations,
|
|
3008
3090
|
diagnostics: docResult.diagnostics
|
|
3009
3091
|
};
|
|
3010
3092
|
}
|
|
3011
|
-
function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
3012
|
-
const normalizedMetadataPolicy =
|
|
3093
|
+
function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, metadataPolicy, discriminatorOptions) {
|
|
3094
|
+
const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(
|
|
3095
|
+
metadataPolicy,
|
|
3096
|
+
discriminatorOptions
|
|
3097
|
+
);
|
|
3013
3098
|
const name = classDecl.name?.text ?? "AnonymousClass";
|
|
3014
3099
|
const fields = [];
|
|
3015
3100
|
const fieldLayouts = [];
|
|
@@ -3064,12 +3149,20 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
|
|
|
3064
3149
|
diagnostics,
|
|
3065
3150
|
normalizedMetadataPolicy
|
|
3066
3151
|
);
|
|
3067
|
-
const metadata = resolveNodeMetadata(
|
|
3152
|
+
const metadata = resolveNodeMetadata(
|
|
3153
|
+
normalizedMetadataPolicy,
|
|
3154
|
+
"type",
|
|
3155
|
+
name,
|
|
3156
|
+
classDecl,
|
|
3068
3157
|
checker,
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3158
|
+
extensionRegistry,
|
|
3159
|
+
{
|
|
3160
|
+
checker,
|
|
3161
|
+
declaration: classDecl,
|
|
3162
|
+
subjectType: classType,
|
|
3163
|
+
hostType: classType
|
|
3164
|
+
}
|
|
3165
|
+
);
|
|
3073
3166
|
return {
|
|
3074
3167
|
name,
|
|
3075
3168
|
...metadata !== void 0 && { metadata },
|
|
@@ -3082,8 +3175,11 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
|
|
|
3082
3175
|
staticMethods
|
|
3083
3176
|
};
|
|
3084
3177
|
}
|
|
3085
|
-
function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
3086
|
-
const normalizedMetadataPolicy =
|
|
3178
|
+
function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegistry, metadataPolicy, discriminatorOptions) {
|
|
3179
|
+
const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(
|
|
3180
|
+
metadataPolicy,
|
|
3181
|
+
discriminatorOptions
|
|
3182
|
+
);
|
|
3087
3183
|
const name = interfaceDecl.name.text;
|
|
3088
3184
|
const fields = [];
|
|
3089
3185
|
const typeRegistry = {};
|
|
@@ -3125,12 +3221,20 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
|
|
|
3125
3221
|
normalizedMetadataPolicy
|
|
3126
3222
|
);
|
|
3127
3223
|
const fieldLayouts = specializedFields.map(() => ({}));
|
|
3128
|
-
const metadata = resolveNodeMetadata(
|
|
3224
|
+
const metadata = resolveNodeMetadata(
|
|
3225
|
+
normalizedMetadataPolicy,
|
|
3226
|
+
"type",
|
|
3227
|
+
name,
|
|
3228
|
+
interfaceDecl,
|
|
3129
3229
|
checker,
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3230
|
+
extensionRegistry,
|
|
3231
|
+
{
|
|
3232
|
+
checker,
|
|
3233
|
+
declaration: interfaceDecl,
|
|
3234
|
+
subjectType: interfaceType,
|
|
3235
|
+
hostType: interfaceType
|
|
3236
|
+
}
|
|
3237
|
+
);
|
|
3134
3238
|
return {
|
|
3135
3239
|
name,
|
|
3136
3240
|
...metadata !== void 0 && { metadata },
|
|
@@ -3143,19 +3247,31 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
|
|
|
3143
3247
|
staticMethods: []
|
|
3144
3248
|
};
|
|
3145
3249
|
}
|
|
3146
|
-
function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
3147
|
-
|
|
3250
|
+
function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry, metadataPolicy, discriminatorOptions) {
|
|
3251
|
+
const members = getObjectLikeTypeAliasMembers(typeAlias.type);
|
|
3252
|
+
if (members === null) {
|
|
3148
3253
|
const sourceFile = typeAlias.getSourceFile();
|
|
3149
3254
|
const { line } = sourceFile.getLineAndCharacterOfPosition(typeAlias.getStart());
|
|
3150
3255
|
const kindDesc = ts3.SyntaxKind[typeAlias.type.kind] ?? "unknown";
|
|
3151
3256
|
return {
|
|
3152
3257
|
ok: false,
|
|
3153
|
-
error: `Type alias "${typeAlias.name.text}" at line ${String(line + 1)} is not an object type
|
|
3258
|
+
error: `Type alias "${typeAlias.name.text}" at line ${String(line + 1)} is not an object-like type alias (found ${kindDesc})`
|
|
3154
3259
|
};
|
|
3155
3260
|
}
|
|
3156
|
-
const
|
|
3157
|
-
|
|
3261
|
+
const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(
|
|
3262
|
+
metadataPolicy,
|
|
3263
|
+
discriminatorOptions
|
|
3264
|
+
);
|
|
3158
3265
|
const name = typeAlias.name.text;
|
|
3266
|
+
const duplicatePropertyNames = findDuplicateObjectLikeTypeAliasPropertyNames(members);
|
|
3267
|
+
if (duplicatePropertyNames.length > 0) {
|
|
3268
|
+
const sourceFile = typeAlias.getSourceFile();
|
|
3269
|
+
const { line } = sourceFile.getLineAndCharacterOfPosition(typeAlias.getStart());
|
|
3270
|
+
return {
|
|
3271
|
+
ok: false,
|
|
3272
|
+
error: `Type alias "${name}" at line ${String(line + 1)} contains duplicate property names across object-like members: ${duplicatePropertyNames.join(", ")}`
|
|
3273
|
+
};
|
|
3274
|
+
}
|
|
3159
3275
|
const fields = [];
|
|
3160
3276
|
const typeRegistry = {};
|
|
3161
3277
|
const diagnostics = [];
|
|
@@ -3168,7 +3284,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
|
|
|
3168
3284
|
const annotations = [...typeAliasDoc.annotations];
|
|
3169
3285
|
diagnostics.push(...typeAliasDoc.diagnostics);
|
|
3170
3286
|
const visiting = /* @__PURE__ */ new Set();
|
|
3171
|
-
for (const member of
|
|
3287
|
+
for (const member of members) {
|
|
3172
3288
|
if (ts3.isPropertySignature(member)) {
|
|
3173
3289
|
const fieldNode = analyzeInterfacePropertyToIR(
|
|
3174
3290
|
member,
|
|
@@ -3195,12 +3311,20 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
|
|
|
3195
3311
|
diagnostics,
|
|
3196
3312
|
normalizedMetadataPolicy
|
|
3197
3313
|
);
|
|
3198
|
-
const metadata = resolveNodeMetadata(
|
|
3314
|
+
const metadata = resolveNodeMetadata(
|
|
3315
|
+
normalizedMetadataPolicy,
|
|
3316
|
+
"type",
|
|
3317
|
+
name,
|
|
3318
|
+
typeAlias,
|
|
3199
3319
|
checker,
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3320
|
+
extensionRegistry,
|
|
3321
|
+
{
|
|
3322
|
+
checker,
|
|
3323
|
+
declaration: typeAlias,
|
|
3324
|
+
subjectType: aliasType,
|
|
3325
|
+
hostType: aliasType
|
|
3326
|
+
}
|
|
3327
|
+
);
|
|
3204
3328
|
return {
|
|
3205
3329
|
ok: true,
|
|
3206
3330
|
analysis: {
|
|
@@ -3241,7 +3365,7 @@ function getLeadingParsedTags(node) {
|
|
|
3241
3365
|
if (!commentText.startsWith("/**")) {
|
|
3242
3366
|
continue;
|
|
3243
3367
|
}
|
|
3244
|
-
parsedTags.push(...(0,
|
|
3368
|
+
parsedTags.push(...(0, import_internal3.parseCommentBlock)(commentText, { offset: range.pos }).tags);
|
|
3245
3369
|
}
|
|
3246
3370
|
return parsedTags;
|
|
3247
3371
|
}
|
|
@@ -3269,15 +3393,43 @@ function isNullishSemanticType(type) {
|
|
|
3269
3393
|
}
|
|
3270
3394
|
return type.isUnion() && type.types.some((member) => isNullishSemanticType(member));
|
|
3271
3395
|
}
|
|
3272
|
-
function isStringLikeSemanticType(type) {
|
|
3396
|
+
function isStringLikeSemanticType(type, checker, seen = /* @__PURE__ */ new Set()) {
|
|
3397
|
+
if (seen.has(type)) {
|
|
3398
|
+
return false;
|
|
3399
|
+
}
|
|
3400
|
+
seen.add(type);
|
|
3273
3401
|
if (type.flags & ts3.TypeFlags.StringLike) {
|
|
3274
3402
|
return true;
|
|
3275
3403
|
}
|
|
3276
3404
|
if (type.isUnion()) {
|
|
3277
|
-
return type.types.length > 0 && type.types.every((member) => isStringLikeSemanticType(member));
|
|
3405
|
+
return type.types.length > 0 && type.types.every((member) => isStringLikeSemanticType(member, checker, seen));
|
|
3406
|
+
}
|
|
3407
|
+
const baseConstraint = checker.getBaseConstraintOfType(type);
|
|
3408
|
+
if (baseConstraint !== void 0 && baseConstraint !== type) {
|
|
3409
|
+
return isStringLikeSemanticType(baseConstraint, checker, seen);
|
|
3278
3410
|
}
|
|
3279
3411
|
return false;
|
|
3280
3412
|
}
|
|
3413
|
+
function getObjectLikeTypeAliasMembers(typeNode) {
|
|
3414
|
+
if (ts3.isParenthesizedTypeNode(typeNode)) {
|
|
3415
|
+
return getObjectLikeTypeAliasMembers(typeNode.type);
|
|
3416
|
+
}
|
|
3417
|
+
if (ts3.isTypeLiteralNode(typeNode)) {
|
|
3418
|
+
return [...typeNode.members];
|
|
3419
|
+
}
|
|
3420
|
+
if (ts3.isIntersectionTypeNode(typeNode)) {
|
|
3421
|
+
const members = [];
|
|
3422
|
+
for (const intersectionMember of typeNode.types) {
|
|
3423
|
+
const resolvedMembers = getObjectLikeTypeAliasMembers(intersectionMember);
|
|
3424
|
+
if (resolvedMembers === null) {
|
|
3425
|
+
return null;
|
|
3426
|
+
}
|
|
3427
|
+
members.push(...resolvedMembers);
|
|
3428
|
+
}
|
|
3429
|
+
return members;
|
|
3430
|
+
}
|
|
3431
|
+
return null;
|
|
3432
|
+
}
|
|
3281
3433
|
function extractDiscriminatorDirective(node, file, diagnostics) {
|
|
3282
3434
|
const discriminatorTags = getLeadingParsedTags(node).filter(
|
|
3283
3435
|
(tag) => tag.normalizedTagName === "discriminator"
|
|
@@ -3384,7 +3536,7 @@ function validateDiscriminatorDirective(node, checker, file, diagnostics) {
|
|
|
3384
3536
|
);
|
|
3385
3537
|
return null;
|
|
3386
3538
|
}
|
|
3387
|
-
if (!isStringLikeSemanticType(property.type)) {
|
|
3539
|
+
if (!isStringLikeSemanticType(property.type, checker)) {
|
|
3388
3540
|
diagnostics.push(
|
|
3389
3541
|
makeAnalysisDiagnostic(
|
|
3390
3542
|
"TYPE_MISMATCH",
|
|
@@ -3411,8 +3563,8 @@ function getConcreteTypeArgumentForDiscriminator(node, subjectType, checker, typ
|
|
|
3411
3563
|
const localTypeParameter = node.typeParameters?.[typeParameterIndex];
|
|
3412
3564
|
return localTypeParameter === void 0 ? null : checker.getTypeAtLocation(localTypeParameter);
|
|
3413
3565
|
}
|
|
3414
|
-
function resolveLiteralDiscriminatorPropertyValue(boundType,
|
|
3415
|
-
const propertySymbol = boundType.getProperty(
|
|
3566
|
+
function resolveLiteralDiscriminatorPropertyValue(boundType, propertyName, checker, provenance, diagnostics) {
|
|
3567
|
+
const propertySymbol = boundType.getProperty(propertyName);
|
|
3416
3568
|
if (propertySymbol === void 0) {
|
|
3417
3569
|
return void 0;
|
|
3418
3570
|
}
|
|
@@ -3443,6 +3595,9 @@ function resolveLiteralDiscriminatorPropertyValue(boundType, fieldName, checker,
|
|
|
3443
3595
|
}
|
|
3444
3596
|
return void 0;
|
|
3445
3597
|
}
|
|
3598
|
+
function getDiscriminatorIdentityPropertyNames(fieldName) {
|
|
3599
|
+
return fieldName === "object" ? ["object"] : [fieldName, "object"];
|
|
3600
|
+
}
|
|
3446
3601
|
function resolveDiscriminatorApiName(boundType, checker, metadataPolicy) {
|
|
3447
3602
|
const declaration = resolveNamedDiscriminatorDeclaration(boundType, checker);
|
|
3448
3603
|
if (declaration === null) {
|
|
@@ -3453,6 +3608,8 @@ function resolveDiscriminatorApiName(boundType, checker, metadataPolicy) {
|
|
|
3453
3608
|
"type",
|
|
3454
3609
|
getDiscriminatorLogicalName(boundType, declaration, checker),
|
|
3455
3610
|
declaration,
|
|
3611
|
+
checker,
|
|
3612
|
+
void 0,
|
|
3456
3613
|
{
|
|
3457
3614
|
checker,
|
|
3458
3615
|
declaration,
|
|
@@ -3461,6 +3618,10 @@ function resolveDiscriminatorApiName(boundType, checker, metadataPolicy) {
|
|
|
3461
3618
|
);
|
|
3462
3619
|
return metadata?.apiName;
|
|
3463
3620
|
}
|
|
3621
|
+
function applyDiscriminatorApiNamePrefix(value, discriminatorOptions) {
|
|
3622
|
+
const prefix = discriminatorOptions?.apiNamePrefix;
|
|
3623
|
+
return prefix === void 0 || prefix === "" ? value : `${prefix}${value}`;
|
|
3624
|
+
}
|
|
3464
3625
|
function resolveNamedDiscriminatorDeclaration(type, checker, seen = /* @__PURE__ */ new Set()) {
|
|
3465
3626
|
if (seen.has(type)) {
|
|
3466
3627
|
return null;
|
|
@@ -3515,22 +3676,27 @@ function resolveDiscriminatorValue(boundType, fieldName, checker, provenance, di
|
|
|
3515
3676
|
return null;
|
|
3516
3677
|
}
|
|
3517
3678
|
}
|
|
3518
|
-
const
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3679
|
+
for (const identityPropertyName of getDiscriminatorIdentityPropertyNames(fieldName)) {
|
|
3680
|
+
const literalIdentityValue = resolveLiteralDiscriminatorPropertyValue(
|
|
3681
|
+
boundType,
|
|
3682
|
+
identityPropertyName,
|
|
3683
|
+
checker,
|
|
3684
|
+
provenance,
|
|
3685
|
+
diagnostics
|
|
3686
|
+
);
|
|
3687
|
+
if (literalIdentityValue === null) {
|
|
3688
|
+
return null;
|
|
3689
|
+
}
|
|
3690
|
+
if (literalIdentityValue !== void 0) {
|
|
3691
|
+
return literalIdentityValue;
|
|
3692
|
+
}
|
|
3527
3693
|
}
|
|
3528
3694
|
const apiName = resolveDiscriminatorApiName(boundType, checker, metadataPolicy);
|
|
3529
3695
|
if (apiName?.source === "explicit") {
|
|
3530
|
-
return apiName.value;
|
|
3696
|
+
return applyDiscriminatorApiNamePrefix(apiName.value, metadataPolicy.discriminator);
|
|
3531
3697
|
}
|
|
3532
3698
|
if (apiName?.source === "inferred") {
|
|
3533
|
-
return apiName.value;
|
|
3699
|
+
return applyDiscriminatorApiNamePrefix(apiName.value, metadataPolicy.discriminator);
|
|
3534
3700
|
}
|
|
3535
3701
|
diagnostics.push(
|
|
3536
3702
|
makeAnalysisDiagnostic(
|
|
@@ -3593,15 +3759,20 @@ function buildInstantiatedReferenceName(baseName, typeArguments, checker) {
|
|
|
3593
3759
|
return renderedArguments.length === 0 ? baseName : `${baseName}__${renderedArguments.join("__")}`;
|
|
3594
3760
|
}
|
|
3595
3761
|
function extractReferenceTypeArguments(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy, extensionRegistry, diagnostics) {
|
|
3596
|
-
const
|
|
3597
|
-
if (
|
|
3762
|
+
const sourceTypeNode = sourceNode === void 0 ? void 0 : extractTypeNodeFromSource(sourceNode);
|
|
3763
|
+
if (sourceTypeNode === void 0) {
|
|
3598
3764
|
return [];
|
|
3599
3765
|
}
|
|
3600
|
-
const
|
|
3601
|
-
|
|
3766
|
+
const unwrapParentheses = (typeNode) => ts3.isParenthesizedTypeNode(typeNode) ? unwrapParentheses(typeNode.type) : typeNode;
|
|
3767
|
+
const directTypeNode = unwrapParentheses(sourceTypeNode);
|
|
3768
|
+
const referenceTypeNode = ts3.isTypeReferenceNode(directTypeNode) ? directTypeNode : (() => {
|
|
3769
|
+
const resolvedTypeNode = resolveAliasedTypeNode(directTypeNode, checker);
|
|
3770
|
+
return ts3.isTypeReferenceNode(resolvedTypeNode) ? resolvedTypeNode : null;
|
|
3771
|
+
})();
|
|
3772
|
+
if (referenceTypeNode?.typeArguments === void 0) {
|
|
3602
3773
|
return [];
|
|
3603
3774
|
}
|
|
3604
|
-
return
|
|
3775
|
+
return referenceTypeNode.typeArguments.map((argumentNode) => {
|
|
3605
3776
|
const argumentType = checker.getTypeFromTypeNode(argumentNode);
|
|
3606
3777
|
return {
|
|
3607
3778
|
tsType: argumentType,
|
|
@@ -3689,12 +3860,20 @@ function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnosti
|
|
|
3689
3860
|
annotations.push(defaultAnnotation);
|
|
3690
3861
|
}
|
|
3691
3862
|
({ type, annotations } = applyEnumMemberDisplayNames(type, annotations));
|
|
3692
|
-
const metadata = resolveNodeMetadata(
|
|
3863
|
+
const metadata = resolveNodeMetadata(
|
|
3864
|
+
metadataPolicy,
|
|
3865
|
+
"field",
|
|
3866
|
+
name,
|
|
3867
|
+
prop,
|
|
3693
3868
|
checker,
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3869
|
+
extensionRegistry,
|
|
3870
|
+
{
|
|
3871
|
+
checker,
|
|
3872
|
+
declaration: prop,
|
|
3873
|
+
subjectType: tsType,
|
|
3874
|
+
hostType
|
|
3875
|
+
}
|
|
3876
|
+
);
|
|
3698
3877
|
return {
|
|
3699
3878
|
kind: "field",
|
|
3700
3879
|
name,
|
|
@@ -3707,10 +3886,10 @@ function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnosti
|
|
|
3707
3886
|
};
|
|
3708
3887
|
}
|
|
3709
3888
|
function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visiting, diagnostics, hostType, metadataPolicy, extensionRegistry) {
|
|
3710
|
-
|
|
3889
|
+
const name = getAnalyzableObjectLikePropertyName(prop.name);
|
|
3890
|
+
if (name === null) {
|
|
3711
3891
|
return null;
|
|
3712
3892
|
}
|
|
3713
|
-
const name = prop.name.text;
|
|
3714
3893
|
const tsType = checker.getTypeAtLocation(prop);
|
|
3715
3894
|
const optional = prop.questionToken !== void 0;
|
|
3716
3895
|
const provenance = provenanceForNode(prop, file);
|
|
@@ -3741,12 +3920,20 @@ function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visitin
|
|
|
3741
3920
|
let annotations = [];
|
|
3742
3921
|
annotations.push(...docResult.annotations);
|
|
3743
3922
|
({ type, annotations } = applyEnumMemberDisplayNames(type, annotations));
|
|
3744
|
-
const metadata = resolveNodeMetadata(
|
|
3923
|
+
const metadata = resolveNodeMetadata(
|
|
3924
|
+
metadataPolicy,
|
|
3925
|
+
"field",
|
|
3926
|
+
name,
|
|
3927
|
+
prop,
|
|
3745
3928
|
checker,
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
3929
|
+
extensionRegistry,
|
|
3930
|
+
{
|
|
3931
|
+
checker,
|
|
3932
|
+
declaration: prop,
|
|
3933
|
+
subjectType: tsType,
|
|
3934
|
+
hostType
|
|
3935
|
+
}
|
|
3936
|
+
);
|
|
3750
3937
|
return {
|
|
3751
3938
|
kind: "field",
|
|
3752
3939
|
name,
|
|
@@ -3758,6 +3945,31 @@ function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visitin
|
|
|
3758
3945
|
provenance
|
|
3759
3946
|
};
|
|
3760
3947
|
}
|
|
3948
|
+
function findDuplicateObjectLikeTypeAliasPropertyNames(members) {
|
|
3949
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3950
|
+
const duplicates = /* @__PURE__ */ new Set();
|
|
3951
|
+
for (const member of members) {
|
|
3952
|
+
if (!ts3.isPropertySignature(member)) {
|
|
3953
|
+
continue;
|
|
3954
|
+
}
|
|
3955
|
+
const name = getAnalyzableObjectLikePropertyName(member.name);
|
|
3956
|
+
if (name === null) {
|
|
3957
|
+
continue;
|
|
3958
|
+
}
|
|
3959
|
+
if (seen.has(name)) {
|
|
3960
|
+
duplicates.add(name);
|
|
3961
|
+
continue;
|
|
3962
|
+
}
|
|
3963
|
+
seen.add(name);
|
|
3964
|
+
}
|
|
3965
|
+
return [...duplicates].sort();
|
|
3966
|
+
}
|
|
3967
|
+
function getAnalyzableObjectLikePropertyName(name) {
|
|
3968
|
+
if (!ts3.isIdentifier(name)) {
|
|
3969
|
+
return null;
|
|
3970
|
+
}
|
|
3971
|
+
return name.text;
|
|
3972
|
+
}
|
|
3761
3973
|
function applyEnumMemberDisplayNames(type, annotations) {
|
|
3762
3974
|
if (!annotations.some(
|
|
3763
3975
|
(annotation) => annotation.annotationKind === "displayName" && annotation.value.trim().startsWith(":")
|
|
@@ -3875,7 +4087,7 @@ function getTypeNodeRegistrationName(typeNode) {
|
|
|
3875
4087
|
}
|
|
3876
4088
|
return null;
|
|
3877
4089
|
}
|
|
3878
|
-
function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
4090
|
+
function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
3879
4091
|
const customType = resolveRegisteredCustomType(sourceNode, extensionRegistry, checker);
|
|
3880
4092
|
if (customType) {
|
|
3881
4093
|
return customType;
|
|
@@ -3950,6 +4162,23 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
|
|
|
3950
4162
|
diagnostics
|
|
3951
4163
|
);
|
|
3952
4164
|
}
|
|
4165
|
+
if (isIntersectionType(type)) {
|
|
4166
|
+
const sourceTypeNode = sourceNode === void 0 ? void 0 : extractTypeNodeFromSource(sourceNode);
|
|
4167
|
+
const resolvedSourceTypeNode = sourceTypeNode === void 0 ? void 0 : resolveAliasedTypeNode(sourceTypeNode, checker);
|
|
4168
|
+
if (resolvedSourceTypeNode !== void 0 && getObjectLikeTypeAliasMembers(resolvedSourceTypeNode) !== null) {
|
|
4169
|
+
return resolveObjectType(
|
|
4170
|
+
type,
|
|
4171
|
+
checker,
|
|
4172
|
+
file,
|
|
4173
|
+
typeRegistry,
|
|
4174
|
+
visiting,
|
|
4175
|
+
sourceNode,
|
|
4176
|
+
metadataPolicy,
|
|
4177
|
+
extensionRegistry,
|
|
4178
|
+
diagnostics
|
|
4179
|
+
);
|
|
4180
|
+
}
|
|
4181
|
+
}
|
|
3953
4182
|
if (isObjectType(type)) {
|
|
3954
4183
|
return resolveObjectType(
|
|
3955
4184
|
type,
|
|
@@ -3965,7 +4194,7 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
|
|
|
3965
4194
|
}
|
|
3966
4195
|
return { kind: "primitive", primitiveKind: "string" };
|
|
3967
4196
|
}
|
|
3968
|
-
function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
4197
|
+
function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
3969
4198
|
if (!(type.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null))) {
|
|
3970
4199
|
return null;
|
|
3971
4200
|
}
|
|
@@ -3985,11 +4214,19 @@ function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiti
|
|
|
3985
4214
|
file,
|
|
3986
4215
|
makeParseOptions(extensionRegistry)
|
|
3987
4216
|
);
|
|
3988
|
-
const metadata = resolveNodeMetadata(
|
|
4217
|
+
const metadata = resolveNodeMetadata(
|
|
4218
|
+
metadataPolicy,
|
|
4219
|
+
"type",
|
|
4220
|
+
aliasName,
|
|
4221
|
+
aliasDecl,
|
|
3989
4222
|
checker,
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
4223
|
+
extensionRegistry,
|
|
4224
|
+
{
|
|
4225
|
+
checker,
|
|
4226
|
+
declaration: aliasDecl,
|
|
4227
|
+
subjectType: aliasType
|
|
4228
|
+
}
|
|
4229
|
+
);
|
|
3993
4230
|
typeRegistry[aliasName] = {
|
|
3994
4231
|
name: aliasName,
|
|
3995
4232
|
...metadata !== void 0 && { metadata },
|
|
@@ -4028,7 +4265,7 @@ function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
|
|
|
4028
4265
|
const resolved = checker.getTypeFromTypeNode(aliasDecl.type);
|
|
4029
4266
|
return !!(resolved.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null));
|
|
4030
4267
|
}
|
|
4031
|
-
function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy =
|
|
4268
|
+
function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
4032
4269
|
const nestedAliasDecl = type.aliasSymbol?.declarations?.find(ts3.isTypeAliasDeclaration);
|
|
4033
4270
|
if (nestedAliasDecl !== void 0) {
|
|
4034
4271
|
return resolveAliasedPrimitiveTarget(
|
|
@@ -4054,7 +4291,7 @@ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiti
|
|
|
4054
4291
|
diagnostics
|
|
4055
4292
|
);
|
|
4056
4293
|
}
|
|
4057
|
-
function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
4294
|
+
function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
4058
4295
|
const typeName = getNamedTypeName(type);
|
|
4059
4296
|
const namedDecl = getNamedTypeDeclaration(type);
|
|
4060
4297
|
if (typeName && typeName in typeRegistry) {
|
|
@@ -4089,11 +4326,19 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
4089
4326
|
return result;
|
|
4090
4327
|
}
|
|
4091
4328
|
const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
|
|
4092
|
-
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
4329
|
+
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
4330
|
+
metadataPolicy,
|
|
4331
|
+
"type",
|
|
4332
|
+
typeName,
|
|
4333
|
+
namedDecl,
|
|
4093
4334
|
checker,
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4335
|
+
extensionRegistry,
|
|
4336
|
+
{
|
|
4337
|
+
checker,
|
|
4338
|
+
declaration: namedDecl,
|
|
4339
|
+
subjectType: type
|
|
4340
|
+
}
|
|
4341
|
+
) : void 0;
|
|
4097
4342
|
typeRegistry[typeName] = {
|
|
4098
4343
|
name: typeName,
|
|
4099
4344
|
...metadata !== void 0 && { metadata },
|
|
@@ -4178,7 +4423,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
4178
4423
|
}
|
|
4179
4424
|
return registerNamed({ kind: "union", members });
|
|
4180
4425
|
}
|
|
4181
|
-
function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
4426
|
+
function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
4182
4427
|
const typeArgs = isTypeReference(type) ? type.typeArguments : void 0;
|
|
4183
4428
|
const elementType = typeArgs?.[0];
|
|
4184
4429
|
const elementSourceNode = extractArrayElementTypeNode(sourceNode, checker);
|
|
@@ -4195,7 +4440,7 @@ function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
4195
4440
|
) : { kind: "primitive", primitiveKind: "string" };
|
|
4196
4441
|
return { kind: "array", items };
|
|
4197
4442
|
}
|
|
4198
|
-
function tryResolveRecordType(type, checker, file, typeRegistry, visiting, metadataPolicy =
|
|
4443
|
+
function tryResolveRecordType(type, checker, file, typeRegistry, visiting, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
4199
4444
|
if (type.getProperties().length > 0) {
|
|
4200
4445
|
return null;
|
|
4201
4446
|
}
|
|
@@ -4256,7 +4501,7 @@ function shouldEmitResolvedObjectProperty(property, declaration) {
|
|
|
4256
4501
|
}
|
|
4257
4502
|
return true;
|
|
4258
4503
|
}
|
|
4259
|
-
function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
4504
|
+
function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
4260
4505
|
const collectedDiagnostics = diagnostics ?? [];
|
|
4261
4506
|
const typeName = getNamedTypeName(type);
|
|
4262
4507
|
const namedTypeName = typeName ?? void 0;
|
|
@@ -4313,7 +4558,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
4313
4558
|
};
|
|
4314
4559
|
}
|
|
4315
4560
|
}
|
|
4316
|
-
const recordNode = tryResolveRecordType(
|
|
4561
|
+
const recordNode = isObjectType(type) ? tryResolveRecordType(
|
|
4317
4562
|
type,
|
|
4318
4563
|
checker,
|
|
4319
4564
|
file,
|
|
@@ -4322,7 +4567,7 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
4322
4567
|
metadataPolicy,
|
|
4323
4568
|
extensionRegistry,
|
|
4324
4569
|
collectedDiagnostics
|
|
4325
|
-
);
|
|
4570
|
+
) : null;
|
|
4326
4571
|
if (recordNode) {
|
|
4327
4572
|
visiting.delete(type);
|
|
4328
4573
|
if (registryTypeName !== void 0 && shouldRegisterNamedType) {
|
|
@@ -4332,11 +4577,19 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
4332
4577
|
return recordNode;
|
|
4333
4578
|
}
|
|
4334
4579
|
const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
|
|
4335
|
-
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
4580
|
+
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
4581
|
+
metadataPolicy,
|
|
4582
|
+
"type",
|
|
4583
|
+
registryTypeName,
|
|
4584
|
+
namedDecl,
|
|
4336
4585
|
checker,
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4586
|
+
extensionRegistry,
|
|
4587
|
+
{
|
|
4588
|
+
checker,
|
|
4589
|
+
declaration: namedDecl,
|
|
4590
|
+
subjectType: type
|
|
4591
|
+
}
|
|
4592
|
+
) : void 0;
|
|
4340
4593
|
typeRegistry[registryTypeName] = {
|
|
4341
4594
|
name: registryTypeName,
|
|
4342
4595
|
...metadata !== void 0 && { metadata },
|
|
@@ -4432,11 +4685,19 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
4432
4685
|
};
|
|
4433
4686
|
if (registryTypeName !== void 0 && shouldRegisterNamedType) {
|
|
4434
4687
|
const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
|
|
4435
|
-
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
4688
|
+
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
4689
|
+
metadataPolicy,
|
|
4690
|
+
"type",
|
|
4691
|
+
registryTypeName,
|
|
4692
|
+
namedDecl,
|
|
4436
4693
|
checker,
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
|
|
4694
|
+
extensionRegistry,
|
|
4695
|
+
{
|
|
4696
|
+
checker,
|
|
4697
|
+
declaration: namedDecl,
|
|
4698
|
+
subjectType: type
|
|
4699
|
+
}
|
|
4700
|
+
) : void 0;
|
|
4440
4701
|
typeRegistry[registryTypeName] = {
|
|
4441
4702
|
name: registryTypeName,
|
|
4442
4703
|
...metadata !== void 0 && { metadata },
|
|
@@ -4503,9 +4764,10 @@ function getNamedTypeFieldNodeInfoMap(type, checker, file, typeRegistry, visitin
|
|
|
4503
4764
|
);
|
|
4504
4765
|
}
|
|
4505
4766
|
const typeAliasDecl = declarations.find(ts3.isTypeAliasDeclaration);
|
|
4506
|
-
|
|
4767
|
+
const typeAliasMembers = typeAliasDecl === void 0 ? null : getObjectLikeTypeAliasMembers(typeAliasDecl.type);
|
|
4768
|
+
if (typeAliasDecl && typeAliasMembers !== null) {
|
|
4507
4769
|
return buildFieldNodeInfoMap(
|
|
4508
|
-
|
|
4770
|
+
typeAliasMembers,
|
|
4509
4771
|
checker,
|
|
4510
4772
|
file,
|
|
4511
4773
|
typeRegistry,
|
|
@@ -4713,12 +4975,12 @@ function detectFormSpecReference(typeNode) {
|
|
|
4713
4975
|
}
|
|
4714
4976
|
return null;
|
|
4715
4977
|
}
|
|
4716
|
-
var ts3,
|
|
4978
|
+
var ts3, import_internal3, RESOLVING_TYPE_PLACEHOLDER, MAX_ALIAS_CHAIN_DEPTH;
|
|
4717
4979
|
var init_class_analyzer = __esm({
|
|
4718
4980
|
"src/analyzer/class-analyzer.ts"() {
|
|
4719
4981
|
"use strict";
|
|
4720
4982
|
ts3 = __toESM(require("typescript"), 1);
|
|
4721
|
-
|
|
4983
|
+
import_internal3 = require("@formspec/analysis/internal");
|
|
4722
4984
|
init_jsdoc_constraints();
|
|
4723
4985
|
init_tsdoc_parser();
|
|
4724
4986
|
init_metadata();
|
|
@@ -4812,17 +5074,18 @@ function findInterfaceByName(sourceFile, interfaceName) {
|
|
|
4812
5074
|
function findTypeAliasByName(sourceFile, aliasName) {
|
|
4813
5075
|
return findNodeByName(sourceFile, aliasName, ts4.isTypeAliasDeclaration, (n) => n.name.text);
|
|
4814
5076
|
}
|
|
4815
|
-
function analyzeNamedTypeToIR(filePath, typeName, extensionRegistry, metadataPolicy) {
|
|
5077
|
+
function analyzeNamedTypeToIR(filePath, typeName, extensionRegistry, metadataPolicy, discriminatorOptions) {
|
|
4816
5078
|
const ctx = createProgramContext(filePath);
|
|
4817
5079
|
return analyzeNamedTypeToIRFromProgramContext(
|
|
4818
5080
|
ctx,
|
|
4819
5081
|
filePath,
|
|
4820
5082
|
typeName,
|
|
4821
5083
|
extensionRegistry,
|
|
4822
|
-
metadataPolicy
|
|
5084
|
+
metadataPolicy,
|
|
5085
|
+
discriminatorOptions
|
|
4823
5086
|
);
|
|
4824
5087
|
}
|
|
4825
|
-
function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensionRegistry, metadataPolicy) {
|
|
5088
|
+
function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensionRegistry, metadataPolicy, discriminatorOptions) {
|
|
4826
5089
|
const analysisFilePath = path.resolve(filePath);
|
|
4827
5090
|
const classDecl = findClassByName(ctx.sourceFile, typeName);
|
|
4828
5091
|
if (classDecl !== null) {
|
|
@@ -4831,7 +5094,8 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
|
|
|
4831
5094
|
ctx.checker,
|
|
4832
5095
|
analysisFilePath,
|
|
4833
5096
|
extensionRegistry,
|
|
4834
|
-
metadataPolicy
|
|
5097
|
+
metadataPolicy,
|
|
5098
|
+
discriminatorOptions
|
|
4835
5099
|
);
|
|
4836
5100
|
}
|
|
4837
5101
|
const interfaceDecl = findInterfaceByName(ctx.sourceFile, typeName);
|
|
@@ -4841,7 +5105,8 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
|
|
|
4841
5105
|
ctx.checker,
|
|
4842
5106
|
analysisFilePath,
|
|
4843
5107
|
extensionRegistry,
|
|
4844
|
-
metadataPolicy
|
|
5108
|
+
metadataPolicy,
|
|
5109
|
+
discriminatorOptions
|
|
4845
5110
|
);
|
|
4846
5111
|
}
|
|
4847
5112
|
const typeAlias = findTypeAliasByName(ctx.sourceFile, typeName);
|
|
@@ -4851,7 +5116,8 @@ function analyzeNamedTypeToIRFromProgramContext(ctx, filePath, typeName, extensi
|
|
|
4851
5116
|
ctx.checker,
|
|
4852
5117
|
analysisFilePath,
|
|
4853
5118
|
extensionRegistry,
|
|
4854
|
-
metadataPolicy
|
|
5119
|
+
metadataPolicy,
|
|
5120
|
+
discriminatorOptions
|
|
4855
5121
|
);
|
|
4856
5122
|
if (result.ok) {
|
|
4857
5123
|
return result.analysis;
|
|
@@ -4874,7 +5140,7 @@ var init_program = __esm({
|
|
|
4874
5140
|
|
|
4875
5141
|
// src/validate/constraint-validator.ts
|
|
4876
5142
|
function validateFieldNode(ctx, field) {
|
|
4877
|
-
const analysis = (0,
|
|
5143
|
+
const analysis = (0, import_internal4.analyzeConstraintTargets)(
|
|
4878
5144
|
field.name,
|
|
4879
5145
|
field.type,
|
|
4880
5146
|
field.constraints,
|
|
@@ -4892,7 +5158,7 @@ function validateFieldNode(ctx, field) {
|
|
|
4892
5158
|
}
|
|
4893
5159
|
function validateObjectProperty(ctx, parentName, property) {
|
|
4894
5160
|
const qualifiedName = `${parentName}.${property.name}`;
|
|
4895
|
-
const analysis = (0,
|
|
5161
|
+
const analysis = (0, import_internal4.analyzeConstraintTargets)(
|
|
4896
5162
|
qualifiedName,
|
|
4897
5163
|
property.type,
|
|
4898
5164
|
property.constraints,
|
|
@@ -4943,11 +5209,11 @@ function validateIR(ir, options) {
|
|
|
4943
5209
|
valid: ctx.diagnostics.every((diagnostic) => diagnostic.severity !== "error")
|
|
4944
5210
|
};
|
|
4945
5211
|
}
|
|
4946
|
-
var
|
|
5212
|
+
var import_internal4;
|
|
4947
5213
|
var init_constraint_validator = __esm({
|
|
4948
5214
|
"src/validate/constraint-validator.ts"() {
|
|
4949
5215
|
"use strict";
|
|
4950
|
-
|
|
5216
|
+
import_internal4 = require("@formspec/analysis/internal");
|
|
4951
5217
|
}
|
|
4952
5218
|
});
|
|
4953
5219
|
|
|
@@ -5009,7 +5275,8 @@ function generateSchemasFromClass(options) {
|
|
|
5009
5275
|
ctx.checker,
|
|
5010
5276
|
options.filePath,
|
|
5011
5277
|
options.extensionRegistry,
|
|
5012
|
-
options.metadata
|
|
5278
|
+
options.metadata,
|
|
5279
|
+
options.discriminator
|
|
5013
5280
|
);
|
|
5014
5281
|
return generateClassSchemas(
|
|
5015
5282
|
analysis,
|
|
@@ -5035,7 +5302,8 @@ function generateSchemasFromProgram(options) {
|
|
|
5035
5302
|
options.filePath,
|
|
5036
5303
|
options.typeName,
|
|
5037
5304
|
options.extensionRegistry,
|
|
5038
|
-
options.metadata
|
|
5305
|
+
options.metadata,
|
|
5306
|
+
options.discriminator
|
|
5039
5307
|
);
|
|
5040
5308
|
return generateClassSchemas(
|
|
5041
5309
|
analysis,
|
|
@@ -5213,7 +5481,7 @@ function toStandaloneJsonSchema(root, typeRegistry, options) {
|
|
|
5213
5481
|
{
|
|
5214
5482
|
kind: "form-ir",
|
|
5215
5483
|
name: root.name,
|
|
5216
|
-
irVersion:
|
|
5484
|
+
irVersion: import_internals6.IR_VERSION,
|
|
5217
5485
|
elements: [syntheticField],
|
|
5218
5486
|
...root.metadata !== void 0 && { metadata: root.metadata },
|
|
5219
5487
|
...root.annotations !== void 0 && root.annotations.length > 0 && { rootAnnotations: root.annotations },
|
|
@@ -5272,7 +5540,7 @@ function generateSchemasFromResolvedType(options, skipNamedDeclaration = false,
|
|
|
5272
5540
|
typeRegistry,
|
|
5273
5541
|
/* @__PURE__ */ new Set(),
|
|
5274
5542
|
options.sourceNode,
|
|
5275
|
-
|
|
5543
|
+
createAnalyzerMetadataPolicy(options.metadata, options.discriminator),
|
|
5276
5544
|
options.extensionRegistry,
|
|
5277
5545
|
diagnostics
|
|
5278
5546
|
);
|
|
@@ -5321,7 +5589,8 @@ function generateSchemasFromDeclaration(options) {
|
|
|
5321
5589
|
options.context.checker,
|
|
5322
5590
|
filePath,
|
|
5323
5591
|
options.extensionRegistry,
|
|
5324
|
-
options.metadata
|
|
5592
|
+
options.metadata,
|
|
5593
|
+
options.discriminator
|
|
5325
5594
|
),
|
|
5326
5595
|
filePath,
|
|
5327
5596
|
options
|
|
@@ -5334,7 +5603,8 @@ function generateSchemasFromDeclaration(options) {
|
|
|
5334
5603
|
options.context.checker,
|
|
5335
5604
|
filePath,
|
|
5336
5605
|
options.extensionRegistry,
|
|
5337
|
-
options.metadata
|
|
5606
|
+
options.metadata,
|
|
5607
|
+
options.discriminator
|
|
5338
5608
|
),
|
|
5339
5609
|
filePath,
|
|
5340
5610
|
options
|
|
@@ -5346,7 +5616,8 @@ function generateSchemasFromDeclaration(options) {
|
|
|
5346
5616
|
options.context.checker,
|
|
5347
5617
|
filePath,
|
|
5348
5618
|
options.extensionRegistry,
|
|
5349
|
-
options.metadata
|
|
5619
|
+
options.metadata,
|
|
5620
|
+
options.discriminator
|
|
5350
5621
|
);
|
|
5351
5622
|
if (analyzedAlias.ok) {
|
|
5352
5623
|
return generateSchemasFromAnalysis(analyzedAlias.analysis, filePath, options);
|
|
@@ -5404,7 +5675,7 @@ function generateSchemasFromReturnType(options) {
|
|
|
5404
5675
|
name: fallbackName
|
|
5405
5676
|
});
|
|
5406
5677
|
}
|
|
5407
|
-
var ts7,
|
|
5678
|
+
var ts7, import_internals6;
|
|
5408
5679
|
var init_discovered_schema = __esm({
|
|
5409
5680
|
"src/generators/discovered-schema.ts"() {
|
|
5410
5681
|
"use strict";
|
|
@@ -5412,7 +5683,7 @@ var init_discovered_schema = __esm({
|
|
|
5412
5683
|
init_class_analyzer();
|
|
5413
5684
|
init_class_schema();
|
|
5414
5685
|
init_ir_generator();
|
|
5415
|
-
|
|
5686
|
+
import_internals6 = require("@formspec/core/internals");
|
|
5416
5687
|
init_metadata();
|
|
5417
5688
|
}
|
|
5418
5689
|
});
|
|
@@ -5424,7 +5695,8 @@ function buildMixedAuthoringSchemas(options) {
|
|
|
5424
5695
|
filePath,
|
|
5425
5696
|
typeName,
|
|
5426
5697
|
schemaOptions.extensionRegistry,
|
|
5427
|
-
schemaOptions.metadata
|
|
5698
|
+
schemaOptions.metadata,
|
|
5699
|
+
schemaOptions.discriminator
|
|
5428
5700
|
);
|
|
5429
5701
|
const composedAnalysis = composeAnalysisWithOverlays(analysis, overlays, schemaOptions.metadata);
|
|
5430
5702
|
const ir = canonicalizeTSDoc(
|