@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.mjs
CHANGED
|
@@ -7402,6 +7402,32 @@ export const ${exportName}: NavItem[] = ${JSON.stringify(navItems, null, 2)} as
|
|
|
7402
7402
|
*/
|
|
7403
7403
|
const DOCS_MANIFEST_FILE = ".ox-content-docs-manifest.json";
|
|
7404
7404
|
const DOCS_DATA_FILE = "docs.json";
|
|
7405
|
+
const DOC_KIND_ORDER = [
|
|
7406
|
+
"function",
|
|
7407
|
+
"class",
|
|
7408
|
+
"interface",
|
|
7409
|
+
"type",
|
|
7410
|
+
"variable",
|
|
7411
|
+
"module"
|
|
7412
|
+
];
|
|
7413
|
+
const DOC_KIND_PLURAL = {
|
|
7414
|
+
function: "functions",
|
|
7415
|
+
class: "classes",
|
|
7416
|
+
interface: "interfaces",
|
|
7417
|
+
type: "types",
|
|
7418
|
+
variable: "variables",
|
|
7419
|
+
module: "modules"
|
|
7420
|
+
};
|
|
7421
|
+
const DEFAULT_DOCS_INCLUDE = [
|
|
7422
|
+
"**/*.ts",
|
|
7423
|
+
"**/*.tsx",
|
|
7424
|
+
"**/*.js",
|
|
7425
|
+
"**/*.jsx",
|
|
7426
|
+
"**/*.mts",
|
|
7427
|
+
"**/*.mjs",
|
|
7428
|
+
"**/*.cts",
|
|
7429
|
+
"**/*.cjs"
|
|
7430
|
+
];
|
|
7405
7431
|
function escapeHtml$3(str) {
|
|
7406
7432
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
7407
7433
|
}
|
|
@@ -7410,7 +7436,7 @@ function entryAnchor(name) {
|
|
|
7410
7436
|
}
|
|
7411
7437
|
function cleanSummaryText(text, maxLength = 120) {
|
|
7412
7438
|
if (!text) return "";
|
|
7413
|
-
const collapsed = text.replace(/\s+/g, " ").trim();
|
|
7439
|
+
const collapsed = text.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/\[([^\]]+)\]/g, "$1").replace(/\s+/g, " ").trim();
|
|
7414
7440
|
if (collapsed.length <= maxLength) return collapsed;
|
|
7415
7441
|
return `${collapsed.slice(0, maxLength - 1).trimEnd()}…`;
|
|
7416
7442
|
}
|
|
@@ -7548,6 +7574,86 @@ function renderDetailsControlsHtml(targetSelector) {
|
|
|
7548
7574
|
<button type="button" class="ox-api-controls__button" data-ox-api-toggle="collapse">Close all</button>
|
|
7549
7575
|
</div>`;
|
|
7550
7576
|
}
|
|
7577
|
+
function createEmptyEntryStats() {
|
|
7578
|
+
return {
|
|
7579
|
+
entries: 0,
|
|
7580
|
+
byKind: {},
|
|
7581
|
+
params: 0,
|
|
7582
|
+
returns: 0,
|
|
7583
|
+
examples: 0,
|
|
7584
|
+
deprecated: 0
|
|
7585
|
+
};
|
|
7586
|
+
}
|
|
7587
|
+
function summarizeEntries(entries) {
|
|
7588
|
+
const stats = createEmptyEntryStats();
|
|
7589
|
+
for (const entry of entries) {
|
|
7590
|
+
stats.entries++;
|
|
7591
|
+
stats.byKind[entry.kind] = (stats.byKind[entry.kind] ?? 0) + 1;
|
|
7592
|
+
stats.params += entry.params?.length ?? 0;
|
|
7593
|
+
stats.returns += entry.returns ? 1 : 0;
|
|
7594
|
+
stats.examples += entry.examples?.length ?? 0;
|
|
7595
|
+
stats.deprecated += entry.tags?.deprecated !== void 0 ? 1 : 0;
|
|
7596
|
+
}
|
|
7597
|
+
return stats;
|
|
7598
|
+
}
|
|
7599
|
+
function buildDocsSummary(docs) {
|
|
7600
|
+
const stats = summarizeEntries(docs.flatMap((doc) => doc.entries));
|
|
7601
|
+
const byKind = {};
|
|
7602
|
+
for (const kind of DOC_KIND_ORDER) {
|
|
7603
|
+
const count = stats.byKind[kind];
|
|
7604
|
+
if (count) byKind[kind] = count;
|
|
7605
|
+
}
|
|
7606
|
+
return {
|
|
7607
|
+
modules: docs.length,
|
|
7608
|
+
entries: stats.entries,
|
|
7609
|
+
byKind,
|
|
7610
|
+
params: stats.params,
|
|
7611
|
+
returns: stats.returns,
|
|
7612
|
+
examples: stats.examples,
|
|
7613
|
+
deprecated: stats.deprecated
|
|
7614
|
+
};
|
|
7615
|
+
}
|
|
7616
|
+
function renderStatsHtml(stats, moduleCount) {
|
|
7617
|
+
const items = [];
|
|
7618
|
+
if (moduleCount !== void 0) items.push({
|
|
7619
|
+
label: "modules",
|
|
7620
|
+
value: moduleCount
|
|
7621
|
+
});
|
|
7622
|
+
items.push({
|
|
7623
|
+
label: "symbols",
|
|
7624
|
+
value: stats.entries
|
|
7625
|
+
});
|
|
7626
|
+
for (const kind of DOC_KIND_ORDER) {
|
|
7627
|
+
const count = stats.byKind[kind];
|
|
7628
|
+
if (count) items.push({
|
|
7629
|
+
label: DOC_KIND_PLURAL[kind],
|
|
7630
|
+
value: count
|
|
7631
|
+
});
|
|
7632
|
+
}
|
|
7633
|
+
if (stats.params) items.push({
|
|
7634
|
+
label: "parameters",
|
|
7635
|
+
value: stats.params
|
|
7636
|
+
});
|
|
7637
|
+
if (stats.returns) items.push({
|
|
7638
|
+
label: "returns",
|
|
7639
|
+
value: stats.returns
|
|
7640
|
+
});
|
|
7641
|
+
if (stats.examples) items.push({
|
|
7642
|
+
label: "examples",
|
|
7643
|
+
value: stats.examples
|
|
7644
|
+
});
|
|
7645
|
+
if (stats.deprecated) items.push({
|
|
7646
|
+
label: "deprecated",
|
|
7647
|
+
value: stats.deprecated,
|
|
7648
|
+
tone: "warning"
|
|
7649
|
+
});
|
|
7650
|
+
return `<div class="ox-api-stats" aria-label="API reference summary">
|
|
7651
|
+
${items.map((item) => `<span class="ox-api-stat${item.tone ? ` ox-api-stat--${item.tone}` : ""}">
|
|
7652
|
+
<strong>${item.value}</strong>
|
|
7653
|
+
<span>${escapeHtml$3(item.label)}</span>
|
|
7654
|
+
</span>`).join("\n")}
|
|
7655
|
+
</div>`;
|
|
7656
|
+
}
|
|
7551
7657
|
function normalizeDocFilePath(filePath) {
|
|
7552
7658
|
const normalized = filePath.replace(/\\/g, "/");
|
|
7553
7659
|
return normalized.match(/(?:^|\/)((?:npm|packages|crates|src)\/.+)$/)?.[1] ?? normalized.replace(/^\/+/, "");
|
|
@@ -7556,6 +7662,7 @@ function buildDocsData(docs) {
|
|
|
7556
7662
|
return {
|
|
7557
7663
|
version: 1,
|
|
7558
7664
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7665
|
+
summary: buildDocsSummary(docs),
|
|
7559
7666
|
modules: docs.map((doc) => ({
|
|
7560
7667
|
...doc,
|
|
7561
7668
|
file: normalizeDocFilePath(doc.file),
|
|
@@ -7566,6 +7673,86 @@ function buildDocsData(docs) {
|
|
|
7566
7673
|
}))
|
|
7567
7674
|
};
|
|
7568
7675
|
}
|
|
7676
|
+
function consumeJSDocType(value) {
|
|
7677
|
+
const trimmed = value.trimStart();
|
|
7678
|
+
if (!trimmed.startsWith("{")) return { rest: trimmed };
|
|
7679
|
+
let depth = 0;
|
|
7680
|
+
for (let index = 0; index < trimmed.length; index++) {
|
|
7681
|
+
const char = trimmed[index];
|
|
7682
|
+
if (char === "{") depth++;
|
|
7683
|
+
else if (char === "}") {
|
|
7684
|
+
depth--;
|
|
7685
|
+
if (depth === 0) return {
|
|
7686
|
+
type: trimmed.slice(1, index).trim() || void 0,
|
|
7687
|
+
rest: trimmed.slice(index + 1).trimStart()
|
|
7688
|
+
};
|
|
7689
|
+
}
|
|
7690
|
+
}
|
|
7691
|
+
return { rest: trimmed };
|
|
7692
|
+
}
|
|
7693
|
+
function cleanTagDescription(value) {
|
|
7694
|
+
return value.trim().replace(/^-\s*/, "").trim();
|
|
7695
|
+
}
|
|
7696
|
+
function splitTagNameAndDescription(value) {
|
|
7697
|
+
const trimmed = value.trimStart();
|
|
7698
|
+
if (trimmed.startsWith("[")) {
|
|
7699
|
+
const closeIndex = trimmed.indexOf("]");
|
|
7700
|
+
if (closeIndex >= 0) return {
|
|
7701
|
+
name: trimmed.slice(0, closeIndex + 1),
|
|
7702
|
+
description: trimmed.slice(closeIndex + 1).trimStart()
|
|
7703
|
+
};
|
|
7704
|
+
}
|
|
7705
|
+
const match = /^(\S+)(?:\s+([\s\S]*))?$/u.exec(trimmed);
|
|
7706
|
+
return {
|
|
7707
|
+
name: match?.[1] ?? "",
|
|
7708
|
+
description: match?.[2] ?? ""
|
|
7709
|
+
};
|
|
7710
|
+
}
|
|
7711
|
+
function parseParamTagValue(value) {
|
|
7712
|
+
const { type, rest } = consumeJSDocType(value);
|
|
7713
|
+
const { name: rawName, description } = splitTagNameAndDescription(rest);
|
|
7714
|
+
let name = rawName.trim();
|
|
7715
|
+
if (!name) return null;
|
|
7716
|
+
let optional = false;
|
|
7717
|
+
let defaultValue;
|
|
7718
|
+
const optionalMatch = /^\[(.*)\]$/u.exec(name);
|
|
7719
|
+
if (optionalMatch) {
|
|
7720
|
+
optional = true;
|
|
7721
|
+
const [innerName, innerDefault] = optionalMatch[1].split(/=(.*)/su);
|
|
7722
|
+
name = innerName.trim();
|
|
7723
|
+
defaultValue = innerDefault?.trim() || void 0;
|
|
7724
|
+
}
|
|
7725
|
+
if (!name) return null;
|
|
7726
|
+
return {
|
|
7727
|
+
name,
|
|
7728
|
+
type: type || "unknown",
|
|
7729
|
+
description: cleanTagDescription(description),
|
|
7730
|
+
optional: optional || void 0,
|
|
7731
|
+
default: defaultValue
|
|
7732
|
+
};
|
|
7733
|
+
}
|
|
7734
|
+
function parseReturnsTagValue(value) {
|
|
7735
|
+
const { type, rest } = consumeJSDocType(value);
|
|
7736
|
+
return {
|
|
7737
|
+
type: type || "unknown",
|
|
7738
|
+
description: cleanTagDescription(rest)
|
|
7739
|
+
};
|
|
7740
|
+
}
|
|
7741
|
+
function normalizeReturnType(value) {
|
|
7742
|
+
const parsed = parseReturnsTagValue(value);
|
|
7743
|
+
return parsed.type === "unknown" ? value : parsed.type;
|
|
7744
|
+
}
|
|
7745
|
+
function mergeParam(params, next) {
|
|
7746
|
+
const existing = params.find((param) => param.name === next.name);
|
|
7747
|
+
if (!existing) {
|
|
7748
|
+
params.push(next);
|
|
7749
|
+
return;
|
|
7750
|
+
}
|
|
7751
|
+
if (next.type && (existing.type === "unknown" || next.type !== "unknown")) existing.type = next.type;
|
|
7752
|
+
if (next.description) existing.description = next.description;
|
|
7753
|
+
if (next.optional) existing.optional = true;
|
|
7754
|
+
if (next.default) existing.default = next.default;
|
|
7755
|
+
}
|
|
7569
7756
|
/**
|
|
7570
7757
|
* Extracts JSDoc documentation from source files in specified directories.
|
|
7571
7758
|
*
|
|
@@ -7577,7 +7764,7 @@ function buildDocsData(docs) {
|
|
|
7577
7764
|
*
|
|
7578
7765
|
* 1. **File Discovery**: Recursively walks directories, applying filters
|
|
7579
7766
|
* 2. **File Reading**: Loads each matching file's content
|
|
7580
|
-
* 3. **JSDoc Extraction**: Parses JSDoc comments using
|
|
7767
|
+
* 3. **JSDoc Extraction**: Parses JSDoc comments using the native parser
|
|
7581
7768
|
* 4. **Declaration Matching**: Pairs JSDoc comments with source declarations
|
|
7582
7769
|
* 5. **Result Collection**: Aggregates extracted documentation by file
|
|
7583
7770
|
*
|
|
@@ -7717,32 +7904,29 @@ function parseNapiDocItem(item) {
|
|
|
7717
7904
|
currentExample = "";
|
|
7718
7905
|
inExample = false;
|
|
7719
7906
|
}
|
|
7720
|
-
const tagMatch =
|
|
7907
|
+
const tagMatch = /^@(\S+)\s*([\s\S]*)$/u.exec(lineText);
|
|
7721
7908
|
if (tagMatch) {
|
|
7722
|
-
const [, tagName,
|
|
7909
|
+
const [, tagName, tagValue = ""] = tagMatch;
|
|
7723
7910
|
switch (tagName) {
|
|
7724
7911
|
case "param":
|
|
7725
|
-
|
|
7726
|
-
|
|
7727
|
-
|
|
7728
|
-
|
|
7729
|
-
description: paramMatch[2]
|
|
7730
|
-
});
|
|
7912
|
+
case "arg":
|
|
7913
|
+
case "argument": {
|
|
7914
|
+
const param = parseParamTagValue(tagValue);
|
|
7915
|
+
if (param) mergeParam(params, param);
|
|
7731
7916
|
break;
|
|
7917
|
+
}
|
|
7732
7918
|
case "returns":
|
|
7733
7919
|
case "return":
|
|
7734
|
-
returns =
|
|
7735
|
-
type: tagType || "unknown",
|
|
7736
|
-
description: tagRest.trim()
|
|
7737
|
-
};
|
|
7920
|
+
returns = parseReturnsTagValue(tagValue);
|
|
7738
7921
|
break;
|
|
7739
7922
|
case "example":
|
|
7740
7923
|
inExample = true;
|
|
7924
|
+
currentExample = tagValue.trim() ? `${tagValue.trim()}\n` : "";
|
|
7741
7925
|
break;
|
|
7742
7926
|
case "private":
|
|
7743
7927
|
isPrivate = true;
|
|
7744
7928
|
break;
|
|
7745
|
-
default: tags[tagName] =
|
|
7929
|
+
default: tags[tagName] = tagValue.trim();
|
|
7746
7930
|
}
|
|
7747
7931
|
}
|
|
7748
7932
|
} else if (inExample) currentExample += rawLine + "\n";
|
|
@@ -7750,32 +7934,41 @@ function parseNapiDocItem(item) {
|
|
|
7750
7934
|
else description += "\n" + lineText;
|
|
7751
7935
|
}
|
|
7752
7936
|
if (inExample && currentExample) examples.push(currentExample.trim());
|
|
7753
|
-
|
|
7754
|
-
name
|
|
7755
|
-
|
|
7756
|
-
|
|
7757
|
-
|
|
7758
|
-
|
|
7759
|
-
|
|
7760
|
-
|
|
7761
|
-
|
|
7762
|
-
for (const param of params) {
|
|
7763
|
-
const rustParam = paramMap.get(param.name);
|
|
7764
|
-
if (!rustParam) continue;
|
|
7765
|
-
if (param.type === "unknown" && rustParam.typeAnnotation) param.type = rustParam.typeAnnotation;
|
|
7766
|
-
if (!param.description && rustParam.description) param.description = rustParam.description;
|
|
7767
|
-
if (param.optional === void 0 && rustParam.optional) param.optional = true;
|
|
7768
|
-
if (!param.default && rustParam.defaultValue) param.default = rustParam.defaultValue;
|
|
7769
|
-
}
|
|
7937
|
+
for (const param of item.params) {
|
|
7938
|
+
if (params.length > 0 && param.name === "param" && !param.typeAnnotation && !param.description && !param.defaultValue) continue;
|
|
7939
|
+
mergeParam(params, {
|
|
7940
|
+
name: param.name,
|
|
7941
|
+
type: param.typeAnnotation ?? "unknown",
|
|
7942
|
+
description: param.description ?? "",
|
|
7943
|
+
optional: param.optional || void 0,
|
|
7944
|
+
default: param.defaultValue
|
|
7945
|
+
});
|
|
7770
7946
|
}
|
|
7771
7947
|
if (!returns && item.returnType) returns = {
|
|
7772
|
-
type: item.returnType,
|
|
7948
|
+
type: normalizeReturnType(item.returnType),
|
|
7773
7949
|
description: ""
|
|
7774
7950
|
};
|
|
7775
|
-
else if (returns &&
|
|
7951
|
+
else if (returns && item.returnType) returns.type = normalizeReturnType(item.returnType);
|
|
7776
7952
|
if (!description) description = item.doc ?? "";
|
|
7777
7953
|
for (const tag of item.tags) {
|
|
7778
|
-
if (tag.tag === "param" || tag.tag === "
|
|
7954
|
+
if (tag.tag === "param" || tag.tag === "arg" || tag.tag === "argument" || tag.tag === "returns" || tag.tag === "return") {
|
|
7955
|
+
if (tag.tag === "param" || tag.tag === "arg" || tag.tag === "argument") {
|
|
7956
|
+
const param = parseParamTagValue(tag.value);
|
|
7957
|
+
if (param) mergeParam(params, param);
|
|
7958
|
+
} else {
|
|
7959
|
+
const parsedReturns = parseReturnsTagValue(tag.value);
|
|
7960
|
+
if (!returns) returns = parsedReturns;
|
|
7961
|
+
else {
|
|
7962
|
+
returns.type = returns.type === "unknown" ? parsedReturns.type : returns.type;
|
|
7963
|
+
returns.description ||= parsedReturns.description;
|
|
7964
|
+
}
|
|
7965
|
+
}
|
|
7966
|
+
continue;
|
|
7967
|
+
}
|
|
7968
|
+
if (tag.tag === "example") {
|
|
7969
|
+
if (tag.value && !examples.includes(tag.value)) examples.push(tag.value);
|
|
7970
|
+
continue;
|
|
7971
|
+
}
|
|
7779
7972
|
if (tag.tag === "private") {
|
|
7780
7973
|
isPrivate = true;
|
|
7781
7974
|
continue;
|
|
@@ -7862,6 +8055,7 @@ function generateFileMarkdown(doc, options, currentFileName, symbolMap) {
|
|
|
7862
8055
|
}
|
|
7863
8056
|
md += `> ${doc.entries.length} documented symbol${doc.entries.length === 1 ? "" : "s"}. `;
|
|
7864
8057
|
md += "Read the signatures first, then expand each item for parameters, return types, and examples.\n\n";
|
|
8058
|
+
md += renderStatsHtml(summarizeEntries(doc.entries)) + "\n\n";
|
|
7865
8059
|
md += "## Reference\n\n";
|
|
7866
8060
|
if (doc.entries.length > 1) md += renderDetailsControlsHtml(".ox-api-entry") + "\n\n";
|
|
7867
8061
|
for (const entry of doc.entries) md += generateEntryMarkdown(entry, options, currentFileName, symbolMap);
|
|
@@ -7881,6 +8075,42 @@ function formatKindLabel(kind) {
|
|
|
7881
8075
|
default: return kind;
|
|
7882
8076
|
}
|
|
7883
8077
|
}
|
|
8078
|
+
function formatCountLabel(count, singular, plural = `${singular}s`) {
|
|
8079
|
+
return `${count} ${count === 1 ? singular : plural}`;
|
|
8080
|
+
}
|
|
8081
|
+
function getEntryBadges(entry) {
|
|
8082
|
+
const badges = [];
|
|
8083
|
+
if (entry.tags?.deprecated !== void 0) badges.push({
|
|
8084
|
+
label: "deprecated",
|
|
8085
|
+
tone: "warning"
|
|
8086
|
+
});
|
|
8087
|
+
if (entry.params?.length) badges.push({ label: formatCountLabel(entry.params.length, "param") });
|
|
8088
|
+
if (entry.returns) badges.push({ label: `returns ${entry.returns.type}` });
|
|
8089
|
+
if (entry.examples?.length) badges.push({ label: formatCountLabel(entry.examples.length, "example") });
|
|
8090
|
+
if (entry.tags?.since) badges.push({ label: `since ${entry.tags.since}` });
|
|
8091
|
+
if (entry.private) badges.push({
|
|
8092
|
+
label: "private",
|
|
8093
|
+
tone: "warning"
|
|
8094
|
+
});
|
|
8095
|
+
return badges;
|
|
8096
|
+
}
|
|
8097
|
+
function renderEntryBadgesHtml(entry, className) {
|
|
8098
|
+
const badges = getEntryBadges(entry);
|
|
8099
|
+
if (badges.length === 0) return "";
|
|
8100
|
+
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>`;
|
|
8101
|
+
}
|
|
8102
|
+
function parseExampleBlock(example) {
|
|
8103
|
+
const trimmed = example.trim();
|
|
8104
|
+
const fenceMatch = /^```([\w-]+)?[^\n]*\n([\s\S]*?)\n?```$/u.exec(trimmed);
|
|
8105
|
+
if (!fenceMatch) return {
|
|
8106
|
+
code: trimmed,
|
|
8107
|
+
language: "ts"
|
|
8108
|
+
};
|
|
8109
|
+
return {
|
|
8110
|
+
code: fenceMatch[2],
|
|
8111
|
+
language: fenceMatch[1] || "ts"
|
|
8112
|
+
};
|
|
8113
|
+
}
|
|
7884
8114
|
function renderOverviewLine(entry, href) {
|
|
7885
8115
|
const signature = normalizeSignature(entry.signature);
|
|
7886
8116
|
const summary = cleanSummaryText(entry.description, 88);
|
|
@@ -7892,8 +8122,9 @@ function renderOverviewLine(entry, href) {
|
|
|
7892
8122
|
function renderOverviewHtmlItem(entry, href) {
|
|
7893
8123
|
const signature = normalizeSignature(entry.signature);
|
|
7894
8124
|
const summary = cleanSummaryText(entry.description, 88);
|
|
8125
|
+
const meta = renderEntryBadgesHtml(entry, "ox-api-module__meta");
|
|
7895
8126
|
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>`;
|
|
7896
|
-
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>`;
|
|
8127
|
+
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>`;
|
|
7897
8128
|
}
|
|
7898
8129
|
function renderParamsListHtml(params) {
|
|
7899
8130
|
return `<div class="ox-api-entry__section ox-api-entry__section--params">
|
|
@@ -7925,6 +8156,10 @@ function generateEntryMarkdown(entry, options, currentFileName, symbolMap) {
|
|
|
7925
8156
|
const sourceHref = options?.githubUrl ? generateSourceHref(entry.file, options.githubUrl, entry.line, entry.endLine) : void 0;
|
|
7926
8157
|
let body = "";
|
|
7927
8158
|
if (processedDescription) body += renderMarkdownBlocksHtml(processedDescription) + "\n";
|
|
8159
|
+
if (entry.signature) body += `<div class="ox-api-entry__section ox-api-entry__section--signature">
|
|
8160
|
+
<h4>Signature</h4>
|
|
8161
|
+
${renderCodeBlockHtml(entry.signature, "typescript")}
|
|
8162
|
+
</div>\n`;
|
|
7928
8163
|
if (sourceHref) body += `<p class="ox-api-entry__source"><a href="${escapeHtml$3(sourceHref)}">View source</a></p>\n`;
|
|
7929
8164
|
if (entry.params && entry.params.length > 0) body += renderParamsListHtml(entry.params) + "\n";
|
|
7930
8165
|
if (entry.returns) body += `<div class="ox-api-entry__section ox-api-entry__section--returns">
|
|
@@ -7935,13 +8170,19 @@ function generateEntryMarkdown(entry, options, currentFileName, symbolMap) {
|
|
|
7935
8170
|
</div>
|
|
7936
8171
|
</div>\n`;
|
|
7937
8172
|
if (entry.examples && entry.examples.length > 0) {
|
|
7938
|
-
const examplesHtml = entry.examples.map((example
|
|
8173
|
+
const examplesHtml = entry.examples.map((example, index) => {
|
|
8174
|
+
const parsed = parseExampleBlock(example);
|
|
8175
|
+
return `<div class="ox-api-entry__example">
|
|
8176
|
+
<div class="ox-api-entry__example-heading">Example ${index + 1}</div>
|
|
8177
|
+
${renderCodeBlockHtml(parsed.code, parsed.language)}
|
|
8178
|
+
</div>`;
|
|
8179
|
+
}).join("\n");
|
|
7939
8180
|
body += `<div class="ox-api-entry__section ox-api-entry__section--examples">\n<h4>Examples</h4>\n${examplesHtml}\n</div>\n`;
|
|
7940
8181
|
}
|
|
7941
8182
|
if (entry.tags && Object.keys(entry.tags).length > 0) body += renderTagListHtml(entry.tags) + "\n";
|
|
7942
8183
|
const summaryDescription = cleanSummaryText(processedDescription, summarySignature ? 80 : 120);
|
|
7943
8184
|
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>`;
|
|
7944
|
-
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>`];
|
|
8185
|
+
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>`];
|
|
7945
8186
|
return `<details id="${entryAnchor(entry.name)}" class="ox-api-entry">
|
|
7946
8187
|
<summary>${summaryParts.join("")}</summary>
|
|
7947
8188
|
<div class="ox-api-entry__body">
|
|
@@ -7955,6 +8196,7 @@ function generateIndex(docs, docToFile) {
|
|
|
7955
8196
|
let md = "# API Documentation\n\n";
|
|
7956
8197
|
md += "Generated by [Ox Content](https://github.com/ubugeeei/ox-content)\n\n";
|
|
7957
8198
|
md += "> Use search scopes like `@api transform` to limit results to the generated API reference.\n\n";
|
|
8199
|
+
md += renderStatsHtml(summarizeEntries(docs.flatMap((doc) => doc.entries)), docs.length) + "\n\n";
|
|
7958
8200
|
md += "## Modules\n\n";
|
|
7959
8201
|
if (docs.length > 1) md += renderDetailsControlsHtml(".ox-api-module") + "\n\n";
|
|
7960
8202
|
for (const doc of docs) {
|
|
@@ -7984,6 +8226,7 @@ function generateCategoryMarkdown(kind, entries, options, symbolMap) {
|
|
|
7984
8226
|
const categoryFileName = `${kind}s`;
|
|
7985
8227
|
let md = `# ${kind.charAt(0).toUpperCase() + kind.slice(1)}s\n\n`;
|
|
7986
8228
|
md += `> ${entries.length} documented ${kind}${entries.length === 1 ? "" : "s"} collected across modules.\n\n`;
|
|
8229
|
+
md += renderStatsHtml(summarizeEntries(entries)) + "\n\n";
|
|
7987
8230
|
md += "## Overview\n\n";
|
|
7988
8231
|
for (const entry of entries) md += renderOverviewLine(entry, `#${entryAnchor(entry.name)}`);
|
|
7989
8232
|
md += "\n## Reference\n\n";
|
|
@@ -7994,6 +8237,7 @@ function generateCategoryMarkdown(kind, entries, options, symbolMap) {
|
|
|
7994
8237
|
function generateCategoryIndex(byKind) {
|
|
7995
8238
|
let md = "# API Documentation\n\n";
|
|
7996
8239
|
md += "Generated by [Ox Content](https://github.com/ubugeeei/ox-content)\n\n";
|
|
8240
|
+
md += renderStatsHtml(summarizeEntries([...byKind.values()].flatMap((entries) => entries))) + "\n\n";
|
|
7997
8241
|
for (const [kind, entries] of [...byKind.entries()].sort(([a], [b]) => compareStrings(a, b))) {
|
|
7998
8242
|
const kindTitle = kind.charAt(0).toUpperCase() + kind.slice(1) + "s";
|
|
7999
8243
|
md += `## [${kindTitle}](./${kind}s.md)\n\n`;
|
|
@@ -8105,7 +8349,7 @@ function resolveDocsOptions(options) {
|
|
|
8105
8349
|
enabled: opts.enabled ?? true,
|
|
8106
8350
|
src: opts.src ?? ["./src"],
|
|
8107
8351
|
out: opts.out ?? "docs/api",
|
|
8108
|
-
include: opts.include ??
|
|
8352
|
+
include: opts.include ?? DEFAULT_DOCS_INCLUDE,
|
|
8109
8353
|
exclude: opts.exclude ?? [
|
|
8110
8354
|
"**/*.test.*",
|
|
8111
8355
|
"**/*.spec.*",
|
|
@@ -9725,6 +9969,40 @@ const DEFAULT_HTML_TEMPLATE = `<!DOCTYPE html>
|
|
|
9725
9969
|
border-color: color-mix(in srgb, var(--color-primary) 38%, var(--color-border));
|
|
9726
9970
|
background: color-mix(in srgb, var(--color-bg-alt) 68%, var(--color-primary) 6%);
|
|
9727
9971
|
}
|
|
9972
|
+
.content .ox-api-stats {
|
|
9973
|
+
display: grid;
|
|
9974
|
+
grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
|
|
9975
|
+
gap: 0.55rem;
|
|
9976
|
+
margin: 1rem 0 1.35rem;
|
|
9977
|
+
}
|
|
9978
|
+
.content .ox-api-stat {
|
|
9979
|
+
min-width: 0;
|
|
9980
|
+
padding: 0.7rem 0.75rem;
|
|
9981
|
+
border: 1px solid color-mix(in srgb, var(--color-border) 76%, transparent);
|
|
9982
|
+
border-radius: 4px;
|
|
9983
|
+
background: color-mix(in srgb, var(--color-bg-alt) 72%, transparent);
|
|
9984
|
+
}
|
|
9985
|
+
.content .ox-api-stat strong {
|
|
9986
|
+
display: block;
|
|
9987
|
+
font-family: var(--font-mono);
|
|
9988
|
+
font-size: 1rem;
|
|
9989
|
+
line-height: 1.2;
|
|
9990
|
+
color: var(--color-text);
|
|
9991
|
+
}
|
|
9992
|
+
.content .ox-api-stat span {
|
|
9993
|
+
display: block;
|
|
9994
|
+
margin-top: 0.25rem;
|
|
9995
|
+
font-family: var(--font-mono);
|
|
9996
|
+
font-size: 0.7rem;
|
|
9997
|
+
font-weight: 600;
|
|
9998
|
+
letter-spacing: 0.04em;
|
|
9999
|
+
text-transform: uppercase;
|
|
10000
|
+
color: var(--color-text-muted);
|
|
10001
|
+
}
|
|
10002
|
+
.content .ox-api-stat--warning {
|
|
10003
|
+
border-color: color-mix(in srgb, #f59e0b 42%, var(--color-border));
|
|
10004
|
+
background: color-mix(in srgb, var(--color-bg-alt) 78%, #f59e0b 8%);
|
|
10005
|
+
}
|
|
9728
10006
|
.content .ox-api-entry,
|
|
9729
10007
|
.content .ox-api-module {
|
|
9730
10008
|
margin: 0;
|
|
@@ -9834,6 +10112,31 @@ const DEFAULT_HTML_TEMPLATE = `<!DOCTYPE html>
|
|
|
9834
10112
|
flex-direction: column;
|
|
9835
10113
|
gap: 0.55rem;
|
|
9836
10114
|
}
|
|
10115
|
+
.content .ox-api-entry__meta,
|
|
10116
|
+
.content .ox-api-module__meta {
|
|
10117
|
+
display: flex;
|
|
10118
|
+
flex-wrap: wrap;
|
|
10119
|
+
gap: 0.35rem;
|
|
10120
|
+
}
|
|
10121
|
+
.content .ox-api-badge {
|
|
10122
|
+
display: inline-flex;
|
|
10123
|
+
align-items: center;
|
|
10124
|
+
max-width: 100%;
|
|
10125
|
+
padding: 0.18rem 0.42rem;
|
|
10126
|
+
border: 1px solid color-mix(in srgb, var(--color-border) 78%, transparent);
|
|
10127
|
+
border-radius: 4px;
|
|
10128
|
+
background: color-mix(in srgb, var(--color-bg-alt) 78%, var(--color-primary) 6%);
|
|
10129
|
+
color: color-mix(in srgb, var(--color-text) 74%, var(--color-text-muted));
|
|
10130
|
+
font-family: var(--font-mono);
|
|
10131
|
+
font-size: 0.68rem;
|
|
10132
|
+
font-weight: 600;
|
|
10133
|
+
line-height: 1.35;
|
|
10134
|
+
}
|
|
10135
|
+
.content .ox-api-badge--warning {
|
|
10136
|
+
border-color: color-mix(in srgb, #f59e0b 46%, var(--color-border));
|
|
10137
|
+
background: color-mix(in srgb, var(--color-bg-alt) 78%, #f59e0b 9%);
|
|
10138
|
+
color: color-mix(in srgb, var(--color-text) 86%, #f59e0b);
|
|
10139
|
+
}
|
|
9837
10140
|
.content .ox-api-entry__name,
|
|
9838
10141
|
.content .ox-api-entry__signature,
|
|
9839
10142
|
.content .ox-api-module__name,
|
|
@@ -9982,6 +10285,23 @@ const DEFAULT_HTML_TEMPLATE = `<!DOCTYPE html>
|
|
|
9982
10285
|
font-size: 0.88rem;
|
|
9983
10286
|
line-height: 1.55;
|
|
9984
10287
|
}
|
|
10288
|
+
.content .ox-api-entry__section--signature pre {
|
|
10289
|
+
margin: 0;
|
|
10290
|
+
border: 1px solid var(--color-code-frame-border);
|
|
10291
|
+
border-radius: 4px;
|
|
10292
|
+
}
|
|
10293
|
+
.content .ox-api-entry__example + .ox-api-entry__example {
|
|
10294
|
+
margin-top: 0.85rem;
|
|
10295
|
+
}
|
|
10296
|
+
.content .ox-api-entry__example-heading {
|
|
10297
|
+
margin-bottom: 0.45rem;
|
|
10298
|
+
font-family: var(--font-mono);
|
|
10299
|
+
font-size: 0.72rem;
|
|
10300
|
+
font-weight: 700;
|
|
10301
|
+
letter-spacing: 0.04em;
|
|
10302
|
+
text-transform: uppercase;
|
|
10303
|
+
color: var(--color-text-muted);
|
|
10304
|
+
}
|
|
9985
10305
|
.content .ox-api-entry__section--examples pre {
|
|
9986
10306
|
margin: 0;
|
|
9987
10307
|
border: 1px solid var(--color-code-frame-border);
|