@formspec/build 0.1.0-alpha.32 → 0.1.0-alpha.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analyzer/class-analyzer.d.ts +5 -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/cli.cjs +317 -165
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +300 -140
- package/dist/cli.js.map +1 -1
- package/dist/extensions/registry.d.ts.map +1 -1
- package/dist/generators/discovered-schema.d.ts.map +1 -1
- package/dist/index.cjs +312 -161
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +299 -140
- package/dist/index.js.map +1 -1
- package/dist/internals.cjs +270 -127
- package/dist/internals.cjs.map +1 -1
- package/dist/internals.js +276 -125
- package/dist/internals.js.map +1 -1
- 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: {
|
|
@@ -2173,6 +2208,8 @@ function resolveDiscriminatorApiName(boundType, checker, metadataPolicy) {
|
|
|
2173
2208
|
"type",
|
|
2174
2209
|
getDiscriminatorLogicalName(boundType, declaration, checker),
|
|
2175
2210
|
declaration,
|
|
2211
|
+
checker,
|
|
2212
|
+
void 0,
|
|
2176
2213
|
{
|
|
2177
2214
|
checker,
|
|
2178
2215
|
declaration,
|
|
@@ -2409,12 +2446,20 @@ function analyzeFieldToIR(prop, checker, file, typeRegistry, visiting, diagnosti
|
|
|
2409
2446
|
annotations.push(defaultAnnotation);
|
|
2410
2447
|
}
|
|
2411
2448
|
({ type, annotations } = applyEnumMemberDisplayNames(type, annotations));
|
|
2412
|
-
const metadata = resolveNodeMetadata(
|
|
2449
|
+
const metadata = resolveNodeMetadata(
|
|
2450
|
+
metadataPolicy,
|
|
2451
|
+
"field",
|
|
2452
|
+
name,
|
|
2453
|
+
prop,
|
|
2413
2454
|
checker,
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2455
|
+
extensionRegistry,
|
|
2456
|
+
{
|
|
2457
|
+
checker,
|
|
2458
|
+
declaration: prop,
|
|
2459
|
+
subjectType: tsType,
|
|
2460
|
+
hostType
|
|
2461
|
+
}
|
|
2462
|
+
);
|
|
2418
2463
|
return {
|
|
2419
2464
|
kind: "field",
|
|
2420
2465
|
name,
|
|
@@ -2461,12 +2506,20 @@ function analyzeInterfacePropertyToIR(prop, checker, file, typeRegistry, visitin
|
|
|
2461
2506
|
let annotations = [];
|
|
2462
2507
|
annotations.push(...docResult.annotations);
|
|
2463
2508
|
({ type, annotations } = applyEnumMemberDisplayNames(type, annotations));
|
|
2464
|
-
const metadata = resolveNodeMetadata(
|
|
2509
|
+
const metadata = resolveNodeMetadata(
|
|
2510
|
+
metadataPolicy,
|
|
2511
|
+
"field",
|
|
2512
|
+
name,
|
|
2513
|
+
prop,
|
|
2465
2514
|
checker,
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2515
|
+
extensionRegistry,
|
|
2516
|
+
{
|
|
2517
|
+
checker,
|
|
2518
|
+
declaration: prop,
|
|
2519
|
+
subjectType: tsType,
|
|
2520
|
+
hostType
|
|
2521
|
+
}
|
|
2522
|
+
);
|
|
2470
2523
|
return {
|
|
2471
2524
|
kind: "field",
|
|
2472
2525
|
name,
|
|
@@ -2595,7 +2648,7 @@ function getTypeNodeRegistrationName(typeNode) {
|
|
|
2595
2648
|
}
|
|
2596
2649
|
return null;
|
|
2597
2650
|
}
|
|
2598
|
-
function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
2651
|
+
function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
2599
2652
|
const customType = resolveRegisteredCustomType(sourceNode, extensionRegistry, checker);
|
|
2600
2653
|
if (customType) {
|
|
2601
2654
|
return customType;
|
|
@@ -2685,7 +2738,7 @@ function resolveTypeNode(type, checker, file, typeRegistry, visiting, sourceNode
|
|
|
2685
2738
|
}
|
|
2686
2739
|
return { kind: "primitive", primitiveKind: "string" };
|
|
2687
2740
|
}
|
|
2688
|
-
function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
2741
|
+
function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
2689
2742
|
if (!(type.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null))) {
|
|
2690
2743
|
return null;
|
|
2691
2744
|
}
|
|
@@ -2705,11 +2758,19 @@ function tryResolveNamedPrimitiveAlias(type, checker, file, typeRegistry, visiti
|
|
|
2705
2758
|
file,
|
|
2706
2759
|
makeParseOptions(extensionRegistry)
|
|
2707
2760
|
);
|
|
2708
|
-
const metadata = resolveNodeMetadata(
|
|
2761
|
+
const metadata = resolveNodeMetadata(
|
|
2762
|
+
metadataPolicy,
|
|
2763
|
+
"type",
|
|
2764
|
+
aliasName,
|
|
2765
|
+
aliasDecl,
|
|
2709
2766
|
checker,
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2767
|
+
extensionRegistry,
|
|
2768
|
+
{
|
|
2769
|
+
checker,
|
|
2770
|
+
declaration: aliasDecl,
|
|
2771
|
+
subjectType: aliasType
|
|
2772
|
+
}
|
|
2773
|
+
);
|
|
2713
2774
|
typeRegistry[aliasName] = {
|
|
2714
2775
|
name: aliasName,
|
|
2715
2776
|
...metadata !== void 0 && { metadata },
|
|
@@ -2748,7 +2809,7 @@ function shouldEmitPrimitiveAliasDefinition(typeNode, checker) {
|
|
|
2748
2809
|
const resolved = checker.getTypeFromTypeNode(aliasDecl.type);
|
|
2749
2810
|
return !!(resolved.flags & (ts3.TypeFlags.String | ts3.TypeFlags.Number | ts3.TypeFlags.BigInt | ts3.TypeFlags.BigIntLiteral | ts3.TypeFlags.Boolean | ts3.TypeFlags.Null));
|
|
2750
2811
|
}
|
|
2751
|
-
function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy =
|
|
2812
|
+
function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiting, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
2752
2813
|
const nestedAliasDecl = type.aliasSymbol?.declarations?.find(ts3.isTypeAliasDeclaration);
|
|
2753
2814
|
if (nestedAliasDecl !== void 0) {
|
|
2754
2815
|
return resolveAliasedPrimitiveTarget(
|
|
@@ -2774,7 +2835,7 @@ function resolveAliasedPrimitiveTarget(type, checker, file, typeRegistry, visiti
|
|
|
2774
2835
|
diagnostics
|
|
2775
2836
|
);
|
|
2776
2837
|
}
|
|
2777
|
-
function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
2838
|
+
function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
2778
2839
|
const typeName = getNamedTypeName(type);
|
|
2779
2840
|
const namedDecl = getNamedTypeDeclaration(type);
|
|
2780
2841
|
if (typeName && typeName in typeRegistry) {
|
|
@@ -2809,11 +2870,19 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
2809
2870
|
return result;
|
|
2810
2871
|
}
|
|
2811
2872
|
const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
|
|
2812
|
-
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
2873
|
+
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
2874
|
+
metadataPolicy,
|
|
2875
|
+
"type",
|
|
2876
|
+
typeName,
|
|
2877
|
+
namedDecl,
|
|
2813
2878
|
checker,
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2879
|
+
extensionRegistry,
|
|
2880
|
+
{
|
|
2881
|
+
checker,
|
|
2882
|
+
declaration: namedDecl,
|
|
2883
|
+
subjectType: type
|
|
2884
|
+
}
|
|
2885
|
+
) : void 0;
|
|
2817
2886
|
typeRegistry[typeName] = {
|
|
2818
2887
|
name: typeName,
|
|
2819
2888
|
...metadata !== void 0 && { metadata },
|
|
@@ -2898,7 +2967,7 @@ function resolveUnionType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
2898
2967
|
}
|
|
2899
2968
|
return registerNamed({ kind: "union", members });
|
|
2900
2969
|
}
|
|
2901
|
-
function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
2970
|
+
function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
2902
2971
|
const typeArgs = isTypeReference(type) ? type.typeArguments : void 0;
|
|
2903
2972
|
const elementType = typeArgs?.[0];
|
|
2904
2973
|
const elementSourceNode = extractArrayElementTypeNode(sourceNode, checker);
|
|
@@ -2915,7 +2984,7 @@ function resolveArrayType(type, checker, file, typeRegistry, visiting, sourceNod
|
|
|
2915
2984
|
) : { kind: "primitive", primitiveKind: "string" };
|
|
2916
2985
|
return { kind: "array", items };
|
|
2917
2986
|
}
|
|
2918
|
-
function tryResolveRecordType(type, checker, file, typeRegistry, visiting, metadataPolicy =
|
|
2987
|
+
function tryResolveRecordType(type, checker, file, typeRegistry, visiting, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
2919
2988
|
if (type.getProperties().length > 0) {
|
|
2920
2989
|
return null;
|
|
2921
2990
|
}
|
|
@@ -2976,7 +3045,7 @@ function shouldEmitResolvedObjectProperty(property, declaration) {
|
|
|
2976
3045
|
}
|
|
2977
3046
|
return true;
|
|
2978
3047
|
}
|
|
2979
|
-
function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy =
|
|
3048
|
+
function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNode, metadataPolicy = createAnalyzerMetadataPolicy(void 0), extensionRegistry, diagnostics) {
|
|
2980
3049
|
const collectedDiagnostics = diagnostics ?? [];
|
|
2981
3050
|
const typeName = getNamedTypeName(type);
|
|
2982
3051
|
const namedTypeName = typeName ?? void 0;
|
|
@@ -3052,11 +3121,19 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3052
3121
|
return recordNode;
|
|
3053
3122
|
}
|
|
3054
3123
|
const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
|
|
3055
|
-
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
3124
|
+
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
3125
|
+
metadataPolicy,
|
|
3126
|
+
"type",
|
|
3127
|
+
registryTypeName,
|
|
3128
|
+
namedDecl,
|
|
3056
3129
|
checker,
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3130
|
+
extensionRegistry,
|
|
3131
|
+
{
|
|
3132
|
+
checker,
|
|
3133
|
+
declaration: namedDecl,
|
|
3134
|
+
subjectType: type
|
|
3135
|
+
}
|
|
3136
|
+
) : void 0;
|
|
3060
3137
|
typeRegistry[registryTypeName] = {
|
|
3061
3138
|
name: registryTypeName,
|
|
3062
3139
|
...metadata !== void 0 && { metadata },
|
|
@@ -3152,11 +3229,19 @@ function resolveObjectType(type, checker, file, typeRegistry, visiting, sourceNo
|
|
|
3152
3229
|
};
|
|
3153
3230
|
if (registryTypeName !== void 0 && shouldRegisterNamedType) {
|
|
3154
3231
|
const annotations = namedDecl ? extractJSDocAnnotationNodes(namedDecl, file, makeParseOptions(extensionRegistry)) : void 0;
|
|
3155
|
-
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
3232
|
+
const metadata = namedDecl !== void 0 ? resolveNodeMetadata(
|
|
3233
|
+
metadataPolicy,
|
|
3234
|
+
"type",
|
|
3235
|
+
registryTypeName,
|
|
3236
|
+
namedDecl,
|
|
3156
3237
|
checker,
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3238
|
+
extensionRegistry,
|
|
3239
|
+
{
|
|
3240
|
+
checker,
|
|
3241
|
+
declaration: namedDecl,
|
|
3242
|
+
subjectType: type
|
|
3243
|
+
}
|
|
3244
|
+
) : void 0;
|
|
3160
3245
|
typeRegistry[registryTypeName] = {
|
|
3161
3246
|
name: registryTypeName,
|
|
3162
3247
|
...metadata !== void 0 && { metadata },
|
|
@@ -4659,13 +4744,29 @@ function formatLocation(location) {
|
|
|
4659
4744
|
}
|
|
4660
4745
|
|
|
4661
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
|
+
}
|
|
4662
4760
|
function createExtensionRegistry(extensions) {
|
|
4761
|
+
const reservedTagSources = buildConstraintTagSources(extensions);
|
|
4663
4762
|
const typeMap = /* @__PURE__ */ new Map();
|
|
4664
4763
|
const typeNameMap = /* @__PURE__ */ new Map();
|
|
4665
4764
|
const constraintMap = /* @__PURE__ */ new Map();
|
|
4666
4765
|
const constraintTagMap = /* @__PURE__ */ new Map();
|
|
4667
4766
|
const builtinBroadeningMap = /* @__PURE__ */ new Map();
|
|
4668
4767
|
const annotationMap = /* @__PURE__ */ new Map();
|
|
4768
|
+
const metadataSlotMap = /* @__PURE__ */ new Map();
|
|
4769
|
+
const metadataTagMap = /* @__PURE__ */ new Map();
|
|
4669
4770
|
for (const ext of extensions) {
|
|
4670
4771
|
if (ext.types !== void 0) {
|
|
4671
4772
|
for (const type of ext.types) {
|
|
@@ -4708,10 +4809,11 @@ function createExtensionRegistry(extensions) {
|
|
|
4708
4809
|
}
|
|
4709
4810
|
if (ext.constraintTags !== void 0) {
|
|
4710
4811
|
for (const tag of ext.constraintTags) {
|
|
4711
|
-
|
|
4712
|
-
|
|
4812
|
+
const canonicalTagName = (0, import_internal4.normalizeFormSpecTagName)(tag.tagName);
|
|
4813
|
+
if (constraintTagMap.has(canonicalTagName)) {
|
|
4814
|
+
throw new Error(`Duplicate custom constraint tag: "@${canonicalTagName}"`);
|
|
4713
4815
|
}
|
|
4714
|
-
constraintTagMap.set(
|
|
4816
|
+
constraintTagMap.set(canonicalTagName, {
|
|
4715
4817
|
extensionId: ext.extensionId,
|
|
4716
4818
|
registration: tag
|
|
4717
4819
|
});
|
|
@@ -4726,20 +4828,61 @@ function createExtensionRegistry(extensions) {
|
|
|
4726
4828
|
annotationMap.set(qualifiedId, annotation);
|
|
4727
4829
|
}
|
|
4728
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
|
+
}
|
|
4729
4872
|
}
|
|
4730
4873
|
return {
|
|
4731
4874
|
extensions,
|
|
4732
4875
|
findType: (typeId) => typeMap.get(typeId),
|
|
4733
4876
|
findTypeByName: (typeName) => typeNameMap.get(typeName),
|
|
4734
4877
|
findConstraint: (constraintId) => constraintMap.get(constraintId),
|
|
4735
|
-
findConstraintTag: (tagName) => constraintTagMap.get(tagName),
|
|
4878
|
+
findConstraintTag: (tagName) => constraintTagMap.get((0, import_internal4.normalizeFormSpecTagName)(tagName)),
|
|
4736
4879
|
findBuiltinConstraintBroadening: (typeId, tagName) => builtinBroadeningMap.get(`${typeId}:${tagName}`),
|
|
4737
4880
|
findAnnotation: (annotationId) => annotationMap.get(annotationId)
|
|
4738
4881
|
};
|
|
4739
4882
|
}
|
|
4740
4883
|
|
|
4741
4884
|
// src/generators/method-schema.ts
|
|
4742
|
-
var
|
|
4885
|
+
var import_internals6 = require("@formspec/core/internals");
|
|
4743
4886
|
function typeToJsonSchema(type, checker) {
|
|
4744
4887
|
const typeRegistry = {};
|
|
4745
4888
|
const visiting = /* @__PURE__ */ new Set();
|
|
@@ -4764,7 +4907,7 @@ function typeToJsonSchema(type, checker) {
|
|
|
4764
4907
|
const fieldProvenance = { surface: "tsdoc", file: "", line: 0, column: 0 };
|
|
4765
4908
|
const ir = {
|
|
4766
4909
|
kind: "form-ir",
|
|
4767
|
-
irVersion:
|
|
4910
|
+
irVersion: import_internals6.IR_VERSION,
|
|
4768
4911
|
elements: [
|
|
4769
4912
|
{
|
|
4770
4913
|
kind: "field",
|