@formspec/build 0.1.0-alpha.31 → 0.1.0-alpha.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -5
- package/dist/analyzer/class-analyzer.d.ts +11 -1
- package/dist/analyzer/class-analyzer.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 +180 -0
- package/dist/build-beta.d.ts +180 -0
- package/dist/build-internal.d.ts +180 -0
- package/dist/build.d.ts +180 -0
- package/dist/cli.cjs +723 -162
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +707 -140
- package/dist/cli.js.map +1 -1
- package/dist/extensions/registry.d.ts.map +1 -1
- package/dist/generators/discovered-schema.d.ts +112 -0
- package/dist/generators/discovered-schema.d.ts.map +1 -0
- package/dist/index.cjs +708 -159
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +689 -140
- package/dist/index.js.map +1 -1
- package/dist/internals.cjs +301 -136
- package/dist/internals.cjs.map +1 -1
- package/dist/internals.js +307 -134
- package/dist/internals.js.map +1 -1
- package/dist/static-build.d.ts +61 -0
- package/dist/static-build.d.ts.map +1 -0
- package/package.json +4 -4
package/dist/internals.js
CHANGED
|
@@ -730,6 +730,7 @@ import * as path from "path";
|
|
|
730
730
|
// src/analyzer/class-analyzer.ts
|
|
731
731
|
import * as ts3 from "typescript";
|
|
732
732
|
import {
|
|
733
|
+
analyzeMetadataForNodeWithChecker,
|
|
733
734
|
parseCommentBlock as parseCommentBlock2
|
|
734
735
|
} from "@formspec/analysis/internal";
|
|
735
736
|
|
|
@@ -743,6 +744,7 @@ import {
|
|
|
743
744
|
extractPathTarget as extractSharedPathTarget,
|
|
744
745
|
getTagDefinition,
|
|
745
746
|
hasTypeSemanticCapability,
|
|
747
|
+
normalizeFormSpecTagName,
|
|
746
748
|
parseConstraintTagValue,
|
|
747
749
|
parseDefaultValueTagValue,
|
|
748
750
|
resolveDeclarationPlacement,
|
|
@@ -779,7 +781,7 @@ function createFormSpecTSDocConfig(extensionTagNames = []) {
|
|
|
779
781
|
})
|
|
780
782
|
);
|
|
781
783
|
}
|
|
782
|
-
for (const tagName of ["displayName", "format", "placeholder"]) {
|
|
784
|
+
for (const tagName of ["apiName", "displayName", "format", "placeholder"]) {
|
|
783
785
|
config.addTagDefinition(
|
|
784
786
|
new TSDocTagDefinition({
|
|
785
787
|
tagName: "@" + tagName,
|
|
@@ -813,6 +815,16 @@ function sharedTagValueOptions(options) {
|
|
|
813
815
|
};
|
|
814
816
|
}
|
|
815
817
|
var SYNTHETIC_TYPE_FORMAT_FLAGS = ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
|
|
818
|
+
function getExtensionTypeNames(registry) {
|
|
819
|
+
if (registry === void 0) {
|
|
820
|
+
return /* @__PURE__ */ new Set();
|
|
821
|
+
}
|
|
822
|
+
return new Set(
|
|
823
|
+
registry.extensions.flatMap(
|
|
824
|
+
(ext) => (ext.types ?? []).flatMap((t) => t.tsTypeNames ?? [t.typeName])
|
|
825
|
+
)
|
|
826
|
+
);
|
|
827
|
+
}
|
|
816
828
|
function collectImportedNames(sourceFile) {
|
|
817
829
|
const importedNames = /* @__PURE__ */ new Set();
|
|
818
830
|
for (const statement of sourceFile.statements) {
|
|
@@ -852,6 +864,9 @@ function isNonReferenceIdentifier(node) {
|
|
|
852
864
|
return false;
|
|
853
865
|
}
|
|
854
866
|
function statementReferencesImportedName(statement, importedNames) {
|
|
867
|
+
if (importedNames.size === 0) {
|
|
868
|
+
return false;
|
|
869
|
+
}
|
|
855
870
|
let referencesImportedName = false;
|
|
856
871
|
const visit = (node) => {
|
|
857
872
|
if (referencesImportedName) {
|
|
@@ -866,14 +881,17 @@ function statementReferencesImportedName(statement, importedNames) {
|
|
|
866
881
|
visit(statement);
|
|
867
882
|
return referencesImportedName;
|
|
868
883
|
}
|
|
869
|
-
function buildSupportingDeclarations(sourceFile) {
|
|
884
|
+
function buildSupportingDeclarations(sourceFile, extensionTypeNames) {
|
|
870
885
|
const importedNames = collectImportedNames(sourceFile);
|
|
886
|
+
const importedNamesToSkip = new Set(
|
|
887
|
+
[...importedNames].filter((name) => !extensionTypeNames.has(name))
|
|
888
|
+
);
|
|
871
889
|
return sourceFile.statements.filter((statement) => {
|
|
872
890
|
if (ts.isImportDeclaration(statement)) return false;
|
|
873
891
|
if (ts.isImportEqualsDeclaration(statement)) return false;
|
|
874
892
|
if (ts.isExportDeclaration(statement) && statement.moduleSpecifier !== void 0)
|
|
875
893
|
return false;
|
|
876
|
-
if (
|
|
894
|
+
if (statementReferencesImportedName(statement, importedNamesToSkip)) {
|
|
877
895
|
return false;
|
|
878
896
|
}
|
|
879
897
|
return true;
|
|
@@ -1130,6 +1148,14 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
1130
1148
|
extensionId: extension.extensionId,
|
|
1131
1149
|
...extension.constraintTags !== void 0 ? {
|
|
1132
1150
|
constraintTags: extension.constraintTags.map((tag) => ({ tagName: tag.tagName }))
|
|
1151
|
+
} : {},
|
|
1152
|
+
...extension.metadataSlots !== void 0 ? {
|
|
1153
|
+
metadataSlots: extension.metadataSlots
|
|
1154
|
+
} : {},
|
|
1155
|
+
...extension.types !== void 0 ? {
|
|
1156
|
+
customTypes: extension.types.map((t) => ({
|
|
1157
|
+
tsTypeNames: t.tsTypeNames ?? [t.typeName]
|
|
1158
|
+
}))
|
|
1133
1159
|
} : {}
|
|
1134
1160
|
}))
|
|
1135
1161
|
} : {}
|
|
@@ -1151,7 +1177,10 @@ var parseResultCache = /* @__PURE__ */ new Map();
|
|
|
1151
1177
|
function getParser(options) {
|
|
1152
1178
|
const extensionTagNames = [
|
|
1153
1179
|
...options?.extensionRegistry?.extensions.flatMap(
|
|
1154
|
-
(extension) => (extension.constraintTags ?? []).map((tag) => tag.tagName)
|
|
1180
|
+
(extension) => (extension.constraintTags ?? []).map((tag) => normalizeFormSpecTagName(tag.tagName))
|
|
1181
|
+
) ?? [],
|
|
1182
|
+
...options?.extensionRegistry?.extensions.flatMap(
|
|
1183
|
+
(extension) => (extension.metadataSlots ?? []).map((slot) => normalizeFormSpecTagName(slot.tagName))
|
|
1155
1184
|
) ?? []
|
|
1156
1185
|
].sort();
|
|
1157
1186
|
const cacheKey = extensionTagNames.join("|");
|
|
@@ -1171,7 +1200,16 @@ function getExtensionRegistryCacheKey(registry) {
|
|
|
1171
1200
|
(extension) => JSON.stringify({
|
|
1172
1201
|
extensionId: extension.extensionId,
|
|
1173
1202
|
typeNames: extension.types?.map((type) => type.typeName) ?? [],
|
|
1174
|
-
constraintTags: extension.constraintTags?.map((tag) => tag.tagName) ?? []
|
|
1203
|
+
constraintTags: extension.constraintTags?.map((tag) => normalizeFormSpecTagName(tag.tagName)) ?? [],
|
|
1204
|
+
metadataSlots: extension.metadataSlots?.map((slot) => ({
|
|
1205
|
+
tagName: normalizeFormSpecTagName(slot.tagName),
|
|
1206
|
+
declarationKinds: [...slot.declarationKinds].sort(),
|
|
1207
|
+
allowBare: slot.allowBare !== false,
|
|
1208
|
+
qualifiers: (slot.qualifiers ?? []).map((qualifier) => ({
|
|
1209
|
+
qualifier: qualifier.qualifier,
|
|
1210
|
+
...qualifier.sourceQualifier !== void 0 ? { sourceQualifier: qualifier.sourceQualifier } : {}
|
|
1211
|
+
})).sort((left, right) => left.qualifier.localeCompare(right.qualifier))
|
|
1212
|
+
})) ?? []
|
|
1175
1213
|
})
|
|
1176
1214
|
).join("|");
|
|
1177
1215
|
}
|
|
@@ -1206,7 +1244,8 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
1206
1244
|
const rawTextTags = [];
|
|
1207
1245
|
const sourceFile = node.getSourceFile();
|
|
1208
1246
|
const sourceText = sourceFile.getFullText();
|
|
1209
|
-
const
|
|
1247
|
+
const extensionTypeNames = getExtensionTypeNames(options?.extensionRegistry);
|
|
1248
|
+
const supportingDeclarations = buildSupportingDeclarations(sourceFile, extensionTypeNames);
|
|
1210
1249
|
const commentRanges = ts.getLeadingCommentRanges(sourceText, node.getFullStart());
|
|
1211
1250
|
const rawTextFallbacks = collectRawTextFallbacks(node, file);
|
|
1212
1251
|
if (commentRanges) {
|
|
@@ -1634,76 +1673,50 @@ function makeParseOptions(extensionRegistry, fieldType, checker, subjectType, ho
|
|
|
1634
1673
|
...hostType !== void 0 && { hostType }
|
|
1635
1674
|
};
|
|
1636
1675
|
}
|
|
1637
|
-
function
|
|
1638
|
-
return
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
let apiName;
|
|
1642
|
-
let displayName;
|
|
1643
|
-
let apiNamePlural;
|
|
1644
|
-
let displayNamePlural;
|
|
1645
|
-
for (const tag of getLeadingParsedTags(node)) {
|
|
1646
|
-
const value = tag.argumentText.trim();
|
|
1647
|
-
if (value === "") {
|
|
1648
|
-
continue;
|
|
1649
|
-
}
|
|
1650
|
-
if (tag.normalizedTagName === "apiName") {
|
|
1651
|
-
if (tag.target === null) {
|
|
1652
|
-
apiName ??= value;
|
|
1653
|
-
} else if (tag.target.kind === "variant") {
|
|
1654
|
-
if (tag.target.rawText === "singular") {
|
|
1655
|
-
apiName ??= value;
|
|
1656
|
-
} else if (tag.target.rawText === "plural") {
|
|
1657
|
-
apiNamePlural ??= value;
|
|
1658
|
-
}
|
|
1659
|
-
}
|
|
1660
|
-
continue;
|
|
1661
|
-
}
|
|
1662
|
-
if (tag.normalizedTagName === "displayName") {
|
|
1663
|
-
if (tag.target === null) {
|
|
1664
|
-
displayName ??= value;
|
|
1665
|
-
} else if (tag.target.kind === "variant") {
|
|
1666
|
-
if (tag.target.rawText === "singular") {
|
|
1667
|
-
displayName ??= value;
|
|
1668
|
-
} else if (tag.target.rawText === "plural") {
|
|
1669
|
-
displayNamePlural ??= value;
|
|
1670
|
-
}
|
|
1671
|
-
}
|
|
1672
|
-
}
|
|
1673
|
-
}
|
|
1674
|
-
const resolvedApiName = makeExplicitScalarMetadata(apiName);
|
|
1675
|
-
const resolvedDisplayName = makeExplicitScalarMetadata(displayName);
|
|
1676
|
-
const resolvedApiNamePlural = makeExplicitScalarMetadata(apiNamePlural);
|
|
1677
|
-
const resolvedDisplayNamePlural = makeExplicitScalarMetadata(displayNamePlural);
|
|
1678
|
-
const metadata = {
|
|
1679
|
-
...resolvedApiName !== void 0 && { apiName: resolvedApiName },
|
|
1680
|
-
...resolvedDisplayName !== void 0 && { displayName: resolvedDisplayName },
|
|
1681
|
-
...resolvedApiNamePlural !== void 0 && { apiNamePlural: resolvedApiNamePlural },
|
|
1682
|
-
...resolvedDisplayNamePlural !== void 0 && {
|
|
1683
|
-
displayNamePlural: resolvedDisplayNamePlural
|
|
1684
|
-
}
|
|
1676
|
+
function createAnalyzerMetadataPolicy(input) {
|
|
1677
|
+
return {
|
|
1678
|
+
raw: input,
|
|
1679
|
+
normalized: normalizeMetadataPolicy(input)
|
|
1685
1680
|
};
|
|
1686
|
-
return Object.keys(metadata).length === 0 ? void 0 : metadata;
|
|
1687
1681
|
}
|
|
1688
|
-
function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, buildContext) {
|
|
1689
|
-
const
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
getDeclarationMetadataPolicy(metadataPolicy, declarationKind),
|
|
1702
|
-
makeMetadataContext("tsdoc", declarationKind, logicalName, buildContext)
|
|
1682
|
+
function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, checker, extensionRegistry, buildContext) {
|
|
1683
|
+
const analysis = analyzeMetadataForNodeWithChecker({
|
|
1684
|
+
checker,
|
|
1685
|
+
node,
|
|
1686
|
+
logicalName,
|
|
1687
|
+
metadata: metadataPolicy.raw,
|
|
1688
|
+
extensions: extensionRegistry?.extensions,
|
|
1689
|
+
...buildContext !== void 0 && { buildContext }
|
|
1690
|
+
});
|
|
1691
|
+
const resolvedMetadata = analysis?.resolvedMetadata;
|
|
1692
|
+
const declarationPolicy = getDeclarationMetadataPolicy(
|
|
1693
|
+
metadataPolicy.normalized,
|
|
1694
|
+
declarationKind
|
|
1703
1695
|
);
|
|
1696
|
+
if (resolvedMetadata?.apiName === void 0 && declarationPolicy.apiName.mode === "require-explicit") {
|
|
1697
|
+
throw new Error(
|
|
1698
|
+
`Metadata policy requires explicit apiName for ${declarationKind} "${logicalName}" on the tsdoc surface.`
|
|
1699
|
+
);
|
|
1700
|
+
}
|
|
1701
|
+
if (resolvedMetadata?.displayName === void 0 && declarationPolicy.displayName.mode === "require-explicit") {
|
|
1702
|
+
throw new Error(
|
|
1703
|
+
`Metadata policy requires explicit displayName for ${declarationKind} "${logicalName}" on the tsdoc surface.`
|
|
1704
|
+
);
|
|
1705
|
+
}
|
|
1706
|
+
if (resolvedMetadata?.apiNamePlural === void 0 && declarationPolicy.apiName.pluralization.mode === "require-explicit") {
|
|
1707
|
+
throw new Error(
|
|
1708
|
+
`Metadata policy requires explicit apiNamePlural for ${declarationKind} "${logicalName}" on the tsdoc surface.`
|
|
1709
|
+
);
|
|
1710
|
+
}
|
|
1711
|
+
if (resolvedMetadata?.displayNamePlural === void 0 && declarationPolicy.displayName.pluralization.mode === "require-explicit") {
|
|
1712
|
+
throw new Error(
|
|
1713
|
+
`Metadata policy requires explicit displayNamePlural for ${declarationKind} "${logicalName}" on the tsdoc surface.`
|
|
1714
|
+
);
|
|
1715
|
+
}
|
|
1716
|
+
return resolvedMetadata;
|
|
1704
1717
|
}
|
|
1705
1718
|
function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
1706
|
-
const normalizedMetadataPolicy =
|
|
1719
|
+
const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
|
|
1707
1720
|
const name = classDecl.name?.text ?? "AnonymousClass";
|
|
1708
1721
|
const fields = [];
|
|
1709
1722
|
const fieldLayouts = [];
|
|
@@ -1758,12 +1771,20 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
|
|
|
1758
1771
|
diagnostics,
|
|
1759
1772
|
normalizedMetadataPolicy
|
|
1760
1773
|
);
|
|
1761
|
-
const metadata = resolveNodeMetadata(
|
|
1774
|
+
const metadata = resolveNodeMetadata(
|
|
1775
|
+
normalizedMetadataPolicy,
|
|
1776
|
+
"type",
|
|
1777
|
+
name,
|
|
1778
|
+
classDecl,
|
|
1762
1779
|
checker,
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1780
|
+
extensionRegistry,
|
|
1781
|
+
{
|
|
1782
|
+
checker,
|
|
1783
|
+
declaration: classDecl,
|
|
1784
|
+
subjectType: classType,
|
|
1785
|
+
hostType: classType
|
|
1786
|
+
}
|
|
1787
|
+
);
|
|
1767
1788
|
return {
|
|
1768
1789
|
name,
|
|
1769
1790
|
...metadata !== void 0 && { metadata },
|
|
@@ -1777,7 +1798,7 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
|
|
|
1777
1798
|
};
|
|
1778
1799
|
}
|
|
1779
1800
|
function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
1780
|
-
const normalizedMetadataPolicy =
|
|
1801
|
+
const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
|
|
1781
1802
|
const name = interfaceDecl.name.text;
|
|
1782
1803
|
const fields = [];
|
|
1783
1804
|
const typeRegistry = {};
|
|
@@ -1819,12 +1840,20 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
|
|
|
1819
1840
|
normalizedMetadataPolicy
|
|
1820
1841
|
);
|
|
1821
1842
|
const fieldLayouts = specializedFields.map(() => ({}));
|
|
1822
|
-
const metadata = resolveNodeMetadata(
|
|
1843
|
+
const metadata = resolveNodeMetadata(
|
|
1844
|
+
normalizedMetadataPolicy,
|
|
1845
|
+
"type",
|
|
1846
|
+
name,
|
|
1847
|
+
interfaceDecl,
|
|
1823
1848
|
checker,
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1849
|
+
extensionRegistry,
|
|
1850
|
+
{
|
|
1851
|
+
checker,
|
|
1852
|
+
declaration: interfaceDecl,
|
|
1853
|
+
subjectType: interfaceType,
|
|
1854
|
+
hostType: interfaceType
|
|
1855
|
+
}
|
|
1856
|
+
);
|
|
1828
1857
|
return {
|
|
1829
1858
|
name,
|
|
1830
1859
|
...metadata !== void 0 && { metadata },
|
|
@@ -1848,7 +1877,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
|
|
|
1848
1877
|
};
|
|
1849
1878
|
}
|
|
1850
1879
|
const typeLiteral = typeAlias.type;
|
|
1851
|
-
const normalizedMetadataPolicy =
|
|
1880
|
+
const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
|
|
1852
1881
|
const name = typeAlias.name.text;
|
|
1853
1882
|
const fields = [];
|
|
1854
1883
|
const typeRegistry = {};
|
|
@@ -1889,12 +1918,20 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
|
|
|
1889
1918
|
diagnostics,
|
|
1890
1919
|
normalizedMetadataPolicy
|
|
1891
1920
|
);
|
|
1892
|
-
const metadata = resolveNodeMetadata(
|
|
1921
|
+
const metadata = resolveNodeMetadata(
|
|
1922
|
+
normalizedMetadataPolicy,
|
|
1923
|
+
"type",
|
|
1924
|
+
name,
|
|
1925
|
+
typeAlias,
|
|
1893
1926
|
checker,
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1927
|
+
extensionRegistry,
|
|
1928
|
+
{
|
|
1929
|
+
checker,
|
|
1930
|
+
declaration: typeAlias,
|
|
1931
|
+
subjectType: aliasType,
|
|
1932
|
+
hostType: aliasType
|
|
1933
|
+
}
|
|
1934
|
+
);
|
|
1898
1935
|
return {
|
|
1899
1936
|
ok: true,
|
|
1900
1937
|
analysis: {
|
|
@@ -2116,10 +2153,7 @@ function resolveLiteralDiscriminatorPropertyValue(boundType, fieldName, checker,
|
|
|
2116
2153
|
if (resolvedAnchorNode === null) {
|
|
2117
2154
|
return void 0;
|
|
2118
2155
|
}
|
|
2119
|
-
const propertyType = checker.getTypeOfSymbolAtLocation(
|
|
2120
|
-
propertySymbol,
|
|
2121
|
-
resolvedAnchorNode
|
|
2122
|
-
);
|
|
2156
|
+
const propertyType = checker.getTypeOfSymbolAtLocation(propertySymbol, resolvedAnchorNode);
|
|
2123
2157
|
if (propertyType.isStringLiteral()) {
|
|
2124
2158
|
return propertyType.value;
|
|
2125
2159
|
}
|
|
@@ -2150,6 +2184,8 @@ function resolveDiscriminatorApiName(boundType, checker, metadataPolicy) {
|
|
|
2150
2184
|
"type",
|
|
2151
2185
|
getDiscriminatorLogicalName(boundType, declaration, checker),
|
|
2152
2186
|
declaration,
|
|
2187
|
+
checker,
|
|
2188
|
+
void 0,
|
|
2153
2189
|
{
|
|
2154
2190
|
checker,
|
|
2155
2191
|
declaration,
|
|
@@ -2386,12 +2422,20 @@ function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnosti
|
|
|
2386
2422
|
annotations.push(defaultAnnotation);
|
|
2387
2423
|
}
|
|
2388
2424
|
({ type, annotations } = applyEnumMemberDisplayNames(type, annotations));
|
|
2389
|
-
const metadata = resolveNodeMetadata(
|
|
2425
|
+
const metadata = resolveNodeMetadata(
|
|
2426
|
+
metadataPolicy,
|
|
2427
|
+
"field",
|
|
2428
|
+
name,
|
|
2429
|
+
prop,
|
|
2390
2430
|
checker,
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2431
|
+
extensionRegistry,
|
|
2432
|
+
{
|
|
2433
|
+
checker,
|
|
2434
|
+
declaration: prop,
|
|
2435
|
+
subjectType: tsType,
|
|
2436
|
+
hostType
|
|
2437
|
+
}
|
|
2438
|
+
);
|
|
2395
2439
|
return {
|
|
2396
2440
|
kind: "field",
|
|
2397
2441
|
name,
|
|
@@ -2438,12 +2482,20 @@ function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visitin
|
|
|
2438
2482
|
let annotations = [];
|
|
2439
2483
|
annotations.push(...docResult.annotations);
|
|
2440
2484
|
({ type, annotations } = applyEnumMemberDisplayNames(type, annotations));
|
|
2441
|
-
const metadata = resolveNodeMetadata(
|
|
2485
|
+
const metadata = resolveNodeMetadata(
|
|
2486
|
+
metadataPolicy,
|
|
2487
|
+
"field",
|
|
2488
|
+
name,
|
|
2489
|
+
prop,
|
|
2442
2490
|
checker,
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2491
|
+
extensionRegistry,
|
|
2492
|
+
{
|
|
2493
|
+
checker,
|
|
2494
|
+
declaration: prop,
|
|
2495
|
+
subjectType: tsType,
|
|
2496
|
+
hostType
|
|
2497
|
+
}
|
|
2498
|
+
);
|
|
2447
2499
|
return {
|
|
2448
2500
|
kind: "field",
|
|
2449
2501
|
name,
|
|
@@ -2572,7 +2624,7 @@ function getTypeNodeRegistrationName(typeNode) {
|
|
|
2572
2624
|
}
|
|
2573
2625
|
return null;
|
|
2574
2626
|
}
|
|
2575
|
-
function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
2627
|
+
function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
2576
2628
|
const customType = resolveRegisteredCustomType(sourceNode, extensionRegistry, checker);
|
|
2577
2629
|
if (customType) {
|
|
2578
2630
|
return customType;
|
|
@@ -2662,7 +2714,7 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
|
|
|
2662
2714
|
}
|
|
2663
2715
|
return { kind: "primitive", primitiveKind: "string" };
|
|
2664
2716
|
}
|
|
2665
|
-
function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
2717
|
+
function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
2666
2718
|
if (!(type.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null))) {
|
|
2667
2719
|
return null;
|
|
2668
2720
|
}
|
|
@@ -2682,11 +2734,19 @@ function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiti
|
|
|
2682
2734
|
file,
|
|
2683
2735
|
makeParseOptions(extensionRegistry)
|
|
2684
2736
|
);
|
|
2685
|
-
const metadata = resolveNodeMetadata(
|
|
2737
|
+
const metadata = resolveNodeMetadata(
|
|
2738
|
+
metadataPolicy,
|
|
2739
|
+
"type",
|
|
2740
|
+
aliasName,
|
|
2741
|
+
aliasDecl,
|
|
2686
2742
|
checker,
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2743
|
+
extensionRegistry,
|
|
2744
|
+
{
|
|
2745
|
+
checker,
|
|
2746
|
+
declaration: aliasDecl,
|
|
2747
|
+
subjectType: aliasType
|
|
2748
|
+
}
|
|
2749
|
+
);
|
|
2690
2750
|
typeRegistry[aliasName] = {
|
|
2691
2751
|
name: aliasName,
|
|
2692
2752
|
...metadata !== void 0 && { metadata },
|
|
@@ -2725,7 +2785,7 @@ function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
|
|
|
2725
2785
|
const resolved = checker.getTypeFromTypeNode(aliasDecl.type);
|
|
2726
2786
|
return !!(resolved.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null));
|
|
2727
2787
|
}
|
|
2728
|
-
function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy =
|
|
2788
|
+
function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
2729
2789
|
const nestedAliasDecl = type.aliasSymbol?.declarations?.find(ts3.isTypeAliasDeclaration);
|
|
2730
2790
|
if (nestedAliasDecl !== void 0) {
|
|
2731
2791
|
return resolveAliasedPrimitiveTarget(
|
|
@@ -2751,7 +2811,7 @@ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiti
|
|
|
2751
2811
|
diagnostics
|
|
2752
2812
|
);
|
|
2753
2813
|
}
|
|
2754
|
-
function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
2814
|
+
function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
2755
2815
|
const typeName = getNamedTypeName(type);
|
|
2756
2816
|
const namedDecl = getNamedTypeDeclaration(type);
|
|
2757
2817
|
if (typeName && typeName in typeRegistry) {
|
|
@@ -2786,11 +2846,19 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
2786
2846
|
return result;
|
|
2787
2847
|
}
|
|
2788
2848
|
const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
|
|
2789
|
-
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
2849
|
+
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
2850
|
+
metadataPolicy,
|
|
2851
|
+
"type",
|
|
2852
|
+
typeName,
|
|
2853
|
+
namedDecl,
|
|
2790
2854
|
checker,
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2855
|
+
extensionRegistry,
|
|
2856
|
+
{
|
|
2857
|
+
checker,
|
|
2858
|
+
declaration: namedDecl,
|
|
2859
|
+
subjectType: type
|
|
2860
|
+
}
|
|
2861
|
+
) : void 0;
|
|
2794
2862
|
typeRegistry[typeName] = {
|
|
2795
2863
|
name: typeName,
|
|
2796
2864
|
...metadata !== void 0 && { metadata },
|
|
@@ -2875,7 +2943,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
2875
2943
|
}
|
|
2876
2944
|
return registerNamed({ kind: "union", members });
|
|
2877
2945
|
}
|
|
2878
|
-
function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
2946
|
+
function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
2879
2947
|
const typeArgs = isTypeReference(type) ? type.typeArguments : void 0;
|
|
2880
2948
|
const elementType = typeArgs?.[0];
|
|
2881
2949
|
const elementSourceNode = extractArrayElementTypeNode(sourceNode, checker);
|
|
@@ -2892,7 +2960,7 @@ function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
2892
2960
|
) : { kind: "primitive", primitiveKind: "string" };
|
|
2893
2961
|
return { kind: "array", items };
|
|
2894
2962
|
}
|
|
2895
|
-
function tryResolveRecordType(type, checker, file, typeRegistry, visiting, metadataPolicy =
|
|
2963
|
+
function tryResolveRecordType(type, checker, file, typeRegistry, visiting, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
2896
2964
|
if (type.getProperties().length > 0) {
|
|
2897
2965
|
return null;
|
|
2898
2966
|
}
|
|
@@ -2953,7 +3021,7 @@ function shouldEmitResolvedObjectProperty(property, declaration) {
|
|
|
2953
3021
|
}
|
|
2954
3022
|
return true;
|
|
2955
3023
|
}
|
|
2956
|
-
function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
3024
|
+
function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
2957
3025
|
const collectedDiagnostics = diagnostics ?? [];
|
|
2958
3026
|
const typeName = getNamedTypeName(type);
|
|
2959
3027
|
const namedTypeName = typeName ?? void 0;
|
|
@@ -3029,11 +3097,19 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3029
3097
|
return recordNode;
|
|
3030
3098
|
}
|
|
3031
3099
|
const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
|
|
3032
|
-
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
3100
|
+
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
3101
|
+
metadataPolicy,
|
|
3102
|
+
"type",
|
|
3103
|
+
registryTypeName,
|
|
3104
|
+
namedDecl,
|
|
3033
3105
|
checker,
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3106
|
+
extensionRegistry,
|
|
3107
|
+
{
|
|
3108
|
+
checker,
|
|
3109
|
+
declaration: namedDecl,
|
|
3110
|
+
subjectType: type
|
|
3111
|
+
}
|
|
3112
|
+
) : void 0;
|
|
3037
3113
|
typeRegistry[registryTypeName] = {
|
|
3038
3114
|
name: registryTypeName,
|
|
3039
3115
|
...metadata !== void 0 && { metadata },
|
|
@@ -3078,14 +3154,39 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3078
3154
|
collectedDiagnostics
|
|
3079
3155
|
);
|
|
3080
3156
|
const fieldNodeInfo = fieldInfoMap?.get(prop.name);
|
|
3157
|
+
const inlineFieldNodeInfo = fieldNodeInfo === void 0 ? ts3.isPropertySignature(declaration) ? analyzeInterfacePropertyToIR(
|
|
3158
|
+
declaration,
|
|
3159
|
+
checker,
|
|
3160
|
+
file,
|
|
3161
|
+
typeRegistry,
|
|
3162
|
+
visiting,
|
|
3163
|
+
collectedDiagnostics,
|
|
3164
|
+
type,
|
|
3165
|
+
metadataPolicy,
|
|
3166
|
+
extensionRegistry
|
|
3167
|
+
) : ts3.isPropertyDeclaration(declaration) ? analyzeFieldToIR(
|
|
3168
|
+
declaration,
|
|
3169
|
+
checker,
|
|
3170
|
+
file,
|
|
3171
|
+
typeRegistry,
|
|
3172
|
+
visiting,
|
|
3173
|
+
collectedDiagnostics,
|
|
3174
|
+
type,
|
|
3175
|
+
metadataPolicy,
|
|
3176
|
+
extensionRegistry
|
|
3177
|
+
) : null : null;
|
|
3178
|
+
const resolvedFieldNodeInfo = fieldNodeInfo ?? inlineFieldNodeInfo;
|
|
3179
|
+
const resolvedPropertyType = inlineFieldNodeInfo?.type ?? propTypeNode;
|
|
3081
3180
|
properties.push({
|
|
3082
3181
|
name: prop.name,
|
|
3083
|
-
...
|
|
3084
|
-
|
|
3182
|
+
...resolvedFieldNodeInfo?.metadata !== void 0 && {
|
|
3183
|
+
metadata: resolvedFieldNodeInfo.metadata
|
|
3184
|
+
},
|
|
3185
|
+
type: resolvedPropertyType,
|
|
3085
3186
|
optional,
|
|
3086
|
-
constraints:
|
|
3087
|
-
annotations:
|
|
3088
|
-
provenance:
|
|
3187
|
+
constraints: resolvedFieldNodeInfo?.constraints ?? [],
|
|
3188
|
+
annotations: resolvedFieldNodeInfo?.annotations ?? [],
|
|
3189
|
+
provenance: resolvedFieldNodeInfo?.provenance ?? provenanceForFile(file)
|
|
3089
3190
|
});
|
|
3090
3191
|
}
|
|
3091
3192
|
visiting.delete(type);
|
|
@@ -3104,11 +3205,19 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3104
3205
|
};
|
|
3105
3206
|
if (registryTypeName !== void 0 && shouldRegisterNamedType) {
|
|
3106
3207
|
const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
|
|
3107
|
-
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
3208
|
+
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
3209
|
+
metadataPolicy,
|
|
3210
|
+
"type",
|
|
3211
|
+
registryTypeName,
|
|
3212
|
+
namedDecl,
|
|
3108
3213
|
checker,
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3214
|
+
extensionRegistry,
|
|
3215
|
+
{
|
|
3216
|
+
checker,
|
|
3217
|
+
declaration: namedDecl,
|
|
3218
|
+
subjectType: type
|
|
3219
|
+
}
|
|
3220
|
+
) : void 0;
|
|
3112
3221
|
typeRegistry[registryTypeName] = {
|
|
3113
3222
|
name: registryTypeName,
|
|
3114
3223
|
...metadata !== void 0 && { metadata },
|
|
@@ -4613,13 +4722,35 @@ function formatLocation(location) {
|
|
|
4613
4722
|
}
|
|
4614
4723
|
|
|
4615
4724
|
// src/extensions/registry.ts
|
|
4725
|
+
import {
|
|
4726
|
+
BUILTIN_CONSTRAINT_DEFINITIONS as BUILTIN_CONSTRAINT_DEFINITIONS2,
|
|
4727
|
+
normalizeConstraintTagName as normalizeConstraintTagName2
|
|
4728
|
+
} from "@formspec/core/internals";
|
|
4729
|
+
import {
|
|
4730
|
+
getTagDefinition as getTagDefinition2,
|
|
4731
|
+
normalizeFormSpecTagName as normalizeFormSpecTagName2
|
|
4732
|
+
} from "@formspec/analysis/internal";
|
|
4733
|
+
var BUILTIN_METADATA_TAGS = /* @__PURE__ */ new Set(["apiName", "displayName"]);
|
|
4734
|
+
function buildConstraintTagSources(extensions) {
|
|
4735
|
+
return extensions.map((extension) => ({
|
|
4736
|
+
extensionId: extension.extensionId,
|
|
4737
|
+
...extension.constraintTags !== void 0 ? {
|
|
4738
|
+
constraintTags: extension.constraintTags.map((tag) => ({
|
|
4739
|
+
tagName: normalizeFormSpecTagName2(tag.tagName)
|
|
4740
|
+
}))
|
|
4741
|
+
} : {}
|
|
4742
|
+
}));
|
|
4743
|
+
}
|
|
4616
4744
|
function createExtensionRegistry(extensions) {
|
|
4745
|
+
const reservedTagSources = buildConstraintTagSources(extensions);
|
|
4617
4746
|
const typeMap = /* @__PURE__ */ new Map();
|
|
4618
4747
|
const typeNameMap = /* @__PURE__ */ new Map();
|
|
4619
4748
|
const constraintMap = /* @__PURE__ */ new Map();
|
|
4620
4749
|
const constraintTagMap = /* @__PURE__ */ new Map();
|
|
4621
4750
|
const builtinBroadeningMap = /* @__PURE__ */ new Map();
|
|
4622
4751
|
const annotationMap = /* @__PURE__ */ new Map();
|
|
4752
|
+
const metadataSlotMap = /* @__PURE__ */ new Map();
|
|
4753
|
+
const metadataTagMap = /* @__PURE__ */ new Map();
|
|
4623
4754
|
for (const ext of extensions) {
|
|
4624
4755
|
if (ext.types !== void 0) {
|
|
4625
4756
|
for (const type of ext.types) {
|
|
@@ -4662,10 +4793,11 @@ function createExtensionRegistry(extensions) {
|
|
|
4662
4793
|
}
|
|
4663
4794
|
if (ext.constraintTags !== void 0) {
|
|
4664
4795
|
for (const tag of ext.constraintTags) {
|
|
4665
|
-
|
|
4666
|
-
|
|
4796
|
+
const canonicalTagName = normalizeFormSpecTagName2(tag.tagName);
|
|
4797
|
+
if (constraintTagMap.has(canonicalTagName)) {
|
|
4798
|
+
throw new Error(`Duplicate custom constraint tag: "@${canonicalTagName}"`);
|
|
4667
4799
|
}
|
|
4668
|
-
constraintTagMap.set(
|
|
4800
|
+
constraintTagMap.set(canonicalTagName, {
|
|
4669
4801
|
extensionId: ext.extensionId,
|
|
4670
4802
|
registration: tag
|
|
4671
4803
|
});
|
|
@@ -4680,13 +4812,54 @@ function createExtensionRegistry(extensions) {
|
|
|
4680
4812
|
annotationMap.set(qualifiedId, annotation);
|
|
4681
4813
|
}
|
|
4682
4814
|
}
|
|
4815
|
+
if (ext.metadataSlots !== void 0) {
|
|
4816
|
+
for (const slot of ext.metadataSlots) {
|
|
4817
|
+
if (metadataSlotMap.has(slot.slotId)) {
|
|
4818
|
+
throw new Error(`Duplicate metadata slot ID: "${slot.slotId}"`);
|
|
4819
|
+
}
|
|
4820
|
+
metadataSlotMap.set(slot.slotId, true);
|
|
4821
|
+
const canonicalTagName = normalizeFormSpecTagName2(slot.tagName);
|
|
4822
|
+
if (slot.allowBare === false && (slot.qualifiers?.length ?? 0) === 0) {
|
|
4823
|
+
throw new Error(
|
|
4824
|
+
`Metadata tag "@${canonicalTagName}" must allow bare usage or declare at least one qualifier.`
|
|
4825
|
+
);
|
|
4826
|
+
}
|
|
4827
|
+
if (metadataTagMap.has(canonicalTagName)) {
|
|
4828
|
+
throw new Error(`Duplicate metadata tag: "@${canonicalTagName}"`);
|
|
4829
|
+
}
|
|
4830
|
+
if (BUILTIN_METADATA_TAGS.has(canonicalTagName)) {
|
|
4831
|
+
throw new Error(
|
|
4832
|
+
`Metadata tag "@${canonicalTagName}" conflicts with built-in metadata tags.`
|
|
4833
|
+
);
|
|
4834
|
+
}
|
|
4835
|
+
if (constraintTagMap.has(canonicalTagName)) {
|
|
4836
|
+
throw new Error(
|
|
4837
|
+
`Metadata tag "@${canonicalTagName}" conflicts with existing FormSpec tag "@${canonicalTagName}".`
|
|
4838
|
+
);
|
|
4839
|
+
}
|
|
4840
|
+
if (Object.hasOwn(BUILTIN_CONSTRAINT_DEFINITIONS2, normalizeConstraintTagName2(canonicalTagName))) {
|
|
4841
|
+
throw new Error(
|
|
4842
|
+
`Metadata tag "@${canonicalTagName}" conflicts with existing FormSpec tag "@${normalizeConstraintTagName2(canonicalTagName)}".`
|
|
4843
|
+
);
|
|
4844
|
+
}
|
|
4845
|
+
const existingTag = getTagDefinition2(canonicalTagName, reservedTagSources);
|
|
4846
|
+
if (existingTag !== null) {
|
|
4847
|
+
throw BUILTIN_METADATA_TAGS.has(existingTag.canonicalName) ? new Error(
|
|
4848
|
+
`Metadata tag "@${canonicalTagName}" conflicts with built-in metadata tags.`
|
|
4849
|
+
) : new Error(
|
|
4850
|
+
`Metadata tag "@${canonicalTagName}" conflicts with existing FormSpec tag "@${existingTag.canonicalName}".`
|
|
4851
|
+
);
|
|
4852
|
+
}
|
|
4853
|
+
metadataTagMap.set(canonicalTagName, true);
|
|
4854
|
+
}
|
|
4855
|
+
}
|
|
4683
4856
|
}
|
|
4684
4857
|
return {
|
|
4685
4858
|
extensions,
|
|
4686
4859
|
findType: (typeId) => typeMap.get(typeId),
|
|
4687
4860
|
findTypeByName: (typeName) => typeNameMap.get(typeName),
|
|
4688
4861
|
findConstraint: (constraintId) => constraintMap.get(constraintId),
|
|
4689
|
-
findConstraintTag: (tagName) => constraintTagMap.get(tagName),
|
|
4862
|
+
findConstraintTag: (tagName) => constraintTagMap.get(normalizeFormSpecTagName2(tagName)),
|
|
4690
4863
|
findBuiltinConstraintBroadening: (typeId, tagName) => builtinBroadeningMap.get(`${typeId}:${tagName}`),
|
|
4691
4864
|
findAnnotation: (annotationId) => annotationMap.get(annotationId)
|
|
4692
4865
|
};
|