@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.cjs
CHANGED
|
@@ -805,7 +805,7 @@ function createFormSpecTSDocConfig(extensionTagNames = []) {
|
|
|
805
805
|
})
|
|
806
806
|
);
|
|
807
807
|
}
|
|
808
|
-
for (const tagName of ["displayName", "format", "placeholder"]) {
|
|
808
|
+
for (const tagName of ["apiName", "displayName", "format", "placeholder"]) {
|
|
809
809
|
config.addTagDefinition(
|
|
810
810
|
new import_tsdoc.TSDocTagDefinition({
|
|
811
811
|
tagName: "@" + tagName,
|
|
@@ -839,6 +839,16 @@ function sharedTagValueOptions(options) {
|
|
|
839
839
|
};
|
|
840
840
|
}
|
|
841
841
|
var SYNTHETIC_TYPE_FORMAT_FLAGS = ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
|
|
842
|
+
function getExtensionTypeNames(registry) {
|
|
843
|
+
if (registry === void 0) {
|
|
844
|
+
return /* @__PURE__ */ new Set();
|
|
845
|
+
}
|
|
846
|
+
return new Set(
|
|
847
|
+
registry.extensions.flatMap(
|
|
848
|
+
(ext) => (ext.types ?? []).flatMap((t) => t.tsTypeNames ?? [t.typeName])
|
|
849
|
+
)
|
|
850
|
+
);
|
|
851
|
+
}
|
|
842
852
|
function collectImportedNames(sourceFile) {
|
|
843
853
|
const importedNames = /* @__PURE__ */ new Set();
|
|
844
854
|
for (const statement of sourceFile.statements) {
|
|
@@ -878,6 +888,9 @@ function isNonReferenceIdentifier(node) {
|
|
|
878
888
|
return false;
|
|
879
889
|
}
|
|
880
890
|
function statementReferencesImportedName(statement, importedNames) {
|
|
891
|
+
if (importedNames.size === 0) {
|
|
892
|
+
return false;
|
|
893
|
+
}
|
|
881
894
|
let referencesImportedName = false;
|
|
882
895
|
const visit = (node) => {
|
|
883
896
|
if (referencesImportedName) {
|
|
@@ -892,14 +905,17 @@ function statementReferencesImportedName(statement, importedNames) {
|
|
|
892
905
|
visit(statement);
|
|
893
906
|
return referencesImportedName;
|
|
894
907
|
}
|
|
895
|
-
function buildSupportingDeclarations(sourceFile) {
|
|
908
|
+
function buildSupportingDeclarations(sourceFile, extensionTypeNames) {
|
|
896
909
|
const importedNames = collectImportedNames(sourceFile);
|
|
910
|
+
const importedNamesToSkip = new Set(
|
|
911
|
+
[...importedNames].filter((name) => !extensionTypeNames.has(name))
|
|
912
|
+
);
|
|
897
913
|
return sourceFile.statements.filter((statement) => {
|
|
898
914
|
if (ts.isImportDeclaration(statement)) return false;
|
|
899
915
|
if (ts.isImportEqualsDeclaration(statement)) return false;
|
|
900
916
|
if (ts.isExportDeclaration(statement) && statement.moduleSpecifier !== void 0)
|
|
901
917
|
return false;
|
|
902
|
-
if (
|
|
918
|
+
if (statementReferencesImportedName(statement, importedNamesToSkip)) {
|
|
903
919
|
return false;
|
|
904
920
|
}
|
|
905
921
|
return true;
|
|
@@ -1156,6 +1172,14 @@ function buildCompilerBackedConstraintDiagnostics(node, sourceFile, tagName, par
|
|
|
1156
1172
|
extensionId: extension.extensionId,
|
|
1157
1173
|
...extension.constraintTags !== void 0 ? {
|
|
1158
1174
|
constraintTags: extension.constraintTags.map((tag) => ({ tagName: tag.tagName }))
|
|
1175
|
+
} : {},
|
|
1176
|
+
...extension.metadataSlots !== void 0 ? {
|
|
1177
|
+
metadataSlots: extension.metadataSlots
|
|
1178
|
+
} : {},
|
|
1179
|
+
...extension.types !== void 0 ? {
|
|
1180
|
+
customTypes: extension.types.map((t) => ({
|
|
1181
|
+
tsTypeNames: t.tsTypeNames ?? [t.typeName]
|
|
1182
|
+
}))
|
|
1159
1183
|
} : {}
|
|
1160
1184
|
}))
|
|
1161
1185
|
} : {}
|
|
@@ -1177,7 +1201,10 @@ var parseResultCache = /* @__PURE__ */ new Map();
|
|
|
1177
1201
|
function getParser(options) {
|
|
1178
1202
|
const extensionTagNames = [
|
|
1179
1203
|
...options?.extensionRegistry?.extensions.flatMap(
|
|
1180
|
-
(extension) => (extension.constraintTags ?? []).map((tag) => tag.tagName)
|
|
1204
|
+
(extension) => (extension.constraintTags ?? []).map((tag) => (0, import_internal.normalizeFormSpecTagName)(tag.tagName))
|
|
1205
|
+
) ?? [],
|
|
1206
|
+
...options?.extensionRegistry?.extensions.flatMap(
|
|
1207
|
+
(extension) => (extension.metadataSlots ?? []).map((slot) => (0, import_internal.normalizeFormSpecTagName)(slot.tagName))
|
|
1181
1208
|
) ?? []
|
|
1182
1209
|
].sort();
|
|
1183
1210
|
const cacheKey = extensionTagNames.join("|");
|
|
@@ -1197,7 +1224,16 @@ function getExtensionRegistryCacheKey(registry) {
|
|
|
1197
1224
|
(extension) => JSON.stringify({
|
|
1198
1225
|
extensionId: extension.extensionId,
|
|
1199
1226
|
typeNames: extension.types?.map((type) => type.typeName) ?? [],
|
|
1200
|
-
constraintTags: extension.constraintTags?.map((tag) => tag.tagName) ?? []
|
|
1227
|
+
constraintTags: extension.constraintTags?.map((tag) => (0, import_internal.normalizeFormSpecTagName)(tag.tagName)) ?? [],
|
|
1228
|
+
metadataSlots: extension.metadataSlots?.map((slot) => ({
|
|
1229
|
+
tagName: (0, import_internal.normalizeFormSpecTagName)(slot.tagName),
|
|
1230
|
+
declarationKinds: [...slot.declarationKinds].sort(),
|
|
1231
|
+
allowBare: slot.allowBare !== false,
|
|
1232
|
+
qualifiers: (slot.qualifiers ?? []).map((qualifier) => ({
|
|
1233
|
+
qualifier: qualifier.qualifier,
|
|
1234
|
+
...qualifier.sourceQualifier !== void 0 ? { sourceQualifier: qualifier.sourceQualifier } : {}
|
|
1235
|
+
})).sort((left, right) => left.qualifier.localeCompare(right.qualifier))
|
|
1236
|
+
})) ?? []
|
|
1201
1237
|
})
|
|
1202
1238
|
).join("|");
|
|
1203
1239
|
}
|
|
@@ -1232,7 +1268,8 @@ function parseTSDocTags(node, file = "", options) {
|
|
|
1232
1268
|
const rawTextTags = [];
|
|
1233
1269
|
const sourceFile = node.getSourceFile();
|
|
1234
1270
|
const sourceText = sourceFile.getFullText();
|
|
1235
|
-
const
|
|
1271
|
+
const extensionTypeNames = getExtensionTypeNames(options?.extensionRegistry);
|
|
1272
|
+
const supportingDeclarations = buildSupportingDeclarations(sourceFile, extensionTypeNames);
|
|
1236
1273
|
const commentRanges = ts.getLeadingCommentRanges(sourceText, node.getFullStart());
|
|
1237
1274
|
const rawTextFallbacks = collectRawTextFallbacks(node, file);
|
|
1238
1275
|
if (commentRanges) {
|
|
@@ -1660,76 +1697,50 @@ function makeParseOptions(extensionRegistry, fieldType, checker, subjectType, ho
|
|
|
1660
1697
|
...hostType !== void 0 && { hostType }
|
|
1661
1698
|
};
|
|
1662
1699
|
}
|
|
1663
|
-
function
|
|
1664
|
-
return
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
let apiName;
|
|
1668
|
-
let displayName;
|
|
1669
|
-
let apiNamePlural;
|
|
1670
|
-
let displayNamePlural;
|
|
1671
|
-
for (const tag of getLeadingParsedTags(node)) {
|
|
1672
|
-
const value = tag.argumentText.trim();
|
|
1673
|
-
if (value === "") {
|
|
1674
|
-
continue;
|
|
1675
|
-
}
|
|
1676
|
-
if (tag.normalizedTagName === "apiName") {
|
|
1677
|
-
if (tag.target === null) {
|
|
1678
|
-
apiName ??= value;
|
|
1679
|
-
} else if (tag.target.kind === "variant") {
|
|
1680
|
-
if (tag.target.rawText === "singular") {
|
|
1681
|
-
apiName ??= value;
|
|
1682
|
-
} else if (tag.target.rawText === "plural") {
|
|
1683
|
-
apiNamePlural ??= value;
|
|
1684
|
-
}
|
|
1685
|
-
}
|
|
1686
|
-
continue;
|
|
1687
|
-
}
|
|
1688
|
-
if (tag.normalizedTagName === "displayName") {
|
|
1689
|
-
if (tag.target === null) {
|
|
1690
|
-
displayName ??= value;
|
|
1691
|
-
} else if (tag.target.kind === "variant") {
|
|
1692
|
-
if (tag.target.rawText === "singular") {
|
|
1693
|
-
displayName ??= value;
|
|
1694
|
-
} else if (tag.target.rawText === "plural") {
|
|
1695
|
-
displayNamePlural ??= value;
|
|
1696
|
-
}
|
|
1697
|
-
}
|
|
1698
|
-
}
|
|
1699
|
-
}
|
|
1700
|
-
const resolvedApiName = makeExplicitScalarMetadata(apiName);
|
|
1701
|
-
const resolvedDisplayName = makeExplicitScalarMetadata(displayName);
|
|
1702
|
-
const resolvedApiNamePlural = makeExplicitScalarMetadata(apiNamePlural);
|
|
1703
|
-
const resolvedDisplayNamePlural = makeExplicitScalarMetadata(displayNamePlural);
|
|
1704
|
-
const metadata = {
|
|
1705
|
-
...resolvedApiName !== void 0 && { apiName: resolvedApiName },
|
|
1706
|
-
...resolvedDisplayName !== void 0 && { displayName: resolvedDisplayName },
|
|
1707
|
-
...resolvedApiNamePlural !== void 0 && { apiNamePlural: resolvedApiNamePlural },
|
|
1708
|
-
...resolvedDisplayNamePlural !== void 0 && {
|
|
1709
|
-
displayNamePlural: resolvedDisplayNamePlural
|
|
1710
|
-
}
|
|
1700
|
+
function createAnalyzerMetadataPolicy(input) {
|
|
1701
|
+
return {
|
|
1702
|
+
raw: input,
|
|
1703
|
+
normalized: normalizeMetadataPolicy(input)
|
|
1711
1704
|
};
|
|
1712
|
-
return Object.keys(metadata).length === 0 ? void 0 : metadata;
|
|
1713
1705
|
}
|
|
1714
|
-
function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, buildContext) {
|
|
1715
|
-
const
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
getDeclarationMetadataPolicy(metadataPolicy, declarationKind),
|
|
1728
|
-
makeMetadataContext("tsdoc", declarationKind, logicalName, buildContext)
|
|
1706
|
+
function resolveNodeMetadata(metadataPolicy, declarationKind, logicalName, node, checker, extensionRegistry, buildContext) {
|
|
1707
|
+
const analysis = (0, import_internal2.analyzeMetadataForNodeWithChecker)({
|
|
1708
|
+
checker,
|
|
1709
|
+
node,
|
|
1710
|
+
logicalName,
|
|
1711
|
+
metadata: metadataPolicy.raw,
|
|
1712
|
+
extensions: extensionRegistry?.extensions,
|
|
1713
|
+
...buildContext !== void 0 && { buildContext }
|
|
1714
|
+
});
|
|
1715
|
+
const resolvedMetadata = analysis?.resolvedMetadata;
|
|
1716
|
+
const declarationPolicy = getDeclarationMetadataPolicy(
|
|
1717
|
+
metadataPolicy.normalized,
|
|
1718
|
+
declarationKind
|
|
1729
1719
|
);
|
|
1720
|
+
if (resolvedMetadata?.apiName === void 0 && declarationPolicy.apiName.mode === "require-explicit") {
|
|
1721
|
+
throw new Error(
|
|
1722
|
+
`Metadata policy requires explicit apiName for ${declarationKind} "${logicalName}" on the tsdoc surface.`
|
|
1723
|
+
);
|
|
1724
|
+
}
|
|
1725
|
+
if (resolvedMetadata?.displayName === void 0 && declarationPolicy.displayName.mode === "require-explicit") {
|
|
1726
|
+
throw new Error(
|
|
1727
|
+
`Metadata policy requires explicit displayName for ${declarationKind} "${logicalName}" on the tsdoc surface.`
|
|
1728
|
+
);
|
|
1729
|
+
}
|
|
1730
|
+
if (resolvedMetadata?.apiNamePlural === void 0 && declarationPolicy.apiName.pluralization.mode === "require-explicit") {
|
|
1731
|
+
throw new Error(
|
|
1732
|
+
`Metadata policy requires explicit apiNamePlural for ${declarationKind} "${logicalName}" on the tsdoc surface.`
|
|
1733
|
+
);
|
|
1734
|
+
}
|
|
1735
|
+
if (resolvedMetadata?.displayNamePlural === void 0 && declarationPolicy.displayName.pluralization.mode === "require-explicit") {
|
|
1736
|
+
throw new Error(
|
|
1737
|
+
`Metadata policy requires explicit displayNamePlural for ${declarationKind} "${logicalName}" on the tsdoc surface.`
|
|
1738
|
+
);
|
|
1739
|
+
}
|
|
1740
|
+
return resolvedMetadata;
|
|
1730
1741
|
}
|
|
1731
1742
|
function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
1732
|
-
const normalizedMetadataPolicy =
|
|
1743
|
+
const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
|
|
1733
1744
|
const name = classDecl.name?.text ?? "AnonymousClass";
|
|
1734
1745
|
const fields = [];
|
|
1735
1746
|
const fieldLayouts = [];
|
|
@@ -1784,12 +1795,20 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
|
|
|
1784
1795
|
diagnostics,
|
|
1785
1796
|
normalizedMetadataPolicy
|
|
1786
1797
|
);
|
|
1787
|
-
const metadata = resolveNodeMetadata(
|
|
1798
|
+
const metadata = resolveNodeMetadata(
|
|
1799
|
+
normalizedMetadataPolicy,
|
|
1800
|
+
"type",
|
|
1801
|
+
name,
|
|
1802
|
+
classDecl,
|
|
1788
1803
|
checker,
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1804
|
+
extensionRegistry,
|
|
1805
|
+
{
|
|
1806
|
+
checker,
|
|
1807
|
+
declaration: classDecl,
|
|
1808
|
+
subjectType: classType,
|
|
1809
|
+
hostType: classType
|
|
1810
|
+
}
|
|
1811
|
+
);
|
|
1793
1812
|
return {
|
|
1794
1813
|
name,
|
|
1795
1814
|
...metadata !== void 0 && { metadata },
|
|
@@ -1803,7 +1822,7 @@ function analyzeClassToIR(classDecl, checker, file = "", extensionRegistry, meta
|
|
|
1803
1822
|
};
|
|
1804
1823
|
}
|
|
1805
1824
|
function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegistry, metadataPolicy) {
|
|
1806
|
-
const normalizedMetadataPolicy =
|
|
1825
|
+
const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
|
|
1807
1826
|
const name = interfaceDecl.name.text;
|
|
1808
1827
|
const fields = [];
|
|
1809
1828
|
const typeRegistry = {};
|
|
@@ -1845,12 +1864,20 @@ function analyzeInterfaceToIR(interfaceDecl, checker, file = "", extensionRegist
|
|
|
1845
1864
|
normalizedMetadataPolicy
|
|
1846
1865
|
);
|
|
1847
1866
|
const fieldLayouts = specializedFields.map(() => ({}));
|
|
1848
|
-
const metadata = resolveNodeMetadata(
|
|
1867
|
+
const metadata = resolveNodeMetadata(
|
|
1868
|
+
normalizedMetadataPolicy,
|
|
1869
|
+
"type",
|
|
1870
|
+
name,
|
|
1871
|
+
interfaceDecl,
|
|
1849
1872
|
checker,
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1873
|
+
extensionRegistry,
|
|
1874
|
+
{
|
|
1875
|
+
checker,
|
|
1876
|
+
declaration: interfaceDecl,
|
|
1877
|
+
subjectType: interfaceType,
|
|
1878
|
+
hostType: interfaceType
|
|
1879
|
+
}
|
|
1880
|
+
);
|
|
1854
1881
|
return {
|
|
1855
1882
|
name,
|
|
1856
1883
|
...metadata !== void 0 && { metadata },
|
|
@@ -1874,7 +1901,7 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
|
|
|
1874
1901
|
};
|
|
1875
1902
|
}
|
|
1876
1903
|
const typeLiteral = typeAlias.type;
|
|
1877
|
-
const normalizedMetadataPolicy =
|
|
1904
|
+
const normalizedMetadataPolicy = createAnalyzerMetadataPolicy(metadataPolicy);
|
|
1878
1905
|
const name = typeAlias.name.text;
|
|
1879
1906
|
const fields = [];
|
|
1880
1907
|
const typeRegistry = {};
|
|
@@ -1915,12 +1942,20 @@ function analyzeTypeAliasToIR(typeAlias, checker, file = "", extensionRegistry,
|
|
|
1915
1942
|
diagnostics,
|
|
1916
1943
|
normalizedMetadataPolicy
|
|
1917
1944
|
);
|
|
1918
|
-
const metadata = resolveNodeMetadata(
|
|
1945
|
+
const metadata = resolveNodeMetadata(
|
|
1946
|
+
normalizedMetadataPolicy,
|
|
1947
|
+
"type",
|
|
1948
|
+
name,
|
|
1949
|
+
typeAlias,
|
|
1919
1950
|
checker,
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1951
|
+
extensionRegistry,
|
|
1952
|
+
{
|
|
1953
|
+
checker,
|
|
1954
|
+
declaration: typeAlias,
|
|
1955
|
+
subjectType: aliasType,
|
|
1956
|
+
hostType: aliasType
|
|
1957
|
+
}
|
|
1958
|
+
);
|
|
1924
1959
|
return {
|
|
1925
1960
|
ok: true,
|
|
1926
1961
|
analysis: {
|
|
@@ -2142,10 +2177,7 @@ function resolveLiteralDiscriminatorPropertyValue(boundType, fieldName, checker,
|
|
|
2142
2177
|
if (resolvedAnchorNode === null) {
|
|
2143
2178
|
return void 0;
|
|
2144
2179
|
}
|
|
2145
|
-
const propertyType = checker.getTypeOfSymbolAtLocation(
|
|
2146
|
-
propertySymbol,
|
|
2147
|
-
resolvedAnchorNode
|
|
2148
|
-
);
|
|
2180
|
+
const propertyType = checker.getTypeOfSymbolAtLocation(propertySymbol, resolvedAnchorNode);
|
|
2149
2181
|
if (propertyType.isStringLiteral()) {
|
|
2150
2182
|
return propertyType.value;
|
|
2151
2183
|
}
|
|
@@ -2176,6 +2208,8 @@ function resolveDiscriminatorApiName(boundType, checker, metadataPolicy) {
|
|
|
2176
2208
|
"type",
|
|
2177
2209
|
getDiscriminatorLogicalName(boundType, declaration, checker),
|
|
2178
2210
|
declaration,
|
|
2211
|
+
checker,
|
|
2212
|
+
void 0,
|
|
2179
2213
|
{
|
|
2180
2214
|
checker,
|
|
2181
2215
|
declaration,
|
|
@@ -2412,12 +2446,20 @@ function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnosti
|
|
|
2412
2446
|
annotations.push(defaultAnnotation);
|
|
2413
2447
|
}
|
|
2414
2448
|
({ type, annotations } = applyEnumMemberDisplayNames(type, annotations));
|
|
2415
|
-
const metadata = resolveNodeMetadata(
|
|
2449
|
+
const metadata = resolveNodeMetadata(
|
|
2450
|
+
metadataPolicy,
|
|
2451
|
+
"field",
|
|
2452
|
+
name,
|
|
2453
|
+
prop,
|
|
2416
2454
|
checker,
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2455
|
+
extensionRegistry,
|
|
2456
|
+
{
|
|
2457
|
+
checker,
|
|
2458
|
+
declaration: prop,
|
|
2459
|
+
subjectType: tsType,
|
|
2460
|
+
hostType
|
|
2461
|
+
}
|
|
2462
|
+
);
|
|
2421
2463
|
return {
|
|
2422
2464
|
kind: "field",
|
|
2423
2465
|
name,
|
|
@@ -2464,12 +2506,20 @@ function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visitin
|
|
|
2464
2506
|
let annotations = [];
|
|
2465
2507
|
annotations.push(...docResult.annotations);
|
|
2466
2508
|
({ type, annotations } = applyEnumMemberDisplayNames(type, annotations));
|
|
2467
|
-
const metadata = resolveNodeMetadata(
|
|
2509
|
+
const metadata = resolveNodeMetadata(
|
|
2510
|
+
metadataPolicy,
|
|
2511
|
+
"field",
|
|
2512
|
+
name,
|
|
2513
|
+
prop,
|
|
2468
2514
|
checker,
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2515
|
+
extensionRegistry,
|
|
2516
|
+
{
|
|
2517
|
+
checker,
|
|
2518
|
+
declaration: prop,
|
|
2519
|
+
subjectType: tsType,
|
|
2520
|
+
hostType
|
|
2521
|
+
}
|
|
2522
|
+
);
|
|
2473
2523
|
return {
|
|
2474
2524
|
kind: "field",
|
|
2475
2525
|
name,
|
|
@@ -2598,7 +2648,7 @@ function getTypeNodeRegistrationName(typeNode) {
|
|
|
2598
2648
|
}
|
|
2599
2649
|
return null;
|
|
2600
2650
|
}
|
|
2601
|
-
function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
2651
|
+
function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
2602
2652
|
const customType = resolveRegisteredCustomType(sourceNode, extensionRegistry, checker);
|
|
2603
2653
|
if (customType) {
|
|
2604
2654
|
return customType;
|
|
@@ -2688,7 +2738,7 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
|
|
|
2688
2738
|
}
|
|
2689
2739
|
return { kind: "primitive", primitiveKind: "string" };
|
|
2690
2740
|
}
|
|
2691
|
-
function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
2741
|
+
function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
2692
2742
|
if (!(type.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null))) {
|
|
2693
2743
|
return null;
|
|
2694
2744
|
}
|
|
@@ -2708,11 +2758,19 @@ function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiti
|
|
|
2708
2758
|
file,
|
|
2709
2759
|
makeParseOptions(extensionRegistry)
|
|
2710
2760
|
);
|
|
2711
|
-
const metadata = resolveNodeMetadata(
|
|
2761
|
+
const metadata = resolveNodeMetadata(
|
|
2762
|
+
metadataPolicy,
|
|
2763
|
+
"type",
|
|
2764
|
+
aliasName,
|
|
2765
|
+
aliasDecl,
|
|
2712
2766
|
checker,
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2767
|
+
extensionRegistry,
|
|
2768
|
+
{
|
|
2769
|
+
checker,
|
|
2770
|
+
declaration: aliasDecl,
|
|
2771
|
+
subjectType: aliasType
|
|
2772
|
+
}
|
|
2773
|
+
);
|
|
2716
2774
|
typeRegistry[aliasName] = {
|
|
2717
2775
|
name: aliasName,
|
|
2718
2776
|
...metadata !== void 0 && { metadata },
|
|
@@ -2751,7 +2809,7 @@ function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
|
|
|
2751
2809
|
const resolved = checker.getTypeFromTypeNode(aliasDecl.type);
|
|
2752
2810
|
return !!(resolved.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null));
|
|
2753
2811
|
}
|
|
2754
|
-
function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy =
|
|
2812
|
+
function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
2755
2813
|
const nestedAliasDecl = type.aliasSymbol?.declarations?.find(ts3.isTypeAliasDeclaration);
|
|
2756
2814
|
if (nestedAliasDecl !== void 0) {
|
|
2757
2815
|
return resolveAliasedPrimitiveTarget(
|
|
@@ -2777,7 +2835,7 @@ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiti
|
|
|
2777
2835
|
diagnostics
|
|
2778
2836
|
);
|
|
2779
2837
|
}
|
|
2780
|
-
function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
2838
|
+
function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
2781
2839
|
const typeName = getNamedTypeName(type);
|
|
2782
2840
|
const namedDecl = getNamedTypeDeclaration(type);
|
|
2783
2841
|
if (typeName && typeName in typeRegistry) {
|
|
@@ -2812,11 +2870,19 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
2812
2870
|
return result;
|
|
2813
2871
|
}
|
|
2814
2872
|
const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
|
|
2815
|
-
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
2873
|
+
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
2874
|
+
metadataPolicy,
|
|
2875
|
+
"type",
|
|
2876
|
+
typeName,
|
|
2877
|
+
namedDecl,
|
|
2816
2878
|
checker,
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2879
|
+
extensionRegistry,
|
|
2880
|
+
{
|
|
2881
|
+
checker,
|
|
2882
|
+
declaration: namedDecl,
|
|
2883
|
+
subjectType: type
|
|
2884
|
+
}
|
|
2885
|
+
) : void 0;
|
|
2820
2886
|
typeRegistry[typeName] = {
|
|
2821
2887
|
name: typeName,
|
|
2822
2888
|
...metadata !== void 0 && { metadata },
|
|
@@ -2901,7 +2967,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
2901
2967
|
}
|
|
2902
2968
|
return registerNamed({ kind: "union", members });
|
|
2903
2969
|
}
|
|
2904
|
-
function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
2970
|
+
function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
2905
2971
|
const typeArgs = isTypeReference(type) ? type.typeArguments : void 0;
|
|
2906
2972
|
const elementType = typeArgs?.[0];
|
|
2907
2973
|
const elementSourceNode = extractArrayElementTypeNode(sourceNode, checker);
|
|
@@ -2918,7 +2984,7 @@ function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
2918
2984
|
) : { kind: "primitive", primitiveKind: "string" };
|
|
2919
2985
|
return { kind: "array", items };
|
|
2920
2986
|
}
|
|
2921
|
-
function tryResolveRecordType(type, checker, file, typeRegistry, visiting, metadataPolicy =
|
|
2987
|
+
function tryResolveRecordType(type, checker, file, typeRegistry, visiting, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
2922
2988
|
if (type.getProperties().length > 0) {
|
|
2923
2989
|
return null;
|
|
2924
2990
|
}
|
|
@@ -2979,7 +3045,7 @@ function shouldEmitResolvedObjectProperty(property, declaration) {
|
|
|
2979
3045
|
}
|
|
2980
3046
|
return true;
|
|
2981
3047
|
}
|
|
2982
|
-
function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
3048
|
+
function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
2983
3049
|
const collectedDiagnostics = diagnostics ?? [];
|
|
2984
3050
|
const typeName = getNamedTypeName(type);
|
|
2985
3051
|
const namedTypeName = typeName ?? void 0;
|
|
@@ -3055,11 +3121,19 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3055
3121
|
return recordNode;
|
|
3056
3122
|
}
|
|
3057
3123
|
const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
|
|
3058
|
-
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
3124
|
+
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
3125
|
+
metadataPolicy,
|
|
3126
|
+
"type",
|
|
3127
|
+
registryTypeName,
|
|
3128
|
+
namedDecl,
|
|
3059
3129
|
checker,
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3130
|
+
extensionRegistry,
|
|
3131
|
+
{
|
|
3132
|
+
checker,
|
|
3133
|
+
declaration: namedDecl,
|
|
3134
|
+
subjectType: type
|
|
3135
|
+
}
|
|
3136
|
+
) : void 0;
|
|
3063
3137
|
typeRegistry[registryTypeName] = {
|
|
3064
3138
|
name: registryTypeName,
|
|
3065
3139
|
...metadata !== void 0 && { metadata },
|
|
@@ -3104,14 +3178,39 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3104
3178
|
collectedDiagnostics
|
|
3105
3179
|
);
|
|
3106
3180
|
const fieldNodeInfo = fieldInfoMap?.get(prop.name);
|
|
3181
|
+
const inlineFieldNodeInfo = fieldNodeInfo === void 0 ? ts3.isPropertySignature(declaration) ? analyzeInterfacePropertyToIR(
|
|
3182
|
+
declaration,
|
|
3183
|
+
checker,
|
|
3184
|
+
file,
|
|
3185
|
+
typeRegistry,
|
|
3186
|
+
visiting,
|
|
3187
|
+
collectedDiagnostics,
|
|
3188
|
+
type,
|
|
3189
|
+
metadataPolicy,
|
|
3190
|
+
extensionRegistry
|
|
3191
|
+
) : ts3.isPropertyDeclaration(declaration) ? analyzeFieldToIR(
|
|
3192
|
+
declaration,
|
|
3193
|
+
checker,
|
|
3194
|
+
file,
|
|
3195
|
+
typeRegistry,
|
|
3196
|
+
visiting,
|
|
3197
|
+
collectedDiagnostics,
|
|
3198
|
+
type,
|
|
3199
|
+
metadataPolicy,
|
|
3200
|
+
extensionRegistry
|
|
3201
|
+
) : null : null;
|
|
3202
|
+
const resolvedFieldNodeInfo = fieldNodeInfo ?? inlineFieldNodeInfo;
|
|
3203
|
+
const resolvedPropertyType = inlineFieldNodeInfo?.type ?? propTypeNode;
|
|
3107
3204
|
properties.push({
|
|
3108
3205
|
name: prop.name,
|
|
3109
|
-
...
|
|
3110
|
-
|
|
3206
|
+
...resolvedFieldNodeInfo?.metadata !== void 0 && {
|
|
3207
|
+
metadata: resolvedFieldNodeInfo.metadata
|
|
3208
|
+
},
|
|
3209
|
+
type: resolvedPropertyType,
|
|
3111
3210
|
optional,
|
|
3112
|
-
constraints:
|
|
3113
|
-
annotations:
|
|
3114
|
-
provenance:
|
|
3211
|
+
constraints: resolvedFieldNodeInfo?.constraints ?? [],
|
|
3212
|
+
annotations: resolvedFieldNodeInfo?.annotations ?? [],
|
|
3213
|
+
provenance: resolvedFieldNodeInfo?.provenance ?? provenanceForFile(file)
|
|
3115
3214
|
});
|
|
3116
3215
|
}
|
|
3117
3216
|
visiting.delete(type);
|
|
@@ -3130,11 +3229,19 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3130
3229
|
};
|
|
3131
3230
|
if (registryTypeName !== void 0 && shouldRegisterNamedType) {
|
|
3132
3231
|
const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
|
|
3133
|
-
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
3232
|
+
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
3233
|
+
metadataPolicy,
|
|
3234
|
+
"type",
|
|
3235
|
+
registryTypeName,
|
|
3236
|
+
namedDecl,
|
|
3134
3237
|
checker,
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3238
|
+
extensionRegistry,
|
|
3239
|
+
{
|
|
3240
|
+
checker,
|
|
3241
|
+
declaration: namedDecl,
|
|
3242
|
+
subjectType: type
|
|
3243
|
+
}
|
|
3244
|
+
) : void 0;
|
|
3138
3245
|
typeRegistry[registryTypeName] = {
|
|
3139
3246
|
name: registryTypeName,
|
|
3140
3247
|
...metadata !== void 0 && { metadata },
|
|
@@ -4637,13 +4744,29 @@ function formatLocation(location) {
|
|
|
4637
4744
|
}
|
|
4638
4745
|
|
|
4639
4746
|
// src/extensions/registry.ts
|
|
4747
|
+
var import_internals5 = require("@formspec/core/internals");
|
|
4748
|
+
var import_internal4 = require("@formspec/analysis/internal");
|
|
4749
|
+
var BUILTIN_METADATA_TAGS = /* @__PURE__ */ new Set(["apiName", "displayName"]);
|
|
4750
|
+
function buildConstraintTagSources(extensions) {
|
|
4751
|
+
return extensions.map((extension) => ({
|
|
4752
|
+
extensionId: extension.extensionId,
|
|
4753
|
+
...extension.constraintTags !== void 0 ? {
|
|
4754
|
+
constraintTags: extension.constraintTags.map((tag) => ({
|
|
4755
|
+
tagName: (0, import_internal4.normalizeFormSpecTagName)(tag.tagName)
|
|
4756
|
+
}))
|
|
4757
|
+
} : {}
|
|
4758
|
+
}));
|
|
4759
|
+
}
|
|
4640
4760
|
function createExtensionRegistry(extensions) {
|
|
4761
|
+
const reservedTagSources = buildConstraintTagSources(extensions);
|
|
4641
4762
|
const typeMap = /* @__PURE__ */ new Map();
|
|
4642
4763
|
const typeNameMap = /* @__PURE__ */ new Map();
|
|
4643
4764
|
const constraintMap = /* @__PURE__ */ new Map();
|
|
4644
4765
|
const constraintTagMap = /* @__PURE__ */ new Map();
|
|
4645
4766
|
const builtinBroadeningMap = /* @__PURE__ */ new Map();
|
|
4646
4767
|
const annotationMap = /* @__PURE__ */ new Map();
|
|
4768
|
+
const metadataSlotMap = /* @__PURE__ */ new Map();
|
|
4769
|
+
const metadataTagMap = /* @__PURE__ */ new Map();
|
|
4647
4770
|
for (const ext of extensions) {
|
|
4648
4771
|
if (ext.types !== void 0) {
|
|
4649
4772
|
for (const type of ext.types) {
|
|
@@ -4686,10 +4809,11 @@ function createExtensionRegistry(extensions) {
|
|
|
4686
4809
|
}
|
|
4687
4810
|
if (ext.constraintTags !== void 0) {
|
|
4688
4811
|
for (const tag of ext.constraintTags) {
|
|
4689
|
-
|
|
4690
|
-
|
|
4812
|
+
const canonicalTagName = (0, import_internal4.normalizeFormSpecTagName)(tag.tagName);
|
|
4813
|
+
if (constraintTagMap.has(canonicalTagName)) {
|
|
4814
|
+
throw new Error(`Duplicate custom constraint tag: "@${canonicalTagName}"`);
|
|
4691
4815
|
}
|
|
4692
|
-
constraintTagMap.set(
|
|
4816
|
+
constraintTagMap.set(canonicalTagName, {
|
|
4693
4817
|
extensionId: ext.extensionId,
|
|
4694
4818
|
registration: tag
|
|
4695
4819
|
});
|
|
@@ -4704,20 +4828,61 @@ function createExtensionRegistry(extensions) {
|
|
|
4704
4828
|
annotationMap.set(qualifiedId, annotation);
|
|
4705
4829
|
}
|
|
4706
4830
|
}
|
|
4831
|
+
if (ext.metadataSlots !== void 0) {
|
|
4832
|
+
for (const slot of ext.metadataSlots) {
|
|
4833
|
+
if (metadataSlotMap.has(slot.slotId)) {
|
|
4834
|
+
throw new Error(`Duplicate metadata slot ID: "${slot.slotId}"`);
|
|
4835
|
+
}
|
|
4836
|
+
metadataSlotMap.set(slot.slotId, true);
|
|
4837
|
+
const canonicalTagName = (0, import_internal4.normalizeFormSpecTagName)(slot.tagName);
|
|
4838
|
+
if (slot.allowBare === false && (slot.qualifiers?.length ?? 0) === 0) {
|
|
4839
|
+
throw new Error(
|
|
4840
|
+
`Metadata tag "@${canonicalTagName}" must allow bare usage or declare at least one qualifier.`
|
|
4841
|
+
);
|
|
4842
|
+
}
|
|
4843
|
+
if (metadataTagMap.has(canonicalTagName)) {
|
|
4844
|
+
throw new Error(`Duplicate metadata tag: "@${canonicalTagName}"`);
|
|
4845
|
+
}
|
|
4846
|
+
if (BUILTIN_METADATA_TAGS.has(canonicalTagName)) {
|
|
4847
|
+
throw new Error(
|
|
4848
|
+
`Metadata tag "@${canonicalTagName}" conflicts with built-in metadata tags.`
|
|
4849
|
+
);
|
|
4850
|
+
}
|
|
4851
|
+
if (constraintTagMap.has(canonicalTagName)) {
|
|
4852
|
+
throw new Error(
|
|
4853
|
+
`Metadata tag "@${canonicalTagName}" conflicts with existing FormSpec tag "@${canonicalTagName}".`
|
|
4854
|
+
);
|
|
4855
|
+
}
|
|
4856
|
+
if (Object.hasOwn(import_internals5.BUILTIN_CONSTRAINT_DEFINITIONS, (0, import_internals5.normalizeConstraintTagName)(canonicalTagName))) {
|
|
4857
|
+
throw new Error(
|
|
4858
|
+
`Metadata tag "@${canonicalTagName}" conflicts with existing FormSpec tag "@${(0, import_internals5.normalizeConstraintTagName)(canonicalTagName)}".`
|
|
4859
|
+
);
|
|
4860
|
+
}
|
|
4861
|
+
const existingTag = (0, import_internal4.getTagDefinition)(canonicalTagName, reservedTagSources);
|
|
4862
|
+
if (existingTag !== null) {
|
|
4863
|
+
throw BUILTIN_METADATA_TAGS.has(existingTag.canonicalName) ? new Error(
|
|
4864
|
+
`Metadata tag "@${canonicalTagName}" conflicts with built-in metadata tags.`
|
|
4865
|
+
) : new Error(
|
|
4866
|
+
`Metadata tag "@${canonicalTagName}" conflicts with existing FormSpec tag "@${existingTag.canonicalName}".`
|
|
4867
|
+
);
|
|
4868
|
+
}
|
|
4869
|
+
metadataTagMap.set(canonicalTagName, true);
|
|
4870
|
+
}
|
|
4871
|
+
}
|
|
4707
4872
|
}
|
|
4708
4873
|
return {
|
|
4709
4874
|
extensions,
|
|
4710
4875
|
findType: (typeId) => typeMap.get(typeId),
|
|
4711
4876
|
findTypeByName: (typeName) => typeNameMap.get(typeName),
|
|
4712
4877
|
findConstraint: (constraintId) => constraintMap.get(constraintId),
|
|
4713
|
-
findConstraintTag: (tagName) => constraintTagMap.get(tagName),
|
|
4878
|
+
findConstraintTag: (tagName) => constraintTagMap.get((0, import_internal4.normalizeFormSpecTagName)(tagName)),
|
|
4714
4879
|
findBuiltinConstraintBroadening: (typeId, tagName) => builtinBroadeningMap.get(`${typeId}:${tagName}`),
|
|
4715
4880
|
findAnnotation: (annotationId) => annotationMap.get(annotationId)
|
|
4716
4881
|
};
|
|
4717
4882
|
}
|
|
4718
4883
|
|
|
4719
4884
|
// src/generators/method-schema.ts
|
|
4720
|
-
var
|
|
4885
|
+
var import_internals6 = require("@formspec/core/internals");
|
|
4721
4886
|
function typeToJsonSchema(type, checker) {
|
|
4722
4887
|
const typeRegistry = {};
|
|
4723
4888
|
const visiting = /* @__PURE__ */ new Set();
|
|
@@ -4742,7 +4907,7 @@ function typeToJsonSchema(type, checker) {
|
|
|
4742
4907
|
const fieldProvenance = { surface: "tsdoc", file: "", line: 0, column: 0 };
|
|
4743
4908
|
const ir = {
|
|
4744
4909
|
kind: "form-ir",
|
|
4745
|
-
irVersion:
|
|
4910
|
+
irVersion: import_internals6.IR_VERSION,
|
|
4746
4911
|
elements: [
|
|
4747
4912
|
{
|
|
4748
4913
|
kind: "field",
|