@ox-content/vite-plugin 2.4.0 → 2.6.0
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/index.cjs +359 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +17 -4
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +17 -4
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +359 -39
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -7377,6 +7377,32 @@ export const ${exportName}: NavItem[] = ${JSON.stringify(navItems, null, 2)} as
|
|
|
7377
7377
|
*/
|
|
7378
7378
|
const DOCS_MANIFEST_FILE = ".ox-content-docs-manifest.json";
|
|
7379
7379
|
const DOCS_DATA_FILE = "docs.json";
|
|
7380
|
+
const DOC_KIND_ORDER = [
|
|
7381
|
+
"function",
|
|
7382
|
+
"class",
|
|
7383
|
+
"interface",
|
|
7384
|
+
"type",
|
|
7385
|
+
"variable",
|
|
7386
|
+
"module"
|
|
7387
|
+
];
|
|
7388
|
+
const DOC_KIND_PLURAL = {
|
|
7389
|
+
function: "functions",
|
|
7390
|
+
class: "classes",
|
|
7391
|
+
interface: "interfaces",
|
|
7392
|
+
type: "types",
|
|
7393
|
+
variable: "variables",
|
|
7394
|
+
module: "modules"
|
|
7395
|
+
};
|
|
7396
|
+
const DEFAULT_DOCS_INCLUDE = [
|
|
7397
|
+
"**/*.ts",
|
|
7398
|
+
"**/*.tsx",
|
|
7399
|
+
"**/*.js",
|
|
7400
|
+
"**/*.jsx",
|
|
7401
|
+
"**/*.mts",
|
|
7402
|
+
"**/*.mjs",
|
|
7403
|
+
"**/*.cts",
|
|
7404
|
+
"**/*.cjs"
|
|
7405
|
+
];
|
|
7380
7406
|
function escapeHtml$3(str) {
|
|
7381
7407
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
7382
7408
|
}
|
|
@@ -7385,7 +7411,7 @@ function entryAnchor(name) {
|
|
|
7385
7411
|
}
|
|
7386
7412
|
function cleanSummaryText(text, maxLength = 120) {
|
|
7387
7413
|
if (!text) return "";
|
|
7388
|
-
const collapsed = text.replace(/\s+/g, " ").trim();
|
|
7414
|
+
const collapsed = text.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/\[([^\]]+)\]/g, "$1").replace(/\s+/g, " ").trim();
|
|
7389
7415
|
if (collapsed.length <= maxLength) return collapsed;
|
|
7390
7416
|
return `${collapsed.slice(0, maxLength - 1).trimEnd()}…`;
|
|
7391
7417
|
}
|
|
@@ -7523,6 +7549,86 @@ function renderDetailsControlsHtml(targetSelector) {
|
|
|
7523
7549
|
<button type="button" class="ox-api-controls__button" data-ox-api-toggle="collapse">Close all</button>
|
|
7524
7550
|
</div>`;
|
|
7525
7551
|
}
|
|
7552
|
+
function createEmptyEntryStats() {
|
|
7553
|
+
return {
|
|
7554
|
+
entries: 0,
|
|
7555
|
+
byKind: {},
|
|
7556
|
+
params: 0,
|
|
7557
|
+
returns: 0,
|
|
7558
|
+
examples: 0,
|
|
7559
|
+
deprecated: 0
|
|
7560
|
+
};
|
|
7561
|
+
}
|
|
7562
|
+
function summarizeEntries(entries) {
|
|
7563
|
+
const stats = createEmptyEntryStats();
|
|
7564
|
+
for (const entry of entries) {
|
|
7565
|
+
stats.entries++;
|
|
7566
|
+
stats.byKind[entry.kind] = (stats.byKind[entry.kind] ?? 0) + 1;
|
|
7567
|
+
stats.params += entry.params?.length ?? 0;
|
|
7568
|
+
stats.returns += entry.returns ? 1 : 0;
|
|
7569
|
+
stats.examples += entry.examples?.length ?? 0;
|
|
7570
|
+
stats.deprecated += entry.tags?.deprecated !== void 0 ? 1 : 0;
|
|
7571
|
+
}
|
|
7572
|
+
return stats;
|
|
7573
|
+
}
|
|
7574
|
+
function buildDocsSummary(docs) {
|
|
7575
|
+
const stats = summarizeEntries(docs.flatMap((doc) => doc.entries));
|
|
7576
|
+
const byKind = {};
|
|
7577
|
+
for (const kind of DOC_KIND_ORDER) {
|
|
7578
|
+
const count = stats.byKind[kind];
|
|
7579
|
+
if (count) byKind[kind] = count;
|
|
7580
|
+
}
|
|
7581
|
+
return {
|
|
7582
|
+
modules: docs.length,
|
|
7583
|
+
entries: stats.entries,
|
|
7584
|
+
byKind,
|
|
7585
|
+
params: stats.params,
|
|
7586
|
+
returns: stats.returns,
|
|
7587
|
+
examples: stats.examples,
|
|
7588
|
+
deprecated: stats.deprecated
|
|
7589
|
+
};
|
|
7590
|
+
}
|
|
7591
|
+
function renderStatsHtml(stats, moduleCount) {
|
|
7592
|
+
const items = [];
|
|
7593
|
+
if (moduleCount !== void 0) items.push({
|
|
7594
|
+
label: "modules",
|
|
7595
|
+
value: moduleCount
|
|
7596
|
+
});
|
|
7597
|
+
items.push({
|
|
7598
|
+
label: "symbols",
|
|
7599
|
+
value: stats.entries
|
|
7600
|
+
});
|
|
7601
|
+
for (const kind of DOC_KIND_ORDER) {
|
|
7602
|
+
const count = stats.byKind[kind];
|
|
7603
|
+
if (count) items.push({
|
|
7604
|
+
label: DOC_KIND_PLURAL[kind],
|
|
7605
|
+
value: count
|
|
7606
|
+
});
|
|
7607
|
+
}
|
|
7608
|
+
if (stats.params) items.push({
|
|
7609
|
+
label: "parameters",
|
|
7610
|
+
value: stats.params
|
|
7611
|
+
});
|
|
7612
|
+
if (stats.returns) items.push({
|
|
7613
|
+
label: "returns",
|
|
7614
|
+
value: stats.returns
|
|
7615
|
+
});
|
|
7616
|
+
if (stats.examples) items.push({
|
|
7617
|
+
label: "examples",
|
|
7618
|
+
value: stats.examples
|
|
7619
|
+
});
|
|
7620
|
+
if (stats.deprecated) items.push({
|
|
7621
|
+
label: "deprecated",
|
|
7622
|
+
value: stats.deprecated,
|
|
7623
|
+
tone: "warning"
|
|
7624
|
+
});
|
|
7625
|
+
return `<div class="ox-api-stats" aria-label="API reference summary">
|
|
7626
|
+
${items.map((item) => `<span class="ox-api-stat${item.tone ? ` ox-api-stat--${item.tone}` : ""}">
|
|
7627
|
+
<strong>${item.value}</strong>
|
|
7628
|
+
<span>${escapeHtml$3(item.label)}</span>
|
|
7629
|
+
</span>`).join("\n")}
|
|
7630
|
+
</div>`;
|
|
7631
|
+
}
|
|
7526
7632
|
function normalizeDocFilePath(filePath) {
|
|
7527
7633
|
const normalized = filePath.replace(/\\/g, "/");
|
|
7528
7634
|
return normalized.match(/(?:^|\/)((?:npm|packages|crates|src)\/.+)$/)?.[1] ?? normalized.replace(/^\/+/, "");
|
|
@@ -7531,6 +7637,7 @@ function buildDocsData(docs) {
|
|
|
7531
7637
|
return {
|
|
7532
7638
|
version: 1,
|
|
7533
7639
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7640
|
+
summary: buildDocsSummary(docs),
|
|
7534
7641
|
modules: docs.map((doc) => ({
|
|
7535
7642
|
...doc,
|
|
7536
7643
|
file: normalizeDocFilePath(doc.file),
|
|
@@ -7541,6 +7648,86 @@ function buildDocsData(docs) {
|
|
|
7541
7648
|
}))
|
|
7542
7649
|
};
|
|
7543
7650
|
}
|
|
7651
|
+
function consumeJSDocType(value) {
|
|
7652
|
+
const trimmed = value.trimStart();
|
|
7653
|
+
if (!trimmed.startsWith("{")) return { rest: trimmed };
|
|
7654
|
+
let depth = 0;
|
|
7655
|
+
for (let index = 0; index < trimmed.length; index++) {
|
|
7656
|
+
const char = trimmed[index];
|
|
7657
|
+
if (char === "{") depth++;
|
|
7658
|
+
else if (char === "}") {
|
|
7659
|
+
depth--;
|
|
7660
|
+
if (depth === 0) return {
|
|
7661
|
+
type: trimmed.slice(1, index).trim() || void 0,
|
|
7662
|
+
rest: trimmed.slice(index + 1).trimStart()
|
|
7663
|
+
};
|
|
7664
|
+
}
|
|
7665
|
+
}
|
|
7666
|
+
return { rest: trimmed };
|
|
7667
|
+
}
|
|
7668
|
+
function cleanTagDescription(value) {
|
|
7669
|
+
return value.trim().replace(/^-\s*/, "").trim();
|
|
7670
|
+
}
|
|
7671
|
+
function splitTagNameAndDescription(value) {
|
|
7672
|
+
const trimmed = value.trimStart();
|
|
7673
|
+
if (trimmed.startsWith("[")) {
|
|
7674
|
+
const closeIndex = trimmed.indexOf("]");
|
|
7675
|
+
if (closeIndex >= 0) return {
|
|
7676
|
+
name: trimmed.slice(0, closeIndex + 1),
|
|
7677
|
+
description: trimmed.slice(closeIndex + 1).trimStart()
|
|
7678
|
+
};
|
|
7679
|
+
}
|
|
7680
|
+
const match = /^(\S+)(?:\s+([\s\S]*))?$/u.exec(trimmed);
|
|
7681
|
+
return {
|
|
7682
|
+
name: match?.[1] ?? "",
|
|
7683
|
+
description: match?.[2] ?? ""
|
|
7684
|
+
};
|
|
7685
|
+
}
|
|
7686
|
+
function parseParamTagValue(value) {
|
|
7687
|
+
const { type, rest } = consumeJSDocType(value);
|
|
7688
|
+
const { name: rawName, description } = splitTagNameAndDescription(rest);
|
|
7689
|
+
let name = rawName.trim();
|
|
7690
|
+
if (!name) return null;
|
|
7691
|
+
let optional = false;
|
|
7692
|
+
let defaultValue;
|
|
7693
|
+
const optionalMatch = /^\[(.*)\]$/u.exec(name);
|
|
7694
|
+
if (optionalMatch) {
|
|
7695
|
+
optional = true;
|
|
7696
|
+
const [innerName, innerDefault] = optionalMatch[1].split(/=(.*)/su);
|
|
7697
|
+
name = innerName.trim();
|
|
7698
|
+
defaultValue = innerDefault?.trim() || void 0;
|
|
7699
|
+
}
|
|
7700
|
+
if (!name) return null;
|
|
7701
|
+
return {
|
|
7702
|
+
name,
|
|
7703
|
+
type: type || "unknown",
|
|
7704
|
+
description: cleanTagDescription(description),
|
|
7705
|
+
optional: optional || void 0,
|
|
7706
|
+
default: defaultValue
|
|
7707
|
+
};
|
|
7708
|
+
}
|
|
7709
|
+
function parseReturnsTagValue(value) {
|
|
7710
|
+
const { type, rest } = consumeJSDocType(value);
|
|
7711
|
+
return {
|
|
7712
|
+
type: type || "unknown",
|
|
7713
|
+
description: cleanTagDescription(rest)
|
|
7714
|
+
};
|
|
7715
|
+
}
|
|
7716
|
+
function normalizeReturnType(value) {
|
|
7717
|
+
const parsed = parseReturnsTagValue(value);
|
|
7718
|
+
return parsed.type === "unknown" ? value : parsed.type;
|
|
7719
|
+
}
|
|
7720
|
+
function mergeParam(params, next) {
|
|
7721
|
+
const existing = params.find((param) => param.name === next.name);
|
|
7722
|
+
if (!existing) {
|
|
7723
|
+
params.push(next);
|
|
7724
|
+
return;
|
|
7725
|
+
}
|
|
7726
|
+
if (next.type && (existing.type === "unknown" || next.type !== "unknown")) existing.type = next.type;
|
|
7727
|
+
if (next.description) existing.description = next.description;
|
|
7728
|
+
if (next.optional) existing.optional = true;
|
|
7729
|
+
if (next.default) existing.default = next.default;
|
|
7730
|
+
}
|
|
7544
7731
|
/**
|
|
7545
7732
|
* Extracts JSDoc documentation from source files in specified directories.
|
|
7546
7733
|
*
|
|
@@ -7552,7 +7739,7 @@ function buildDocsData(docs) {
|
|
|
7552
7739
|
*
|
|
7553
7740
|
* 1. **File Discovery**: Recursively walks directories, applying filters
|
|
7554
7741
|
* 2. **File Reading**: Loads each matching file's content
|
|
7555
|
-
* 3. **JSDoc Extraction**: Parses JSDoc comments using
|
|
7742
|
+
* 3. **JSDoc Extraction**: Parses JSDoc comments using the native parser
|
|
7556
7743
|
* 4. **Declaration Matching**: Pairs JSDoc comments with source declarations
|
|
7557
7744
|
* 5. **Result Collection**: Aggregates extracted documentation by file
|
|
7558
7745
|
*
|
|
@@ -7692,32 +7879,29 @@ function parseNapiDocItem(item) {
|
|
|
7692
7879
|
currentExample = "";
|
|
7693
7880
|
inExample = false;
|
|
7694
7881
|
}
|
|
7695
|
-
const tagMatch =
|
|
7882
|
+
const tagMatch = /^@(\S+)\s*([\s\S]*)$/u.exec(lineText);
|
|
7696
7883
|
if (tagMatch) {
|
|
7697
|
-
const [, tagName,
|
|
7884
|
+
const [, tagName, tagValue = ""] = tagMatch;
|
|
7698
7885
|
switch (tagName) {
|
|
7699
7886
|
case "param":
|
|
7700
|
-
|
|
7701
|
-
|
|
7702
|
-
|
|
7703
|
-
|
|
7704
|
-
description: paramMatch[2]
|
|
7705
|
-
});
|
|
7887
|
+
case "arg":
|
|
7888
|
+
case "argument": {
|
|
7889
|
+
const param = parseParamTagValue(tagValue);
|
|
7890
|
+
if (param) mergeParam(params, param);
|
|
7706
7891
|
break;
|
|
7892
|
+
}
|
|
7707
7893
|
case "returns":
|
|
7708
7894
|
case "return":
|
|
7709
|
-
returns =
|
|
7710
|
-
type: tagType || "unknown",
|
|
7711
|
-
description: tagRest.trim()
|
|
7712
|
-
};
|
|
7895
|
+
returns = parseReturnsTagValue(tagValue);
|
|
7713
7896
|
break;
|
|
7714
7897
|
case "example":
|
|
7715
7898
|
inExample = true;
|
|
7899
|
+
currentExample = tagValue.trim() ? `${tagValue.trim()}\n` : "";
|
|
7716
7900
|
break;
|
|
7717
7901
|
case "private":
|
|
7718
7902
|
isPrivate = true;
|
|
7719
7903
|
break;
|
|
7720
|
-
default: tags[tagName] =
|
|
7904
|
+
default: tags[tagName] = tagValue.trim();
|
|
7721
7905
|
}
|
|
7722
7906
|
}
|
|
7723
7907
|
} else if (inExample) currentExample += rawLine + "\n";
|
|
@@ -7725,32 +7909,41 @@ function parseNapiDocItem(item) {
|
|
|
7725
7909
|
else description += "\n" + lineText;
|
|
7726
7910
|
}
|
|
7727
7911
|
if (inExample && currentExample) examples.push(currentExample.trim());
|
|
7728
|
-
|
|
7729
|
-
name
|
|
7730
|
-
|
|
7731
|
-
|
|
7732
|
-
|
|
7733
|
-
|
|
7734
|
-
|
|
7735
|
-
|
|
7736
|
-
|
|
7737
|
-
for (const param of params) {
|
|
7738
|
-
const rustParam = paramMap.get(param.name);
|
|
7739
|
-
if (!rustParam) continue;
|
|
7740
|
-
if (param.type === "unknown" && rustParam.typeAnnotation) param.type = rustParam.typeAnnotation;
|
|
7741
|
-
if (!param.description && rustParam.description) param.description = rustParam.description;
|
|
7742
|
-
if (param.optional === void 0 && rustParam.optional) param.optional = true;
|
|
7743
|
-
if (!param.default && rustParam.defaultValue) param.default = rustParam.defaultValue;
|
|
7744
|
-
}
|
|
7912
|
+
for (const param of item.params) {
|
|
7913
|
+
if (params.length > 0 && param.name === "param" && !param.typeAnnotation && !param.description && !param.defaultValue) continue;
|
|
7914
|
+
mergeParam(params, {
|
|
7915
|
+
name: param.name,
|
|
7916
|
+
type: param.typeAnnotation ?? "unknown",
|
|
7917
|
+
description: param.description ?? "",
|
|
7918
|
+
optional: param.optional || void 0,
|
|
7919
|
+
default: param.defaultValue
|
|
7920
|
+
});
|
|
7745
7921
|
}
|
|
7746
7922
|
if (!returns && item.returnType) returns = {
|
|
7747
|
-
type: item.returnType,
|
|
7923
|
+
type: normalizeReturnType(item.returnType),
|
|
7748
7924
|
description: ""
|
|
7749
7925
|
};
|
|
7750
|
-
else if (returns &&
|
|
7926
|
+
else if (returns && item.returnType) returns.type = normalizeReturnType(item.returnType);
|
|
7751
7927
|
if (!description) description = item.doc ?? "";
|
|
7752
7928
|
for (const tag of item.tags) {
|
|
7753
|
-
if (tag.tag === "param" || tag.tag === "
|
|
7929
|
+
if (tag.tag === "param" || tag.tag === "arg" || tag.tag === "argument" || tag.tag === "returns" || tag.tag === "return") {
|
|
7930
|
+
if (tag.tag === "param" || tag.tag === "arg" || tag.tag === "argument") {
|
|
7931
|
+
const param = parseParamTagValue(tag.value);
|
|
7932
|
+
if (param) mergeParam(params, param);
|
|
7933
|
+
} else {
|
|
7934
|
+
const parsedReturns = parseReturnsTagValue(tag.value);
|
|
7935
|
+
if (!returns) returns = parsedReturns;
|
|
7936
|
+
else {
|
|
7937
|
+
returns.type = returns.type === "unknown" ? parsedReturns.type : returns.type;
|
|
7938
|
+
returns.description ||= parsedReturns.description;
|
|
7939
|
+
}
|
|
7940
|
+
}
|
|
7941
|
+
continue;
|
|
7942
|
+
}
|
|
7943
|
+
if (tag.tag === "example") {
|
|
7944
|
+
if (tag.value && !examples.includes(tag.value)) examples.push(tag.value);
|
|
7945
|
+
continue;
|
|
7946
|
+
}
|
|
7754
7947
|
if (tag.tag === "private") {
|
|
7755
7948
|
isPrivate = true;
|
|
7756
7949
|
continue;
|
|
@@ -7837,6 +8030,7 @@ function generateFileMarkdown(doc, options, currentFileName, symbolMap) {
|
|
|
7837
8030
|
}
|
|
7838
8031
|
md += `> ${doc.entries.length} documented symbol${doc.entries.length === 1 ? "" : "s"}. `;
|
|
7839
8032
|
md += "Read the signatures first, then expand each item for parameters, return types, and examples.\n\n";
|
|
8033
|
+
md += renderStatsHtml(summarizeEntries(doc.entries)) + "\n\n";
|
|
7840
8034
|
md += "## Reference\n\n";
|
|
7841
8035
|
if (doc.entries.length > 1) md += renderDetailsControlsHtml(".ox-api-entry") + "\n\n";
|
|
7842
8036
|
for (const entry of doc.entries) md += generateEntryMarkdown(entry, options, currentFileName, symbolMap);
|
|
@@ -7856,6 +8050,42 @@ function formatKindLabel(kind) {
|
|
|
7856
8050
|
default: return kind;
|
|
7857
8051
|
}
|
|
7858
8052
|
}
|
|
8053
|
+
function formatCountLabel(count, singular, plural = `${singular}s`) {
|
|
8054
|
+
return `${count} ${count === 1 ? singular : plural}`;
|
|
8055
|
+
}
|
|
8056
|
+
function getEntryBadges(entry) {
|
|
8057
|
+
const badges = [];
|
|
8058
|
+
if (entry.tags?.deprecated !== void 0) badges.push({
|
|
8059
|
+
label: "deprecated",
|
|
8060
|
+
tone: "warning"
|
|
8061
|
+
});
|
|
8062
|
+
if (entry.params?.length) badges.push({ label: formatCountLabel(entry.params.length, "param") });
|
|
8063
|
+
if (entry.returns) badges.push({ label: `returns ${entry.returns.type}` });
|
|
8064
|
+
if (entry.examples?.length) badges.push({ label: formatCountLabel(entry.examples.length, "example") });
|
|
8065
|
+
if (entry.tags?.since) badges.push({ label: `since ${entry.tags.since}` });
|
|
8066
|
+
if (entry.private) badges.push({
|
|
8067
|
+
label: "private",
|
|
8068
|
+
tone: "warning"
|
|
8069
|
+
});
|
|
8070
|
+
return badges;
|
|
8071
|
+
}
|
|
8072
|
+
function renderEntryBadgesHtml(entry, className) {
|
|
8073
|
+
const badges = getEntryBadges(entry);
|
|
8074
|
+
if (badges.length === 0) return "";
|
|
8075
|
+
return `<span class="${className}">${badges.map((badge) => `<span class="ox-api-badge${badge.tone ? ` ox-api-badge--${badge.tone}` : ""}">${escapeHtml$3(badge.label)}</span>`).join("")}</span>`;
|
|
8076
|
+
}
|
|
8077
|
+
function parseExampleBlock(example) {
|
|
8078
|
+
const trimmed = example.trim();
|
|
8079
|
+
const fenceMatch = /^```([\w-]+)?[^\n]*\n([\s\S]*?)\n?```$/u.exec(trimmed);
|
|
8080
|
+
if (!fenceMatch) return {
|
|
8081
|
+
code: trimmed,
|
|
8082
|
+
language: "ts"
|
|
8083
|
+
};
|
|
8084
|
+
return {
|
|
8085
|
+
code: fenceMatch[2],
|
|
8086
|
+
language: fenceMatch[1] || "ts"
|
|
8087
|
+
};
|
|
8088
|
+
}
|
|
7859
8089
|
function renderOverviewLine(entry, href) {
|
|
7860
8090
|
const signature = normalizeSignature(entry.signature);
|
|
7861
8091
|
const summary = cleanSummaryText(entry.description, 88);
|
|
@@ -7867,8 +8097,9 @@ function renderOverviewLine(entry, href) {
|
|
|
7867
8097
|
function renderOverviewHtmlItem(entry, href) {
|
|
7868
8098
|
const signature = normalizeSignature(entry.signature);
|
|
7869
8099
|
const summary = cleanSummaryText(entry.description, 88);
|
|
8100
|
+
const meta = renderEntryBadgesHtml(entry, "ox-api-module__meta");
|
|
7870
8101
|
const heading = signature ? `<a href="${escapeHtml$3(href)}" class="ox-api-module__link">${renderHighlightedInlineCodeHtml(signature, "ox-api-module__signature ox-api-module__signature--highlighted")}</a>` : `<a href="${escapeHtml$3(href)}" class="ox-api-module__link"><code class="ox-api-module__name">${escapeHtml$3(entry.name)}</code></a>`;
|
|
7871
|
-
return `<li><span class="ox-api-module__kind">${escapeHtml$3(formatKindLabel(entry.kind))}</span><div class="ox-api-module__item">${heading}${summary ? `<span class="ox-api-module__summary">${renderInlineHtml(summary)}</span>` : ""}</div></li>`;
|
|
8102
|
+
return `<li><span class="ox-api-module__kind">${escapeHtml$3(formatKindLabel(entry.kind))}</span><div class="ox-api-module__item">${heading}${summary ? `<span class="ox-api-module__summary">${renderInlineHtml(summary)}</span>` : ""}${meta}</div></li>`;
|
|
7872
8103
|
}
|
|
7873
8104
|
function renderParamsListHtml(params) {
|
|
7874
8105
|
return `<div class="ox-api-entry__section ox-api-entry__section--params">
|
|
@@ -7900,6 +8131,10 @@ function generateEntryMarkdown(entry, options, currentFileName, symbolMap) {
|
|
|
7900
8131
|
const sourceHref = options?.githubUrl ? generateSourceHref(entry.file, options.githubUrl, entry.line, entry.endLine) : void 0;
|
|
7901
8132
|
let body = "";
|
|
7902
8133
|
if (processedDescription) body += renderMarkdownBlocksHtml(processedDescription) + "\n";
|
|
8134
|
+
if (entry.signature) body += `<div class="ox-api-entry__section ox-api-entry__section--signature">
|
|
8135
|
+
<h4>Signature</h4>
|
|
8136
|
+
${renderCodeBlockHtml(entry.signature, "typescript")}
|
|
8137
|
+
</div>\n`;
|
|
7903
8138
|
if (sourceHref) body += `<p class="ox-api-entry__source"><a href="${escapeHtml$3(sourceHref)}">View source</a></p>\n`;
|
|
7904
8139
|
if (entry.params && entry.params.length > 0) body += renderParamsListHtml(entry.params) + "\n";
|
|
7905
8140
|
if (entry.returns) body += `<div class="ox-api-entry__section ox-api-entry__section--returns">
|
|
@@ -7910,13 +8145,19 @@ function generateEntryMarkdown(entry, options, currentFileName, symbolMap) {
|
|
|
7910
8145
|
</div>
|
|
7911
8146
|
</div>\n`;
|
|
7912
8147
|
if (entry.examples && entry.examples.length > 0) {
|
|
7913
|
-
const examplesHtml = entry.examples.map((example
|
|
8148
|
+
const examplesHtml = entry.examples.map((example, index) => {
|
|
8149
|
+
const parsed = parseExampleBlock(example);
|
|
8150
|
+
return `<div class="ox-api-entry__example">
|
|
8151
|
+
<div class="ox-api-entry__example-heading">Example ${index + 1}</div>
|
|
8152
|
+
${renderCodeBlockHtml(parsed.code, parsed.language)}
|
|
8153
|
+
</div>`;
|
|
8154
|
+
}).join("\n");
|
|
7914
8155
|
body += `<div class="ox-api-entry__section ox-api-entry__section--examples">\n<h4>Examples</h4>\n${examplesHtml}\n</div>\n`;
|
|
7915
8156
|
}
|
|
7916
8157
|
if (entry.tags && Object.keys(entry.tags).length > 0) body += renderTagListHtml(entry.tags) + "\n";
|
|
7917
8158
|
const summaryDescription = cleanSummaryText(processedDescription, summarySignature ? 80 : 120);
|
|
7918
8159
|
const summaryHeading = summarySignature ? renderHighlightedInlineCodeHtml(summarySignature, "ox-api-entry__signature ox-api-entry__signature--highlighted") : `<code class="ox-api-entry__name">${escapeHtml$3(entry.name)}</code>`;
|
|
7919
|
-
const summaryParts = [`<span class="ox-api-entry__kind">${escapeHtml$3(formatKindLabel(entry.kind))}</span>`, `<span class="ox-api-entry__summary-main">${summaryHeading}${summaryDescription ? `<span class="ox-api-entry__description">${renderInlineHtml(summaryDescription)}</span>` : ""}</span>`];
|
|
8160
|
+
const summaryParts = [`<span class="ox-api-entry__kind">${escapeHtml$3(formatKindLabel(entry.kind))}</span>`, `<span class="ox-api-entry__summary-main">${summaryHeading}${summaryDescription ? `<span class="ox-api-entry__description">${renderInlineHtml(summaryDescription)}</span>` : ""}${renderEntryBadgesHtml(entry, "ox-api-entry__meta")}</span>`];
|
|
7920
8161
|
return `<details id="${entryAnchor(entry.name)}" class="ox-api-entry">
|
|
7921
8162
|
<summary>${summaryParts.join("")}</summary>
|
|
7922
8163
|
<div class="ox-api-entry__body">
|
|
@@ -7930,6 +8171,7 @@ function generateIndex(docs, docToFile) {
|
|
|
7930
8171
|
let md = "# API Documentation\n\n";
|
|
7931
8172
|
md += "Generated by [Ox Content](https://github.com/ubugeeei/ox-content)\n\n";
|
|
7932
8173
|
md += "> Use search scopes like `@api transform` to limit results to the generated API reference.\n\n";
|
|
8174
|
+
md += renderStatsHtml(summarizeEntries(docs.flatMap((doc) => doc.entries)), docs.length) + "\n\n";
|
|
7933
8175
|
md += "## Modules\n\n";
|
|
7934
8176
|
if (docs.length > 1) md += renderDetailsControlsHtml(".ox-api-module") + "\n\n";
|
|
7935
8177
|
for (const doc of docs) {
|
|
@@ -7959,6 +8201,7 @@ function generateCategoryMarkdown(kind, entries, options, symbolMap) {
|
|
|
7959
8201
|
const categoryFileName = `${kind}s`;
|
|
7960
8202
|
let md = `# ${kind.charAt(0).toUpperCase() + kind.slice(1)}s\n\n`;
|
|
7961
8203
|
md += `> ${entries.length} documented ${kind}${entries.length === 1 ? "" : "s"} collected across modules.\n\n`;
|
|
8204
|
+
md += renderStatsHtml(summarizeEntries(entries)) + "\n\n";
|
|
7962
8205
|
md += "## Overview\n\n";
|
|
7963
8206
|
for (const entry of entries) md += renderOverviewLine(entry, `#${entryAnchor(entry.name)}`);
|
|
7964
8207
|
md += "\n## Reference\n\n";
|
|
@@ -7969,6 +8212,7 @@ function generateCategoryMarkdown(kind, entries, options, symbolMap) {
|
|
|
7969
8212
|
function generateCategoryIndex(byKind) {
|
|
7970
8213
|
let md = "# API Documentation\n\n";
|
|
7971
8214
|
md += "Generated by [Ox Content](https://github.com/ubugeeei/ox-content)\n\n";
|
|
8215
|
+
md += renderStatsHtml(summarizeEntries([...byKind.values()].flatMap((entries) => entries))) + "\n\n";
|
|
7972
8216
|
for (const [kind, entries] of [...byKind.entries()].sort(([a], [b]) => compareStrings(a, b))) {
|
|
7973
8217
|
const kindTitle = kind.charAt(0).toUpperCase() + kind.slice(1) + "s";
|
|
7974
8218
|
md += `## [${kindTitle}](./${kind}s.md)\n\n`;
|
|
@@ -8080,7 +8324,7 @@ function resolveDocsOptions(options) {
|
|
|
8080
8324
|
enabled: opts.enabled ?? true,
|
|
8081
8325
|
src: opts.src ?? ["./src"],
|
|
8082
8326
|
out: opts.out ?? "docs/api",
|
|
8083
|
-
include: opts.include ??
|
|
8327
|
+
include: opts.include ?? DEFAULT_DOCS_INCLUDE,
|
|
8084
8328
|
exclude: opts.exclude ?? [
|
|
8085
8329
|
"**/*.test.*",
|
|
8086
8330
|
"**/*.spec.*",
|
|
@@ -9700,6 +9944,40 @@ const DEFAULT_HTML_TEMPLATE = `<!DOCTYPE html>
|
|
|
9700
9944
|
border-color: color-mix(in srgb, var(--color-primary) 38%, var(--color-border));
|
|
9701
9945
|
background: color-mix(in srgb, var(--color-bg-alt) 68%, var(--color-primary) 6%);
|
|
9702
9946
|
}
|
|
9947
|
+
.content .ox-api-stats {
|
|
9948
|
+
display: grid;
|
|
9949
|
+
grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
|
|
9950
|
+
gap: 0.55rem;
|
|
9951
|
+
margin: 1rem 0 1.35rem;
|
|
9952
|
+
}
|
|
9953
|
+
.content .ox-api-stat {
|
|
9954
|
+
min-width: 0;
|
|
9955
|
+
padding: 0.7rem 0.75rem;
|
|
9956
|
+
border: 1px solid color-mix(in srgb, var(--color-border) 76%, transparent);
|
|
9957
|
+
border-radius: 4px;
|
|
9958
|
+
background: color-mix(in srgb, var(--color-bg-alt) 72%, transparent);
|
|
9959
|
+
}
|
|
9960
|
+
.content .ox-api-stat strong {
|
|
9961
|
+
display: block;
|
|
9962
|
+
font-family: var(--font-mono);
|
|
9963
|
+
font-size: 1rem;
|
|
9964
|
+
line-height: 1.2;
|
|
9965
|
+
color: var(--color-text);
|
|
9966
|
+
}
|
|
9967
|
+
.content .ox-api-stat span {
|
|
9968
|
+
display: block;
|
|
9969
|
+
margin-top: 0.25rem;
|
|
9970
|
+
font-family: var(--font-mono);
|
|
9971
|
+
font-size: 0.7rem;
|
|
9972
|
+
font-weight: 600;
|
|
9973
|
+
letter-spacing: 0.04em;
|
|
9974
|
+
text-transform: uppercase;
|
|
9975
|
+
color: var(--color-text-muted);
|
|
9976
|
+
}
|
|
9977
|
+
.content .ox-api-stat--warning {
|
|
9978
|
+
border-color: color-mix(in srgb, #f59e0b 42%, var(--color-border));
|
|
9979
|
+
background: color-mix(in srgb, var(--color-bg-alt) 78%, #f59e0b 8%);
|
|
9980
|
+
}
|
|
9703
9981
|
.content .ox-api-entry,
|
|
9704
9982
|
.content .ox-api-module {
|
|
9705
9983
|
margin: 0;
|
|
@@ -9809,6 +10087,31 @@ const DEFAULT_HTML_TEMPLATE = `<!DOCTYPE html>
|
|
|
9809
10087
|
flex-direction: column;
|
|
9810
10088
|
gap: 0.55rem;
|
|
9811
10089
|
}
|
|
10090
|
+
.content .ox-api-entry__meta,
|
|
10091
|
+
.content .ox-api-module__meta {
|
|
10092
|
+
display: flex;
|
|
10093
|
+
flex-wrap: wrap;
|
|
10094
|
+
gap: 0.35rem;
|
|
10095
|
+
}
|
|
10096
|
+
.content .ox-api-badge {
|
|
10097
|
+
display: inline-flex;
|
|
10098
|
+
align-items: center;
|
|
10099
|
+
max-width: 100%;
|
|
10100
|
+
padding: 0.18rem 0.42rem;
|
|
10101
|
+
border: 1px solid color-mix(in srgb, var(--color-border) 78%, transparent);
|
|
10102
|
+
border-radius: 4px;
|
|
10103
|
+
background: color-mix(in srgb, var(--color-bg-alt) 78%, var(--color-primary) 6%);
|
|
10104
|
+
color: color-mix(in srgb, var(--color-text) 74%, var(--color-text-muted));
|
|
10105
|
+
font-family: var(--font-mono);
|
|
10106
|
+
font-size: 0.68rem;
|
|
10107
|
+
font-weight: 600;
|
|
10108
|
+
line-height: 1.35;
|
|
10109
|
+
}
|
|
10110
|
+
.content .ox-api-badge--warning {
|
|
10111
|
+
border-color: color-mix(in srgb, #f59e0b 46%, var(--color-border));
|
|
10112
|
+
background: color-mix(in srgb, var(--color-bg-alt) 78%, #f59e0b 9%);
|
|
10113
|
+
color: color-mix(in srgb, var(--color-text) 86%, #f59e0b);
|
|
10114
|
+
}
|
|
9812
10115
|
.content .ox-api-entry__name,
|
|
9813
10116
|
.content .ox-api-entry__signature,
|
|
9814
10117
|
.content .ox-api-module__name,
|
|
@@ -9957,6 +10260,23 @@ const DEFAULT_HTML_TEMPLATE = `<!DOCTYPE html>
|
|
|
9957
10260
|
font-size: 0.88rem;
|
|
9958
10261
|
line-height: 1.55;
|
|
9959
10262
|
}
|
|
10263
|
+
.content .ox-api-entry__section--signature pre {
|
|
10264
|
+
margin: 0;
|
|
10265
|
+
border: 1px solid var(--color-code-frame-border);
|
|
10266
|
+
border-radius: 4px;
|
|
10267
|
+
}
|
|
10268
|
+
.content .ox-api-entry__example + .ox-api-entry__example {
|
|
10269
|
+
margin-top: 0.85rem;
|
|
10270
|
+
}
|
|
10271
|
+
.content .ox-api-entry__example-heading {
|
|
10272
|
+
margin-bottom: 0.45rem;
|
|
10273
|
+
font-family: var(--font-mono);
|
|
10274
|
+
font-size: 0.72rem;
|
|
10275
|
+
font-weight: 700;
|
|
10276
|
+
letter-spacing: 0.04em;
|
|
10277
|
+
text-transform: uppercase;
|
|
10278
|
+
color: var(--color-text-muted);
|
|
10279
|
+
}
|
|
9960
10280
|
.content .ox-api-entry__section--examples pre {
|
|
9961
10281
|
margin: 0;
|
|
9962
10282
|
border: 1px solid var(--color-code-frame-border);
|