@openpkg-ts/sdk 0.37.0 → 0.37.1
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/browser.js +1 -1
- package/dist/index.js +289 -266
- package/dist/shared/{chunk-hnajr1tb.js → chunk-zrx9s0n4.js} +2 -1
- package/package.json +1 -1
package/dist/browser.js
CHANGED
package/dist/index.js
CHANGED
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
toPagefindRecords,
|
|
30
30
|
toSearchIndex,
|
|
31
31
|
toSearchIndexJSON
|
|
32
|
-
} from "./shared/chunk-
|
|
32
|
+
} from "./shared/chunk-zrx9s0n4.js";
|
|
33
33
|
|
|
34
34
|
// src/primitives/diff.ts
|
|
35
35
|
import {
|
|
@@ -86,6 +86,9 @@ import * as fs2 from "node:fs";
|
|
|
86
86
|
import { validateSpec } from "@openpkg-ts/spec";
|
|
87
87
|
|
|
88
88
|
// src/render/html.ts
|
|
89
|
+
import {
|
|
90
|
+
KIND_LABELS
|
|
91
|
+
} from "@openpkg-ts/spec";
|
|
89
92
|
var defaultCSS = `
|
|
90
93
|
:root {
|
|
91
94
|
--text: #1a1a1a;
|
|
@@ -381,14 +384,14 @@ function toHTML(spec, options = {}) {
|
|
|
381
384
|
const byKind = groupByKind(specExports);
|
|
382
385
|
const navItems = Object.entries(byKind).map(([kind, exports]) => {
|
|
383
386
|
const links = exports.map((e) => `<a href="#${e.id}">${escapeHTML(e.name)}</a>`).join("");
|
|
384
|
-
return `<li><strong>${kind}
|
|
387
|
+
return `<li><strong>${KIND_LABELS[kind] ?? kind}:</strong> ${links}</li>`;
|
|
385
388
|
}).join("");
|
|
386
389
|
const nav = `<nav><ul>${navItems}</ul></nav>`;
|
|
387
390
|
const sections = KIND_ORDER.filter((kind) => byKind[kind]?.length).map((kind) => {
|
|
388
391
|
const exports = byKind[kind].map(renderExport).join("");
|
|
389
392
|
return `
|
|
390
393
|
<section class="kind-section">
|
|
391
|
-
<h2>${kind
|
|
394
|
+
<h2>${KIND_LABELS[kind]}</h2>
|
|
392
395
|
${exports}
|
|
393
396
|
</section>`;
|
|
394
397
|
}).join("");
|
|
@@ -533,6 +536,9 @@ function toJSONString(spec, options = {}) {
|
|
|
533
536
|
}
|
|
534
537
|
|
|
535
538
|
// src/render/markdown.ts
|
|
539
|
+
import {
|
|
540
|
+
KIND_LABELS as KIND_LABELS2
|
|
541
|
+
} from "@openpkg-ts/spec";
|
|
536
542
|
var defaultSections = {
|
|
537
543
|
signature: true,
|
|
538
544
|
description: true,
|
|
@@ -898,7 +904,7 @@ function toMarkdown(spec, options = {}) {
|
|
|
898
904
|
const exports = byKind[kind];
|
|
899
905
|
if (!exports?.length)
|
|
900
906
|
continue;
|
|
901
|
-
parts.push(`## ${kind
|
|
907
|
+
parts.push(`## ${KIND_LABELS2[kind]}`);
|
|
902
908
|
parts.push("");
|
|
903
909
|
for (const exp of exports) {
|
|
904
910
|
const content = exportToMarkdown(exp, {
|
|
@@ -915,18 +921,7 @@ function toMarkdown(spec, options = {}) {
|
|
|
915
921
|
}
|
|
916
922
|
|
|
917
923
|
// src/render/nav.ts
|
|
918
|
-
|
|
919
|
-
function: "Functions",
|
|
920
|
-
class: "Classes",
|
|
921
|
-
interface: "Interfaces",
|
|
922
|
-
type: "Types",
|
|
923
|
-
enum: "Enums",
|
|
924
|
-
variable: "Variables",
|
|
925
|
-
namespace: "Namespaces",
|
|
926
|
-
module: "Modules",
|
|
927
|
-
reference: "References",
|
|
928
|
-
external: "External"
|
|
929
|
-
};
|
|
924
|
+
import { KIND_LABELS as KIND_LABELS3 } from "@openpkg-ts/spec";
|
|
930
925
|
var defaultSlugify = (name) => name.toLowerCase().replace(/[^a-z0-9]+/g, "-");
|
|
931
926
|
function getModuleName(exp) {
|
|
932
927
|
if (exp.source?.file) {
|
|
@@ -980,9 +975,9 @@ function toGenericNav(spec, options) {
|
|
|
980
975
|
sortAlphabetically = true,
|
|
981
976
|
includeGroupIndex = false
|
|
982
977
|
} = options;
|
|
983
|
-
const labels = { ...
|
|
978
|
+
const labels = { ...KIND_LABELS3, ...kindLabels };
|
|
984
979
|
const grouped = groupExports(spec.exports, groupBy);
|
|
985
|
-
const
|
|
980
|
+
const keyedGroups = [];
|
|
986
981
|
for (const [key, exports] of grouped) {
|
|
987
982
|
const sortedExports = sortAlphabetically ? sortByName(exports) : exports;
|
|
988
983
|
const items = sortedExports.map((exp) => ({
|
|
@@ -990,19 +985,19 @@ function toGenericNav(spec, options) {
|
|
|
990
985
|
href: `${basePath}/${slugify(exp.name)}`
|
|
991
986
|
}));
|
|
992
987
|
const title = groupBy === "kind" ? labels[key] || key : key;
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
988
|
+
keyedGroups.push({
|
|
989
|
+
key,
|
|
990
|
+
group: {
|
|
991
|
+
title,
|
|
992
|
+
items,
|
|
993
|
+
index: includeGroupIndex ? `${basePath}/${slugify(key)}` : undefined
|
|
994
|
+
}
|
|
997
995
|
});
|
|
998
996
|
}
|
|
999
997
|
if (groupBy === "kind") {
|
|
1000
|
-
|
|
1001
|
-
const aIdx = KIND_ORDER.indexOf(a.title.toLowerCase().replace(/s$/, ""));
|
|
1002
|
-
const bIdx = KIND_ORDER.indexOf(b.title.toLowerCase().replace(/s$/, ""));
|
|
1003
|
-
return aIdx - bIdx;
|
|
1004
|
-
});
|
|
998
|
+
keyedGroups.sort((a, b) => KIND_ORDER.indexOf(a.key) - KIND_ORDER.indexOf(b.key));
|
|
1005
999
|
}
|
|
1000
|
+
const groups = keyedGroups.map((g) => g.group);
|
|
1006
1001
|
const flatItems = groupBy === "none" ? groups.flatMap((g) => g.items) : groups.map((g) => ({
|
|
1007
1002
|
title: g.title,
|
|
1008
1003
|
items: g.items
|
|
@@ -1517,211 +1512,8 @@ function filterSpec(spec, criteria) {
|
|
|
1517
1512
|
// src/primitives/get.ts
|
|
1518
1513
|
import ts11 from "typescript";
|
|
1519
1514
|
|
|
1520
|
-
// src/compiler/program.ts
|
|
1521
|
-
import * as fs4 from "node:fs";
|
|
1522
|
-
import * as path3 from "node:path";
|
|
1523
|
-
import ts from "typescript";
|
|
1524
|
-
function isJsFile(file) {
|
|
1525
|
-
return /\.(js|mjs|cjs|jsx)$/.test(file);
|
|
1526
|
-
}
|
|
1527
|
-
function getScriptKind(file) {
|
|
1528
|
-
if (/\.tsx$/.test(file))
|
|
1529
|
-
return ts.ScriptKind.TSX;
|
|
1530
|
-
if (/\.jsx$/.test(file))
|
|
1531
|
-
return ts.ScriptKind.JSX;
|
|
1532
|
-
if (/\.(js|mjs|cjs)$/.test(file))
|
|
1533
|
-
return ts.ScriptKind.JS;
|
|
1534
|
-
return ts.ScriptKind.TS;
|
|
1535
|
-
}
|
|
1536
|
-
var DEFAULT_COMPILER_OPTIONS = {
|
|
1537
|
-
target: ts.ScriptTarget.Latest,
|
|
1538
|
-
module: ts.ModuleKind.CommonJS,
|
|
1539
|
-
lib: ["lib.es2021.d.ts"],
|
|
1540
|
-
declaration: true,
|
|
1541
|
-
moduleResolution: ts.ModuleResolutionKind.NodeJs
|
|
1542
|
-
};
|
|
1543
|
-
function resolveProjectReferences(configPath, parsedConfig) {
|
|
1544
|
-
const additionalFiles = [];
|
|
1545
|
-
if (!parsedConfig.projectReferences?.length) {
|
|
1546
|
-
return additionalFiles;
|
|
1547
|
-
}
|
|
1548
|
-
const configDir = path3.dirname(configPath);
|
|
1549
|
-
for (const ref of parsedConfig.projectReferences) {
|
|
1550
|
-
const refPath = path3.resolve(configDir, ref.path);
|
|
1551
|
-
const refConfigPath = fs4.existsSync(path3.join(refPath, "tsconfig.json")) ? path3.join(refPath, "tsconfig.json") : refPath;
|
|
1552
|
-
if (!fs4.existsSync(refConfigPath))
|
|
1553
|
-
continue;
|
|
1554
|
-
const refConfigFile = ts.readConfigFile(refConfigPath, ts.sys.readFile);
|
|
1555
|
-
if (refConfigFile.error)
|
|
1556
|
-
continue;
|
|
1557
|
-
const refParsed = ts.parseJsonConfigFileContent(refConfigFile.config, ts.sys, path3.dirname(refConfigPath));
|
|
1558
|
-
additionalFiles.push(...refParsed.fileNames);
|
|
1559
|
-
}
|
|
1560
|
-
return additionalFiles;
|
|
1561
|
-
}
|
|
1562
|
-
function parsePnpmWorkspace(yamlContent) {
|
|
1563
|
-
const globs = [];
|
|
1564
|
-
const lines = yamlContent.split(`
|
|
1565
|
-
`);
|
|
1566
|
-
let inPackages = false;
|
|
1567
|
-
for (const line of lines) {
|
|
1568
|
-
const trimmed = line.trim();
|
|
1569
|
-
if (trimmed === "packages:") {
|
|
1570
|
-
inPackages = true;
|
|
1571
|
-
continue;
|
|
1572
|
-
}
|
|
1573
|
-
if (inPackages) {
|
|
1574
|
-
if (!line.startsWith(" ") && !line.startsWith("-") && trimmed) {
|
|
1575
|
-
break;
|
|
1576
|
-
}
|
|
1577
|
-
const match = trimmed.match(/^-\s*['"]?([^'"]+)['"]?$/);
|
|
1578
|
-
if (match) {
|
|
1579
|
-
globs.push(match[1]);
|
|
1580
|
-
}
|
|
1581
|
-
}
|
|
1582
|
-
}
|
|
1583
|
-
return globs;
|
|
1584
|
-
}
|
|
1585
|
-
function buildWorkspaceMap(baseDir) {
|
|
1586
|
-
let currentDir = baseDir;
|
|
1587
|
-
let rootDir;
|
|
1588
|
-
let workspaceGlobs = [];
|
|
1589
|
-
for (let i = 0;i < 10; i++) {
|
|
1590
|
-
const pnpmPath = path3.join(currentDir, "pnpm-workspace.yaml");
|
|
1591
|
-
if (fs4.existsSync(pnpmPath)) {
|
|
1592
|
-
try {
|
|
1593
|
-
const yamlContent = fs4.readFileSync(pnpmPath, "utf-8");
|
|
1594
|
-
workspaceGlobs = parsePnpmWorkspace(yamlContent);
|
|
1595
|
-
if (workspaceGlobs.length > 0) {
|
|
1596
|
-
rootDir = currentDir;
|
|
1597
|
-
break;
|
|
1598
|
-
}
|
|
1599
|
-
} catch {}
|
|
1600
|
-
}
|
|
1601
|
-
const pkgPath = path3.join(currentDir, "package.json");
|
|
1602
|
-
if (fs4.existsSync(pkgPath)) {
|
|
1603
|
-
try {
|
|
1604
|
-
const pkg = JSON.parse(fs4.readFileSync(pkgPath, "utf-8"));
|
|
1605
|
-
if (pkg.workspaces) {
|
|
1606
|
-
rootDir = currentDir;
|
|
1607
|
-
workspaceGlobs = Array.isArray(pkg.workspaces) ? pkg.workspaces : pkg.workspaces?.packages || [];
|
|
1608
|
-
break;
|
|
1609
|
-
}
|
|
1610
|
-
} catch {}
|
|
1611
|
-
}
|
|
1612
|
-
const parent = path3.dirname(currentDir);
|
|
1613
|
-
if (parent === currentDir)
|
|
1614
|
-
break;
|
|
1615
|
-
currentDir = parent;
|
|
1616
|
-
}
|
|
1617
|
-
if (!rootDir || workspaceGlobs.length === 0)
|
|
1618
|
-
return;
|
|
1619
|
-
const packages = new Map;
|
|
1620
|
-
for (const glob of workspaceGlobs) {
|
|
1621
|
-
const globDir = path3.join(rootDir, glob.replace(/\/\*$/, ""));
|
|
1622
|
-
if (!fs4.existsSync(globDir) || !fs4.statSync(globDir).isDirectory())
|
|
1623
|
-
continue;
|
|
1624
|
-
const entries = fs4.readdirSync(globDir, { withFileTypes: true });
|
|
1625
|
-
for (const entry of entries) {
|
|
1626
|
-
if (!entry.isDirectory())
|
|
1627
|
-
continue;
|
|
1628
|
-
const pkgDir = path3.join(globDir, entry.name);
|
|
1629
|
-
const pkgJsonPath = path3.join(pkgDir, "package.json");
|
|
1630
|
-
if (!fs4.existsSync(pkgJsonPath))
|
|
1631
|
-
continue;
|
|
1632
|
-
try {
|
|
1633
|
-
const pkg = JSON.parse(fs4.readFileSync(pkgJsonPath, "utf-8"));
|
|
1634
|
-
if (pkg.name) {
|
|
1635
|
-
const srcDir = fs4.existsSync(path3.join(pkgDir, "src")) ? path3.join(pkgDir, "src") : pkgDir;
|
|
1636
|
-
packages.set(pkg.name, srcDir);
|
|
1637
|
-
}
|
|
1638
|
-
} catch {}
|
|
1639
|
-
}
|
|
1640
|
-
}
|
|
1641
|
-
return packages.size > 0 ? { packages, rootDir } : undefined;
|
|
1642
|
-
}
|
|
1643
|
-
function createProgram({
|
|
1644
|
-
entryFile,
|
|
1645
|
-
baseDir = path3.dirname(entryFile),
|
|
1646
|
-
content
|
|
1647
|
-
}) {
|
|
1648
|
-
let configPath = ts.findConfigFile(baseDir, ts.sys.fileExists, "tsconfig.json");
|
|
1649
|
-
if (!configPath) {
|
|
1650
|
-
configPath = ts.findConfigFile(baseDir, ts.sys.fileExists, "jsconfig.json");
|
|
1651
|
-
}
|
|
1652
|
-
let compilerOptions = { ...DEFAULT_COMPILER_OPTIONS };
|
|
1653
|
-
let additionalRootFiles = [];
|
|
1654
|
-
if (configPath) {
|
|
1655
|
-
const configFile = ts.readConfigFile(configPath, ts.sys.readFile);
|
|
1656
|
-
const parsedConfig = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path3.dirname(configPath));
|
|
1657
|
-
compilerOptions = { ...compilerOptions, ...parsedConfig.options };
|
|
1658
|
-
additionalRootFiles = resolveProjectReferences(configPath, parsedConfig);
|
|
1659
|
-
const sourceFiles = parsedConfig.fileNames.filter((f) => !f.includes(".test.") && !f.includes(".spec.") && !f.includes("/dist/") && !f.includes("/node_modules/"));
|
|
1660
|
-
additionalRootFiles.push(...sourceFiles);
|
|
1661
|
-
}
|
|
1662
|
-
if (isJsFile(entryFile)) {
|
|
1663
|
-
compilerOptions = {
|
|
1664
|
-
...compilerOptions,
|
|
1665
|
-
allowJs: true,
|
|
1666
|
-
checkJs: true,
|
|
1667
|
-
isolatedDeclarations: false
|
|
1668
|
-
};
|
|
1669
|
-
} else {
|
|
1670
|
-
const allowJsVal = compilerOptions.allowJs;
|
|
1671
|
-
if (typeof allowJsVal === "boolean" && allowJsVal) {
|
|
1672
|
-
compilerOptions = { ...compilerOptions, allowJs: false, checkJs: false };
|
|
1673
|
-
}
|
|
1674
|
-
}
|
|
1675
|
-
const workspaceMap = buildWorkspaceMap(baseDir);
|
|
1676
|
-
const compilerHost = ts.createCompilerHost(compilerOptions, true);
|
|
1677
|
-
let inMemorySource;
|
|
1678
|
-
if (workspaceMap) {
|
|
1679
|
-
const originalResolveModuleNames = compilerHost.resolveModuleNames?.bind(compilerHost);
|
|
1680
|
-
compilerHost.resolveModuleNames = (moduleNames, containingFile, _reusedNames, redirectedReference, options) => {
|
|
1681
|
-
return moduleNames.map((moduleName) => {
|
|
1682
|
-
const srcDir = workspaceMap.packages.get(moduleName);
|
|
1683
|
-
if (srcDir) {
|
|
1684
|
-
const indexFile = path3.join(srcDir, "index.ts");
|
|
1685
|
-
if (fs4.existsSync(indexFile)) {
|
|
1686
|
-
return { resolvedFileName: indexFile, isExternalLibraryImport: false };
|
|
1687
|
-
}
|
|
1688
|
-
}
|
|
1689
|
-
if (originalResolveModuleNames) {
|
|
1690
|
-
const result = originalResolveModuleNames([moduleName], containingFile, _reusedNames, redirectedReference, options);
|
|
1691
|
-
return result[0];
|
|
1692
|
-
}
|
|
1693
|
-
const resolved = ts.resolveModuleName(moduleName, containingFile, options, compilerHost);
|
|
1694
|
-
return resolved.resolvedModule;
|
|
1695
|
-
});
|
|
1696
|
-
};
|
|
1697
|
-
}
|
|
1698
|
-
if (content !== undefined) {
|
|
1699
|
-
inMemorySource = ts.createSourceFile(entryFile, content, ts.ScriptTarget.Latest, true, getScriptKind(entryFile));
|
|
1700
|
-
const originalGetSourceFile = compilerHost.getSourceFile.bind(compilerHost);
|
|
1701
|
-
compilerHost.getSourceFile = (fileName, languageVersion, onError, shouldCreateNewSourceFile) => {
|
|
1702
|
-
if (fileName === entryFile) {
|
|
1703
|
-
return inMemorySource;
|
|
1704
|
-
}
|
|
1705
|
-
return originalGetSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile);
|
|
1706
|
-
};
|
|
1707
|
-
}
|
|
1708
|
-
const rootFiles = [entryFile, ...additionalRootFiles];
|
|
1709
|
-
const program = ts.createProgram(rootFiles, compilerOptions, compilerHost);
|
|
1710
|
-
const sourceFile = inMemorySource ?? program.getSourceFile(entryFile);
|
|
1711
|
-
return {
|
|
1712
|
-
program,
|
|
1713
|
-
compilerHost,
|
|
1714
|
-
compilerOptions,
|
|
1715
|
-
sourceFile,
|
|
1716
|
-
configPath
|
|
1717
|
-
};
|
|
1718
|
-
}
|
|
1719
|
-
|
|
1720
|
-
// src/serializers/classes.ts
|
|
1721
|
-
import ts7 from "typescript";
|
|
1722
|
-
|
|
1723
1515
|
// src/ast/utils.ts
|
|
1724
|
-
import
|
|
1516
|
+
import ts from "typescript";
|
|
1725
1517
|
function parseExamplesFromTags(tags) {
|
|
1726
1518
|
const examples = [];
|
|
1727
1519
|
for (const tag of tags) {
|
|
@@ -1783,12 +1575,12 @@ function extractSeeTagText(tag) {
|
|
|
1783
1575
|
if (Array.isArray(tag.comment)) {
|
|
1784
1576
|
const parts = [];
|
|
1785
1577
|
for (const part of tag.comment) {
|
|
1786
|
-
if (
|
|
1578
|
+
if (ts.isJSDocLink(part) || ts.isJSDocLinkCode(part) || ts.isJSDocLinkPlain(part)) {
|
|
1787
1579
|
if (part.name) {
|
|
1788
1580
|
try {
|
|
1789
1581
|
parts.push(part.name.getText());
|
|
1790
1582
|
} catch {
|
|
1791
|
-
if (
|
|
1583
|
+
if (ts.isIdentifier(part.name)) {
|
|
1792
1584
|
parts.push(part.name.text);
|
|
1793
1585
|
}
|
|
1794
1586
|
}
|
|
@@ -1796,7 +1588,7 @@ function extractSeeTagText(tag) {
|
|
|
1796
1588
|
if (part.text) {
|
|
1797
1589
|
parts.push(part.text);
|
|
1798
1590
|
}
|
|
1799
|
-
} else if (part.kind ===
|
|
1591
|
+
} else if (part.kind === ts.SyntaxKind.JSDocText) {
|
|
1800
1592
|
parts.push(part.text);
|
|
1801
1593
|
}
|
|
1802
1594
|
}
|
|
@@ -1805,12 +1597,12 @@ function extractSeeTagText(tag) {
|
|
|
1805
1597
|
return result;
|
|
1806
1598
|
}
|
|
1807
1599
|
}
|
|
1808
|
-
return typeof tag.comment === "string" ? tag.comment :
|
|
1600
|
+
return typeof tag.comment === "string" ? tag.comment : ts.getTextOfJSDocComment(tag.comment) ?? "";
|
|
1809
1601
|
}
|
|
1810
1602
|
function getJSDocComment(node, symbol, checker) {
|
|
1811
|
-
const jsDocTags =
|
|
1603
|
+
const jsDocTags = ts.getJSDocTags(node);
|
|
1812
1604
|
const tags = jsDocTags.map((tag) => {
|
|
1813
|
-
const rawText = typeof tag.comment === "string" ? tag.comment :
|
|
1605
|
+
const rawText = typeof tag.comment === "string" ? tag.comment : ts.getTextOfJSDocComment(tag.comment) ?? "";
|
|
1814
1606
|
if (tag.tagName.text === "param") {
|
|
1815
1607
|
const paramTag = tag;
|
|
1816
1608
|
let paramName = "";
|
|
@@ -1845,12 +1637,12 @@ function getJSDocComment(node, symbol, checker) {
|
|
|
1845
1637
|
}
|
|
1846
1638
|
return { name: tag.tagName.text, text: rawText };
|
|
1847
1639
|
});
|
|
1848
|
-
const jsDocComments =
|
|
1640
|
+
const jsDocComments = ts.getJSDocCommentsAndTags(node).filter(ts.isJSDoc);
|
|
1849
1641
|
let description;
|
|
1850
1642
|
if (jsDocComments.length > 0) {
|
|
1851
1643
|
const firstDoc = jsDocComments[0];
|
|
1852
1644
|
if (firstDoc.comment) {
|
|
1853
|
-
description = typeof firstDoc.comment === "string" ? firstDoc.comment :
|
|
1645
|
+
description = typeof firstDoc.comment === "string" ? firstDoc.comment : ts.getTextOfJSDocComment(firstDoc.comment);
|
|
1854
1646
|
}
|
|
1855
1647
|
}
|
|
1856
1648
|
if (!description && symbol && checker) {
|
|
@@ -1883,7 +1675,7 @@ function getParamDescription(propertyName, jsdocTags, inferredAlias) {
|
|
|
1883
1675
|
}
|
|
1884
1676
|
const isMatch = tagParamName === propertyName || inferredAlias && tagParamName === `${inferredAlias}.${propertyName}` || tagParamName.endsWith(`.${propertyName}`);
|
|
1885
1677
|
if (isMatch) {
|
|
1886
|
-
const comment = typeof tag.comment === "string" ? tag.comment :
|
|
1678
|
+
const comment = typeof tag.comment === "string" ? tag.comment : ts.getTextOfJSDocComment(tag.comment);
|
|
1887
1679
|
return stripParamSeparator(comment);
|
|
1888
1680
|
}
|
|
1889
1681
|
}
|
|
@@ -1896,11 +1688,11 @@ function extractVarianceModifiers(modifiers) {
|
|
|
1896
1688
|
let hasOut = false;
|
|
1897
1689
|
let isConst;
|
|
1898
1690
|
for (const mod of modifiers) {
|
|
1899
|
-
if (mod.kind ===
|
|
1691
|
+
if (mod.kind === ts.SyntaxKind.InKeyword)
|
|
1900
1692
|
hasIn = true;
|
|
1901
|
-
if (mod.kind ===
|
|
1693
|
+
if (mod.kind === ts.SyntaxKind.OutKeyword)
|
|
1902
1694
|
hasOut = true;
|
|
1903
|
-
if (mod.kind ===
|
|
1695
|
+
if (mod.kind === ts.SyntaxKind.ConstKeyword)
|
|
1904
1696
|
isConst = true;
|
|
1905
1697
|
}
|
|
1906
1698
|
const variance = hasIn && hasOut ? "inout" : hasIn ? "in" : hasOut ? "out" : undefined;
|
|
@@ -1922,7 +1714,7 @@ function extractTypeParameters(node, checker) {
|
|
|
1922
1714
|
const defType = checker.getTypeAtLocation(tp.default);
|
|
1923
1715
|
defaultType = checker.typeToString(defType);
|
|
1924
1716
|
}
|
|
1925
|
-
const { variance, isConst } = extractVarianceModifiers(
|
|
1717
|
+
const { variance, isConst } = extractVarianceModifiers(ts.getModifiers(tp));
|
|
1926
1718
|
return {
|
|
1927
1719
|
name,
|
|
1928
1720
|
...constraint ? { constraint } : {},
|
|
@@ -1943,7 +1735,7 @@ function isSymbolDeprecated(symbol) {
|
|
|
1943
1735
|
return { deprecated: true, reason };
|
|
1944
1736
|
}
|
|
1945
1737
|
for (const declaration of symbol.getDeclarations() ?? []) {
|
|
1946
|
-
const tag =
|
|
1738
|
+
const tag = ts.getJSDocDeprecatedTag(declaration);
|
|
1947
1739
|
if (tag) {
|
|
1948
1740
|
let reason;
|
|
1949
1741
|
if (typeof tag.comment === "string") {
|
|
@@ -1953,10 +1745,10 @@ function isSymbolDeprecated(symbol) {
|
|
|
1953
1745
|
}
|
|
1954
1746
|
return { deprecated: true, reason };
|
|
1955
1747
|
}
|
|
1956
|
-
if (
|
|
1748
|
+
if (ts.isExportSpecifier(declaration)) {
|
|
1957
1749
|
const exportDecl = declaration.parent?.parent;
|
|
1958
|
-
if (exportDecl &&
|
|
1959
|
-
const parentTag =
|
|
1750
|
+
if (exportDecl && ts.isExportDeclaration(exportDecl)) {
|
|
1751
|
+
const parentTag = ts.getJSDocDeprecatedTag(exportDecl);
|
|
1960
1752
|
if (parentTag) {
|
|
1961
1753
|
let reason;
|
|
1962
1754
|
if (typeof parentTag.comment === "string") {
|
|
@@ -2001,8 +1793,8 @@ function extractTypeParametersFromSignature(signature, checker) {
|
|
|
2001
1793
|
const tpSymbol = tp.getSymbol();
|
|
2002
1794
|
const declarations = tpSymbol?.getDeclarations() ?? [];
|
|
2003
1795
|
for (const decl of declarations) {
|
|
2004
|
-
if (
|
|
2005
|
-
({ variance, isConst } = extractVarianceModifiers(
|
|
1796
|
+
if (ts.isTypeParameterDeclaration(decl)) {
|
|
1797
|
+
({ variance, isConst } = extractVarianceModifiers(ts.getModifiers(decl)));
|
|
2006
1798
|
break;
|
|
2007
1799
|
}
|
|
2008
1800
|
}
|
|
@@ -2016,25 +1808,228 @@ function extractTypeParametersFromSignature(signature, checker) {
|
|
|
2016
1808
|
});
|
|
2017
1809
|
}
|
|
2018
1810
|
function getExportKind(declaration, type) {
|
|
2019
|
-
if (
|
|
1811
|
+
if (ts.isFunctionDeclaration(declaration) || ts.isFunctionExpression(declaration))
|
|
2020
1812
|
return "function";
|
|
2021
|
-
if (
|
|
1813
|
+
if (ts.isClassDeclaration(declaration))
|
|
2022
1814
|
return "class";
|
|
2023
|
-
if (
|
|
1815
|
+
if (ts.isInterfaceDeclaration(declaration))
|
|
2024
1816
|
return "interface";
|
|
2025
|
-
if (
|
|
1817
|
+
if (ts.isTypeAliasDeclaration(declaration))
|
|
2026
1818
|
return "type";
|
|
2027
|
-
if (
|
|
1819
|
+
if (ts.isEnumDeclaration(declaration))
|
|
2028
1820
|
return "enum";
|
|
2029
|
-
if (
|
|
1821
|
+
if (ts.isModuleDeclaration(declaration) || ts.isNamespaceExport(declaration))
|
|
2030
1822
|
return "namespace";
|
|
2031
|
-
if (
|
|
1823
|
+
if (ts.isVariableDeclaration(declaration) && type.getConstructSignatures().length > 0)
|
|
2032
1824
|
return "class";
|
|
2033
|
-
if (
|
|
1825
|
+
if (ts.isVariableDeclaration(declaration) && type.getCallSignatures().length > 0)
|
|
2034
1826
|
return "function";
|
|
2035
1827
|
return "variable";
|
|
2036
1828
|
}
|
|
2037
1829
|
|
|
1830
|
+
// src/compiler/program.ts
|
|
1831
|
+
import * as fs4 from "node:fs";
|
|
1832
|
+
import * as path3 from "node:path";
|
|
1833
|
+
import ts2 from "typescript";
|
|
1834
|
+
function isJsFile(file) {
|
|
1835
|
+
return /\.(js|mjs|cjs|jsx)$/.test(file);
|
|
1836
|
+
}
|
|
1837
|
+
function getScriptKind(file) {
|
|
1838
|
+
if (/\.tsx$/.test(file))
|
|
1839
|
+
return ts2.ScriptKind.TSX;
|
|
1840
|
+
if (/\.jsx$/.test(file))
|
|
1841
|
+
return ts2.ScriptKind.JSX;
|
|
1842
|
+
if (/\.(js|mjs|cjs)$/.test(file))
|
|
1843
|
+
return ts2.ScriptKind.JS;
|
|
1844
|
+
return ts2.ScriptKind.TS;
|
|
1845
|
+
}
|
|
1846
|
+
var DEFAULT_COMPILER_OPTIONS = {
|
|
1847
|
+
target: ts2.ScriptTarget.Latest,
|
|
1848
|
+
module: ts2.ModuleKind.CommonJS,
|
|
1849
|
+
lib: ["lib.es2021.d.ts"],
|
|
1850
|
+
declaration: true,
|
|
1851
|
+
moduleResolution: ts2.ModuleResolutionKind.NodeJs
|
|
1852
|
+
};
|
|
1853
|
+
function resolveProjectReferences(configPath, parsedConfig) {
|
|
1854
|
+
const additionalFiles = [];
|
|
1855
|
+
if (!parsedConfig.projectReferences?.length) {
|
|
1856
|
+
return additionalFiles;
|
|
1857
|
+
}
|
|
1858
|
+
const configDir = path3.dirname(configPath);
|
|
1859
|
+
for (const ref of parsedConfig.projectReferences) {
|
|
1860
|
+
const refPath = path3.resolve(configDir, ref.path);
|
|
1861
|
+
const refConfigPath = fs4.existsSync(path3.join(refPath, "tsconfig.json")) ? path3.join(refPath, "tsconfig.json") : refPath;
|
|
1862
|
+
if (!fs4.existsSync(refConfigPath))
|
|
1863
|
+
continue;
|
|
1864
|
+
const refConfigFile = ts2.readConfigFile(refConfigPath, ts2.sys.readFile);
|
|
1865
|
+
if (refConfigFile.error)
|
|
1866
|
+
continue;
|
|
1867
|
+
const refParsed = ts2.parseJsonConfigFileContent(refConfigFile.config, ts2.sys, path3.dirname(refConfigPath));
|
|
1868
|
+
additionalFiles.push(...refParsed.fileNames);
|
|
1869
|
+
}
|
|
1870
|
+
return additionalFiles;
|
|
1871
|
+
}
|
|
1872
|
+
function parsePnpmWorkspace(yamlContent) {
|
|
1873
|
+
const globs = [];
|
|
1874
|
+
const lines = yamlContent.split(`
|
|
1875
|
+
`);
|
|
1876
|
+
let inPackages = false;
|
|
1877
|
+
for (const line of lines) {
|
|
1878
|
+
const trimmed = line.trim();
|
|
1879
|
+
if (trimmed === "packages:") {
|
|
1880
|
+
inPackages = true;
|
|
1881
|
+
continue;
|
|
1882
|
+
}
|
|
1883
|
+
if (inPackages) {
|
|
1884
|
+
if (!line.startsWith(" ") && !line.startsWith("-") && trimmed) {
|
|
1885
|
+
break;
|
|
1886
|
+
}
|
|
1887
|
+
const match = trimmed.match(/^-\s*['"]?([^'"]+)['"]?$/);
|
|
1888
|
+
if (match) {
|
|
1889
|
+
globs.push(match[1]);
|
|
1890
|
+
}
|
|
1891
|
+
}
|
|
1892
|
+
}
|
|
1893
|
+
return globs;
|
|
1894
|
+
}
|
|
1895
|
+
function buildWorkspaceMap(baseDir) {
|
|
1896
|
+
let currentDir = baseDir;
|
|
1897
|
+
let rootDir;
|
|
1898
|
+
let workspaceGlobs = [];
|
|
1899
|
+
for (let i = 0;i < 10; i++) {
|
|
1900
|
+
const pnpmPath = path3.join(currentDir, "pnpm-workspace.yaml");
|
|
1901
|
+
if (fs4.existsSync(pnpmPath)) {
|
|
1902
|
+
try {
|
|
1903
|
+
const yamlContent = fs4.readFileSync(pnpmPath, "utf-8");
|
|
1904
|
+
workspaceGlobs = parsePnpmWorkspace(yamlContent);
|
|
1905
|
+
if (workspaceGlobs.length > 0) {
|
|
1906
|
+
rootDir = currentDir;
|
|
1907
|
+
break;
|
|
1908
|
+
}
|
|
1909
|
+
} catch {}
|
|
1910
|
+
}
|
|
1911
|
+
const pkgPath = path3.join(currentDir, "package.json");
|
|
1912
|
+
if (fs4.existsSync(pkgPath)) {
|
|
1913
|
+
try {
|
|
1914
|
+
const pkg = JSON.parse(fs4.readFileSync(pkgPath, "utf-8"));
|
|
1915
|
+
if (pkg.workspaces) {
|
|
1916
|
+
rootDir = currentDir;
|
|
1917
|
+
workspaceGlobs = Array.isArray(pkg.workspaces) ? pkg.workspaces : pkg.workspaces?.packages || [];
|
|
1918
|
+
break;
|
|
1919
|
+
}
|
|
1920
|
+
} catch {}
|
|
1921
|
+
}
|
|
1922
|
+
const parent = path3.dirname(currentDir);
|
|
1923
|
+
if (parent === currentDir)
|
|
1924
|
+
break;
|
|
1925
|
+
currentDir = parent;
|
|
1926
|
+
}
|
|
1927
|
+
if (!rootDir || workspaceGlobs.length === 0)
|
|
1928
|
+
return;
|
|
1929
|
+
const packages = new Map;
|
|
1930
|
+
for (const glob of workspaceGlobs) {
|
|
1931
|
+
const globDir = path3.join(rootDir, glob.replace(/\/\*$/, ""));
|
|
1932
|
+
if (!fs4.existsSync(globDir) || !fs4.statSync(globDir).isDirectory())
|
|
1933
|
+
continue;
|
|
1934
|
+
const entries = fs4.readdirSync(globDir, { withFileTypes: true });
|
|
1935
|
+
for (const entry of entries) {
|
|
1936
|
+
if (!entry.isDirectory())
|
|
1937
|
+
continue;
|
|
1938
|
+
const pkgDir = path3.join(globDir, entry.name);
|
|
1939
|
+
const pkgJsonPath = path3.join(pkgDir, "package.json");
|
|
1940
|
+
if (!fs4.existsSync(pkgJsonPath))
|
|
1941
|
+
continue;
|
|
1942
|
+
try {
|
|
1943
|
+
const pkg = JSON.parse(fs4.readFileSync(pkgJsonPath, "utf-8"));
|
|
1944
|
+
if (pkg.name) {
|
|
1945
|
+
const srcDir = fs4.existsSync(path3.join(pkgDir, "src")) ? path3.join(pkgDir, "src") : pkgDir;
|
|
1946
|
+
packages.set(pkg.name, srcDir);
|
|
1947
|
+
}
|
|
1948
|
+
} catch {}
|
|
1949
|
+
}
|
|
1950
|
+
}
|
|
1951
|
+
return packages.size > 0 ? { packages, rootDir } : undefined;
|
|
1952
|
+
}
|
|
1953
|
+
function createProgram({
|
|
1954
|
+
entryFile,
|
|
1955
|
+
baseDir = path3.dirname(entryFile),
|
|
1956
|
+
content
|
|
1957
|
+
}) {
|
|
1958
|
+
let configPath = ts2.findConfigFile(baseDir, ts2.sys.fileExists, "tsconfig.json");
|
|
1959
|
+
if (!configPath) {
|
|
1960
|
+
configPath = ts2.findConfigFile(baseDir, ts2.sys.fileExists, "jsconfig.json");
|
|
1961
|
+
}
|
|
1962
|
+
let compilerOptions = { ...DEFAULT_COMPILER_OPTIONS };
|
|
1963
|
+
let additionalRootFiles = [];
|
|
1964
|
+
if (configPath) {
|
|
1965
|
+
const configFile = ts2.readConfigFile(configPath, ts2.sys.readFile);
|
|
1966
|
+
const parsedConfig = ts2.parseJsonConfigFileContent(configFile.config, ts2.sys, path3.dirname(configPath));
|
|
1967
|
+
compilerOptions = { ...compilerOptions, ...parsedConfig.options };
|
|
1968
|
+
additionalRootFiles = resolveProjectReferences(configPath, parsedConfig);
|
|
1969
|
+
const sourceFiles = parsedConfig.fileNames.filter((f) => !f.includes(".test.") && !f.includes(".spec.") && !f.includes("/dist/") && !f.includes("/node_modules/"));
|
|
1970
|
+
additionalRootFiles.push(...sourceFiles);
|
|
1971
|
+
}
|
|
1972
|
+
if (isJsFile(entryFile)) {
|
|
1973
|
+
compilerOptions = {
|
|
1974
|
+
...compilerOptions,
|
|
1975
|
+
allowJs: true,
|
|
1976
|
+
checkJs: true,
|
|
1977
|
+
isolatedDeclarations: false
|
|
1978
|
+
};
|
|
1979
|
+
} else {
|
|
1980
|
+
const allowJsVal = compilerOptions.allowJs;
|
|
1981
|
+
if (typeof allowJsVal === "boolean" && allowJsVal) {
|
|
1982
|
+
compilerOptions = { ...compilerOptions, allowJs: false, checkJs: false };
|
|
1983
|
+
}
|
|
1984
|
+
}
|
|
1985
|
+
const workspaceMap = buildWorkspaceMap(baseDir);
|
|
1986
|
+
const compilerHost = ts2.createCompilerHost(compilerOptions, true);
|
|
1987
|
+
let inMemorySource;
|
|
1988
|
+
if (workspaceMap) {
|
|
1989
|
+
const originalResolveModuleNames = compilerHost.resolveModuleNames?.bind(compilerHost);
|
|
1990
|
+
compilerHost.resolveModuleNames = (moduleNames, containingFile, _reusedNames, redirectedReference, options) => {
|
|
1991
|
+
return moduleNames.map((moduleName) => {
|
|
1992
|
+
const srcDir = workspaceMap.packages.get(moduleName);
|
|
1993
|
+
if (srcDir) {
|
|
1994
|
+
const indexFile = path3.join(srcDir, "index.ts");
|
|
1995
|
+
if (fs4.existsSync(indexFile)) {
|
|
1996
|
+
return { resolvedFileName: indexFile, isExternalLibraryImport: false };
|
|
1997
|
+
}
|
|
1998
|
+
}
|
|
1999
|
+
if (originalResolveModuleNames) {
|
|
2000
|
+
const result = originalResolveModuleNames([moduleName], containingFile, _reusedNames, redirectedReference, options);
|
|
2001
|
+
return result[0];
|
|
2002
|
+
}
|
|
2003
|
+
const resolved = ts2.resolveModuleName(moduleName, containingFile, options, compilerHost);
|
|
2004
|
+
return resolved.resolvedModule;
|
|
2005
|
+
});
|
|
2006
|
+
};
|
|
2007
|
+
}
|
|
2008
|
+
if (content !== undefined) {
|
|
2009
|
+
inMemorySource = ts2.createSourceFile(entryFile, content, ts2.ScriptTarget.Latest, true, getScriptKind(entryFile));
|
|
2010
|
+
const originalGetSourceFile = compilerHost.getSourceFile.bind(compilerHost);
|
|
2011
|
+
compilerHost.getSourceFile = (fileName, languageVersion, onError, shouldCreateNewSourceFile) => {
|
|
2012
|
+
if (fileName === entryFile) {
|
|
2013
|
+
return inMemorySource;
|
|
2014
|
+
}
|
|
2015
|
+
return originalGetSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile);
|
|
2016
|
+
};
|
|
2017
|
+
}
|
|
2018
|
+
const rootFiles = [entryFile, ...additionalRootFiles];
|
|
2019
|
+
const program = ts2.createProgram(rootFiles, compilerOptions, compilerHost);
|
|
2020
|
+
const sourceFile = inMemorySource ?? program.getSourceFile(entryFile);
|
|
2021
|
+
return {
|
|
2022
|
+
program,
|
|
2023
|
+
compilerHost,
|
|
2024
|
+
compilerOptions,
|
|
2025
|
+
sourceFile,
|
|
2026
|
+
configPath
|
|
2027
|
+
};
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2030
|
+
// src/serializers/classes.ts
|
|
2031
|
+
import ts7 from "typescript";
|
|
2032
|
+
|
|
2038
2033
|
// src/types/parameters.ts
|
|
2039
2034
|
import ts4 from "typescript";
|
|
2040
2035
|
|
|
@@ -2595,7 +2590,7 @@ function buildSchemaInternal(type, checker, ctx) {
|
|
|
2595
2590
|
return { type: checker.typeToString(type) };
|
|
2596
2591
|
} finally {
|
|
2597
2592
|
if (addedToVisited) {
|
|
2598
|
-
ctx
|
|
2593
|
+
ctx?.visitedTypes.delete(type);
|
|
2599
2594
|
}
|
|
2600
2595
|
}
|
|
2601
2596
|
}
|
|
@@ -4647,12 +4642,20 @@ async function getExport(options) {
|
|
|
4647
4642
|
const result = createProgram({ entryFile, baseDir, content });
|
|
4648
4643
|
const { program, sourceFile } = result;
|
|
4649
4644
|
if (!sourceFile) {
|
|
4650
|
-
return {
|
|
4645
|
+
return {
|
|
4646
|
+
export: null,
|
|
4647
|
+
types: [],
|
|
4648
|
+
errors: [`Entry file not found: ${entryFile}. Specify with: drift get src/index.ts <name>`]
|
|
4649
|
+
};
|
|
4651
4650
|
}
|
|
4652
4651
|
const checker = program.getTypeChecker();
|
|
4653
4652
|
const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
|
|
4654
4653
|
if (!moduleSymbol) {
|
|
4655
|
-
return {
|
|
4654
|
+
return {
|
|
4655
|
+
export: null,
|
|
4656
|
+
types: [],
|
|
4657
|
+
errors: [`No exports found in ${entryFile}. Is this the right entry point?`]
|
|
4658
|
+
};
|
|
4656
4659
|
}
|
|
4657
4660
|
const exportedSymbols = checker.getExportsOfModule(moduleSymbol);
|
|
4658
4661
|
const targetSymbol = exportedSymbols.find((s) => s.getName() === exportName);
|
|
@@ -4671,7 +4674,11 @@ async function getExport(options) {
|
|
|
4671
4674
|
if (isNamespaceExportDecl) {
|
|
4672
4675
|
const spec2 = serializeNamespaceForGet(targetSymbol, exportName, ctx);
|
|
4673
4676
|
const types2 = ctx.typeRegistry.getAll().map((t) => normalizeType(t, { dialect: "draft-2020-12" }));
|
|
4674
|
-
return {
|
|
4677
|
+
return {
|
|
4678
|
+
export: normalizeExport(spec2, { dialect: "draft-2020-12" }),
|
|
4679
|
+
types: types2,
|
|
4680
|
+
errors
|
|
4681
|
+
};
|
|
4675
4682
|
}
|
|
4676
4683
|
const { declaration, resolvedSymbol, isTypeOnly } = resolveExportTarget(targetSymbol, checker);
|
|
4677
4684
|
if (!declaration) {
|
|
@@ -4845,12 +4852,18 @@ async function listExports(options) {
|
|
|
4845
4852
|
const result = createProgram({ entryFile, baseDir, content });
|
|
4846
4853
|
const { program, sourceFile } = result;
|
|
4847
4854
|
if (!sourceFile) {
|
|
4848
|
-
return {
|
|
4855
|
+
return {
|
|
4856
|
+
exports: [],
|
|
4857
|
+
errors: [`Entry file not found: ${entryFile}. Specify with: drift list src/index.ts`]
|
|
4858
|
+
};
|
|
4849
4859
|
}
|
|
4850
4860
|
const checker = program.getTypeChecker();
|
|
4851
4861
|
const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
|
|
4852
4862
|
if (!moduleSymbol) {
|
|
4853
|
-
return {
|
|
4863
|
+
return {
|
|
4864
|
+
exports: [],
|
|
4865
|
+
errors: [`No exports found in ${entryFile}. Is this the right entry point?`]
|
|
4866
|
+
};
|
|
4854
4867
|
}
|
|
4855
4868
|
const exportedSymbols = checker.getExportsOfModule(moduleSymbol);
|
|
4856
4869
|
for (const symbol of exportedSymbols) {
|
|
@@ -6056,7 +6069,12 @@ async function extract(options) {
|
|
|
6056
6069
|
if (!sourceFile) {
|
|
6057
6070
|
return {
|
|
6058
6071
|
spec: createEmptySpec(entryFile, includeSchema, isDtsSource),
|
|
6059
|
-
diagnostics: [
|
|
6072
|
+
diagnostics: [
|
|
6073
|
+
{
|
|
6074
|
+
message: `Entry file not found: ${entryFile}. Specify with: drift list src/index.ts`,
|
|
6075
|
+
severity: "error"
|
|
6076
|
+
}
|
|
6077
|
+
]
|
|
6060
6078
|
};
|
|
6061
6079
|
}
|
|
6062
6080
|
const typeChecker = program.getTypeChecker();
|
|
@@ -6064,7 +6082,12 @@ async function extract(options) {
|
|
|
6064
6082
|
if (!moduleSymbol) {
|
|
6065
6083
|
return {
|
|
6066
6084
|
spec: createEmptySpec(entryFile, includeSchema, isDtsSource),
|
|
6067
|
-
diagnostics: [
|
|
6085
|
+
diagnostics: [
|
|
6086
|
+
{
|
|
6087
|
+
message: `No exports found in ${entryFile}. Is this the right entry point?`,
|
|
6088
|
+
severity: "warning"
|
|
6089
|
+
}
|
|
6090
|
+
]
|
|
6068
6091
|
};
|
|
6069
6092
|
}
|
|
6070
6093
|
const exportedSymbols = typeChecker.getExportsOfModule(moduleSymbol);
|
|
@@ -347,6 +347,7 @@ function filterExports(spec, names) {
|
|
|
347
347
|
}
|
|
348
348
|
|
|
349
349
|
// src/core/search.ts
|
|
350
|
+
import { KIND_LABELS } from "@openpkg-ts/spec";
|
|
350
351
|
var defaultSlugify = (name) => name.toLowerCase().replace(/[^a-z0-9]+/g, "-");
|
|
351
352
|
function extractKeywords(exp, options = {}) {
|
|
352
353
|
const keywords = new Set;
|
|
@@ -501,7 +502,7 @@ function toAlgoliaRecords(spec, options = {}) {
|
|
|
501
502
|
url: `${baseUrl}/${slugify(exp.name)}`,
|
|
502
503
|
hierarchy: {
|
|
503
504
|
lvl0: spec.meta.name,
|
|
504
|
-
lvl1:
|
|
505
|
+
lvl1: KIND_LABELS[exp.kind],
|
|
505
506
|
lvl2: exp.name
|
|
506
507
|
}
|
|
507
508
|
}));
|