docula 1.5.0 → 1.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/docula.d.ts +24 -2
- package/dist/docula.js +135 -46
- package/package.json +1 -1
- package/templates/modern/api.hbs +2 -2
- package/templates/modern/changelog-entry.hbs +1 -1
- package/templates/modern/changelog.hbs +1 -1
- package/templates/modern/home.hbs +2 -2
- package/templates/modern/includes/api-reference.hbs +1 -1
- package/templates/modern/includes/documentation.hbs +1 -1
- package/templates/modern/includes/footer.hbs +2 -2
- package/templates/modern/includes/header-bar.hbs +8 -8
- package/templates/modern/includes/header.hbs +4 -4
- package/templates/modern/includes/home.hbs +1 -1
- package/templates/modern/includes/scripts.hbs +1 -1
package/dist/docula.d.ts
CHANGED
|
@@ -215,9 +215,23 @@ declare class DoculaOptions {
|
|
|
215
215
|
*/
|
|
216
216
|
autoUpdateIgnores: boolean;
|
|
217
217
|
/**
|
|
218
|
-
*
|
|
219
|
-
*
|
|
218
|
+
* Base URL path prefix for all generated paths (e.g., "/docs").
|
|
219
|
+
* When set, all asset and navigation URLs are prefixed with this path.
|
|
220
|
+
*/
|
|
221
|
+
baseUrl: string;
|
|
222
|
+
/**
|
|
223
|
+
* Output subdirectory and URL segment for documentation pages.
|
|
224
|
+
* Set to empty string to place docs at the output root.
|
|
225
|
+
*/
|
|
226
|
+
docsPath: string;
|
|
227
|
+
/**
|
|
228
|
+
* Output subdirectory and URL segment for API reference pages.
|
|
229
|
+
*/
|
|
230
|
+
apiPath: string;
|
|
231
|
+
/**
|
|
232
|
+
* Output subdirectory and URL segment for changelog pages.
|
|
220
233
|
*/
|
|
234
|
+
changelogPath: string;
|
|
221
235
|
/**
|
|
222
236
|
* Cookie-based authentication. When set, shows a Login/Logout button
|
|
223
237
|
* in the header based on whether a JWT cookie is present.
|
|
@@ -297,6 +311,13 @@ type DoculaData = {
|
|
|
297
311
|
enableLlmsTxt?: boolean;
|
|
298
312
|
hasFeed?: boolean;
|
|
299
313
|
lastModified?: string;
|
|
314
|
+
baseUrl: string;
|
|
315
|
+
docsPath: string;
|
|
316
|
+
apiPath: string;
|
|
317
|
+
changelogPath: string;
|
|
318
|
+
docsUrl: string;
|
|
319
|
+
apiUrl: string;
|
|
320
|
+
changelogUrl: string;
|
|
300
321
|
};
|
|
301
322
|
type DoculaTemplates = {
|
|
302
323
|
home: string;
|
|
@@ -345,6 +366,7 @@ declare class DoculaBuilder {
|
|
|
345
366
|
buildLlmsFiles(data: DoculaData): Promise<void>;
|
|
346
367
|
private generateLlmsIndexContent;
|
|
347
368
|
private generateLlmsFullContent;
|
|
369
|
+
private buildUrlPath;
|
|
348
370
|
private buildAbsoluteSiteUrl;
|
|
349
371
|
private normalizePathForUrl;
|
|
350
372
|
private escapeXml;
|
package/dist/docula.js
CHANGED
|
@@ -907,6 +907,18 @@ var Github = class {
|
|
|
907
907
|
// src/options.ts
|
|
908
908
|
import path3 from "path";
|
|
909
909
|
import process3 from "process";
|
|
910
|
+
function trimSlashes(value) {
|
|
911
|
+
let start = 0;
|
|
912
|
+
let end = value.length;
|
|
913
|
+
while (start < end && value[start] === "/") start++;
|
|
914
|
+
while (end > start && value[end - 1] === "/") end--;
|
|
915
|
+
return value.slice(start, end);
|
|
916
|
+
}
|
|
917
|
+
function trimTrailingSlashes(value) {
|
|
918
|
+
let end = value.length;
|
|
919
|
+
while (end > 0 && value[end - 1] === "/") end--;
|
|
920
|
+
return value.slice(0, end);
|
|
921
|
+
}
|
|
910
922
|
var DoculaOptions = class {
|
|
911
923
|
/**
|
|
912
924
|
* Name of the built-in template to use (e.g., "modern", "classic")
|
|
@@ -979,9 +991,23 @@ var DoculaOptions = class {
|
|
|
979
991
|
*/
|
|
980
992
|
autoUpdateIgnores = true;
|
|
981
993
|
/**
|
|
982
|
-
*
|
|
983
|
-
*
|
|
994
|
+
* Base URL path prefix for all generated paths (e.g., "/docs").
|
|
995
|
+
* When set, all asset and navigation URLs are prefixed with this path.
|
|
996
|
+
*/
|
|
997
|
+
baseUrl = "";
|
|
998
|
+
/**
|
|
999
|
+
* Output subdirectory and URL segment for documentation pages.
|
|
1000
|
+
* Set to empty string to place docs at the output root.
|
|
1001
|
+
*/
|
|
1002
|
+
docsPath = "docs";
|
|
1003
|
+
/**
|
|
1004
|
+
* Output subdirectory and URL segment for API reference pages.
|
|
984
1005
|
*/
|
|
1006
|
+
apiPath = "api";
|
|
1007
|
+
/**
|
|
1008
|
+
* Output subdirectory and URL segment for changelog pages.
|
|
1009
|
+
*/
|
|
1010
|
+
changelogPath = "changelog";
|
|
985
1011
|
/**
|
|
986
1012
|
* Cookie-based authentication. When set, shows a Login/Logout button
|
|
987
1013
|
* in the header based on whether a JWT cookie is present.
|
|
@@ -1096,6 +1122,18 @@ var DoculaOptions = class {
|
|
|
1096
1122
|
if (options.cache && typeof options.cache === "object" && options.cache.github !== null && typeof options.cache.github === "object" && typeof options.cache.github.ttl === "number") {
|
|
1097
1123
|
this.cache = options.cache;
|
|
1098
1124
|
}
|
|
1125
|
+
if (options.baseUrl !== void 0 && typeof options.baseUrl === "string") {
|
|
1126
|
+
this.baseUrl = trimTrailingSlashes(options.baseUrl);
|
|
1127
|
+
}
|
|
1128
|
+
if (options.docsPath !== void 0 && typeof options.docsPath === "string") {
|
|
1129
|
+
this.docsPath = trimSlashes(options.docsPath);
|
|
1130
|
+
}
|
|
1131
|
+
if (options.apiPath !== void 0 && typeof options.apiPath === "string") {
|
|
1132
|
+
this.apiPath = trimSlashes(options.apiPath);
|
|
1133
|
+
}
|
|
1134
|
+
if (options.changelogPath !== void 0 && typeof options.changelogPath === "string") {
|
|
1135
|
+
this.changelogPath = trimSlashes(options.changelogPath);
|
|
1136
|
+
}
|
|
1099
1137
|
if (options.allowedAssets && Array.isArray(options.allowedAssets)) {
|
|
1100
1138
|
this.allowedAssets = options.allowedAssets;
|
|
1101
1139
|
}
|
|
@@ -1207,14 +1245,28 @@ var DoculaBuilder = class {
|
|
|
1207
1245
|
themeMode: this.options.themeMode,
|
|
1208
1246
|
cookieAuth: this.options.cookieAuth,
|
|
1209
1247
|
headerLinks: this.options.headerLinks,
|
|
1210
|
-
enableLlmsTxt: this.options.enableLlmsTxt
|
|
1248
|
+
enableLlmsTxt: this.options.enableLlmsTxt,
|
|
1249
|
+
baseUrl: this.options.baseUrl,
|
|
1250
|
+
docsPath: this.options.docsPath,
|
|
1251
|
+
apiPath: this.options.apiPath,
|
|
1252
|
+
changelogPath: this.options.changelogPath,
|
|
1253
|
+
docsUrl: this.buildUrlPath(this.options.baseUrl, this.options.docsPath),
|
|
1254
|
+
apiUrl: this.buildUrlPath(this.options.baseUrl, this.options.apiPath),
|
|
1255
|
+
changelogUrl: this.buildUrlPath(
|
|
1256
|
+
this.options.baseUrl,
|
|
1257
|
+
this.options.changelogPath
|
|
1258
|
+
)
|
|
1211
1259
|
};
|
|
1212
1260
|
const readmePath = `${this.options.sitePath}/README.md`;
|
|
1213
1261
|
if (doculaData.hasReadme) {
|
|
1214
1262
|
currentAssetHashes["README.md"] = this.hashFile(readmePath);
|
|
1215
1263
|
}
|
|
1216
1264
|
if (!doculaData.openApiUrl && fs3.existsSync(`${doculaData.sitePath}/api/swagger.json`)) {
|
|
1217
|
-
doculaData.openApiUrl =
|
|
1265
|
+
doculaData.openApiUrl = this.buildUrlPath(
|
|
1266
|
+
this.options.baseUrl,
|
|
1267
|
+
this.options.apiPath,
|
|
1268
|
+
"swagger.json"
|
|
1269
|
+
);
|
|
1218
1270
|
}
|
|
1219
1271
|
if (this.options.githubPath) {
|
|
1220
1272
|
doculaData.github = await this.getGithubData(this.options.githubPath);
|
|
@@ -1318,15 +1370,17 @@ var DoculaBuilder = class {
|
|
|
1318
1370
|
if (doculaData.hasApi) {
|
|
1319
1371
|
this._console.step("Building API page...");
|
|
1320
1372
|
await this.buildApiPage(doculaData);
|
|
1321
|
-
this._console.fileBuilt(
|
|
1373
|
+
this._console.fileBuilt(`${this.options.apiPath}/index.html`);
|
|
1322
1374
|
}
|
|
1323
1375
|
if (doculaData.hasChangelog) {
|
|
1324
1376
|
this._console.step("Building changelog...");
|
|
1325
1377
|
await this.buildChangelogPage(doculaData);
|
|
1326
|
-
this._console.fileBuilt(
|
|
1378
|
+
this._console.fileBuilt(`${this.options.changelogPath}/index.html`);
|
|
1327
1379
|
await this.buildChangelogEntryPages(doculaData);
|
|
1328
1380
|
for (const entry of doculaData.changelogEntries ?? []) {
|
|
1329
|
-
this._console.fileBuilt(
|
|
1381
|
+
this._console.fileBuilt(
|
|
1382
|
+
`${this.options.changelogPath}/${entry.slug}/index.html`
|
|
1383
|
+
);
|
|
1330
1384
|
}
|
|
1331
1385
|
}
|
|
1332
1386
|
const siteRelativePath = this.options.sitePath;
|
|
@@ -1416,7 +1470,7 @@ var DoculaBuilder = class {
|
|
|
1416
1470
|
);
|
|
1417
1471
|
this.copyContentAssets(
|
|
1418
1472
|
`${doculaData.sitePath}/changelog`,
|
|
1419
|
-
`${this.options.output}
|
|
1473
|
+
`${this.options.output}/${this.options.changelogPath}`
|
|
1420
1474
|
);
|
|
1421
1475
|
if (doculaData.documents?.length) {
|
|
1422
1476
|
this.copyDocumentSiblingAssets(doculaData);
|
|
@@ -1524,13 +1578,17 @@ var DoculaBuilder = class {
|
|
|
1524
1578
|
const sitemapPath = `${data.output}/sitemap.xml`;
|
|
1525
1579
|
const urls = [{ url: data.siteUrl }];
|
|
1526
1580
|
if (data.documents?.length) {
|
|
1527
|
-
urls.push({ url: `${data.siteUrl}/feed.xml` });
|
|
1581
|
+
urls.push({ url: `${data.siteUrl}${data.baseUrl}/feed.xml` });
|
|
1528
1582
|
}
|
|
1529
1583
|
if (data.openApiUrl && data.templates?.api) {
|
|
1530
|
-
urls.push({
|
|
1584
|
+
urls.push({
|
|
1585
|
+
url: `${data.siteUrl}${data.apiUrl}`
|
|
1586
|
+
});
|
|
1531
1587
|
}
|
|
1532
1588
|
if (data.hasChangelog && data.templates?.changelog) {
|
|
1533
|
-
urls.push({
|
|
1589
|
+
urls.push({
|
|
1590
|
+
url: `${data.siteUrl}${data.changelogUrl}`
|
|
1591
|
+
});
|
|
1534
1592
|
const perPage = this.options.changelogPerPage;
|
|
1535
1593
|
const totalPages = Math.max(
|
|
1536
1594
|
1,
|
|
@@ -1538,12 +1596,12 @@ var DoculaBuilder = class {
|
|
|
1538
1596
|
);
|
|
1539
1597
|
for (let page = 2; page <= totalPages; page++) {
|
|
1540
1598
|
urls.push({
|
|
1541
|
-
url: `${data.siteUrl}/
|
|
1599
|
+
url: `${data.siteUrl}${data.changelogUrl}/page/${page}`
|
|
1542
1600
|
});
|
|
1543
1601
|
}
|
|
1544
1602
|
for (const entry of data.changelogEntries ?? []) {
|
|
1545
1603
|
urls.push({
|
|
1546
|
-
url: `${data.siteUrl}
|
|
1604
|
+
url: `${data.siteUrl}${data.changelogUrl}/${entry.slug}`
|
|
1547
1605
|
});
|
|
1548
1606
|
}
|
|
1549
1607
|
}
|
|
@@ -1552,7 +1610,7 @@ var DoculaBuilder = class {
|
|
|
1552
1610
|
if (urlPath.endsWith("index.html")) {
|
|
1553
1611
|
urlPath = urlPath.slice(0, -10);
|
|
1554
1612
|
}
|
|
1555
|
-
urls.push({ url: `${data.siteUrl}${urlPath}` });
|
|
1613
|
+
urls.push({ url: `${data.siteUrl}${data.baseUrl}${urlPath}` });
|
|
1556
1614
|
}
|
|
1557
1615
|
let xml = '<?xml version="1.0" encoding="UTF-8"?>';
|
|
1558
1616
|
xml += '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
|
|
@@ -1570,8 +1628,14 @@ var DoculaBuilder = class {
|
|
|
1570
1628
|
return;
|
|
1571
1629
|
}
|
|
1572
1630
|
const feedPath = `${data.output}/feed.xml`;
|
|
1573
|
-
const channelLink = this.buildAbsoluteSiteUrl(
|
|
1574
|
-
|
|
1631
|
+
const channelLink = this.buildAbsoluteSiteUrl(
|
|
1632
|
+
data.siteUrl,
|
|
1633
|
+
`${data.baseUrl}/`
|
|
1634
|
+
);
|
|
1635
|
+
const feedUrl = this.buildAbsoluteSiteUrl(
|
|
1636
|
+
data.siteUrl,
|
|
1637
|
+
`${data.baseUrl}/feed.xml`
|
|
1638
|
+
);
|
|
1575
1639
|
let xml = '<?xml version="1.0" encoding="UTF-8"?>';
|
|
1576
1640
|
xml += '<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">';
|
|
1577
1641
|
xml += "<channel>";
|
|
@@ -1584,7 +1648,7 @@ var DoculaBuilder = class {
|
|
|
1584
1648
|
const itemTitle = document.navTitle || document.title || document.urlPath;
|
|
1585
1649
|
const itemLink = this.buildAbsoluteSiteUrl(
|
|
1586
1650
|
data.siteUrl,
|
|
1587
|
-
this.normalizePathForUrl(document.urlPath)
|
|
1651
|
+
`${data.baseUrl}${this.normalizePathForUrl(document.urlPath)}`
|
|
1588
1652
|
);
|
|
1589
1653
|
const summary = document.description || this.summarizeMarkdown(new Writr(document.content).body);
|
|
1590
1654
|
xml += "<item>";
|
|
@@ -1642,7 +1706,7 @@ var DoculaBuilder = class {
|
|
|
1642
1706
|
lines.push(data.siteDescription);
|
|
1643
1707
|
lines.push("");
|
|
1644
1708
|
lines.push(
|
|
1645
|
-
`- [Full LLM Content](${this.buildAbsoluteSiteUrl(data.siteUrl,
|
|
1709
|
+
`- [Full LLM Content](${this.buildAbsoluteSiteUrl(data.siteUrl, `${data.baseUrl}/llms-full.txt`)})`
|
|
1646
1710
|
);
|
|
1647
1711
|
lines.push("");
|
|
1648
1712
|
lines.push("## Documentation");
|
|
@@ -1650,7 +1714,7 @@ var DoculaBuilder = class {
|
|
|
1650
1714
|
for (const document of documents) {
|
|
1651
1715
|
const documentUrl = this.buildAbsoluteSiteUrl(
|
|
1652
1716
|
data.siteUrl,
|
|
1653
|
-
this.normalizePathForUrl(document.urlPath)
|
|
1717
|
+
`${data.baseUrl}${this.normalizePathForUrl(document.urlPath)}`
|
|
1654
1718
|
);
|
|
1655
1719
|
const description = document.description ? ` - ${document.description}` : "";
|
|
1656
1720
|
lines.push(`- [${document.navTitle}](${documentUrl})${description}`);
|
|
@@ -1662,7 +1726,7 @@ var DoculaBuilder = class {
|
|
|
1662
1726
|
lines.push("## API Reference");
|
|
1663
1727
|
if (data.hasApi) {
|
|
1664
1728
|
lines.push(
|
|
1665
|
-
`- [API Documentation](${this.buildAbsoluteSiteUrl(data.siteUrl,
|
|
1729
|
+
`- [API Documentation](${this.buildAbsoluteSiteUrl(data.siteUrl, data.apiUrl)})`
|
|
1666
1730
|
);
|
|
1667
1731
|
} else {
|
|
1668
1732
|
lines.push("- Not available.");
|
|
@@ -1671,12 +1735,12 @@ var DoculaBuilder = class {
|
|
|
1671
1735
|
lines.push("## Changelog");
|
|
1672
1736
|
if (data.hasChangelog) {
|
|
1673
1737
|
lines.push(
|
|
1674
|
-
`- [Changelog](${this.buildAbsoluteSiteUrl(data.siteUrl,
|
|
1738
|
+
`- [Changelog](${this.buildAbsoluteSiteUrl(data.siteUrl, data.changelogUrl)})`
|
|
1675
1739
|
);
|
|
1676
1740
|
for (const entry of changelogEntries.slice(0, 20)) {
|
|
1677
1741
|
const date = entry.formattedDate || entry.date || "No date";
|
|
1678
1742
|
lines.push(
|
|
1679
|
-
`- [${entry.title}](${this.buildAbsoluteSiteUrl(data.siteUrl,
|
|
1743
|
+
`- [${entry.title}](${this.buildAbsoluteSiteUrl(data.siteUrl, `${data.changelogUrl}/${entry.slug}`)}) (${date})`
|
|
1680
1744
|
);
|
|
1681
1745
|
}
|
|
1682
1746
|
} else {
|
|
@@ -1694,7 +1758,7 @@ var DoculaBuilder = class {
|
|
|
1694
1758
|
lines.push(data.siteDescription);
|
|
1695
1759
|
lines.push("");
|
|
1696
1760
|
lines.push(
|
|
1697
|
-
`Source Index: ${this.buildAbsoluteSiteUrl(data.siteUrl,
|
|
1761
|
+
`Source Index: ${this.buildAbsoluteSiteUrl(data.siteUrl, `${data.baseUrl}/llms.txt`)}`
|
|
1698
1762
|
);
|
|
1699
1763
|
lines.push("");
|
|
1700
1764
|
lines.push("## Documentation");
|
|
@@ -1702,7 +1766,7 @@ var DoculaBuilder = class {
|
|
|
1702
1766
|
for (const document of documents) {
|
|
1703
1767
|
const documentUrl = this.buildAbsoluteSiteUrl(
|
|
1704
1768
|
data.siteUrl,
|
|
1705
|
-
this.normalizePathForUrl(document.urlPath)
|
|
1769
|
+
`${data.baseUrl}${this.normalizePathForUrl(document.urlPath)}`
|
|
1706
1770
|
);
|
|
1707
1771
|
const markdownBody = new Writr(document.content).body.trim();
|
|
1708
1772
|
lines.push("");
|
|
@@ -1720,7 +1784,9 @@ var DoculaBuilder = class {
|
|
|
1720
1784
|
lines.push("");
|
|
1721
1785
|
lines.push("## API Reference");
|
|
1722
1786
|
if (data.hasApi) {
|
|
1723
|
-
lines.push(
|
|
1787
|
+
lines.push(
|
|
1788
|
+
`URL: ${this.buildAbsoluteSiteUrl(data.siteUrl, data.apiUrl)}`
|
|
1789
|
+
);
|
|
1724
1790
|
lines.push("");
|
|
1725
1791
|
const localOpenApiSpec = await this.getSafeLocalOpenApiSpec(data);
|
|
1726
1792
|
if (localOpenApiSpec) {
|
|
@@ -1742,13 +1808,13 @@ var DoculaBuilder = class {
|
|
|
1742
1808
|
lines.push("## Changelog");
|
|
1743
1809
|
if (data.hasChangelog && changelogEntries.length > 0) {
|
|
1744
1810
|
lines.push(
|
|
1745
|
-
`URL: ${this.buildAbsoluteSiteUrl(data.siteUrl,
|
|
1811
|
+
`URL: ${this.buildAbsoluteSiteUrl(data.siteUrl, data.changelogUrl)}`
|
|
1746
1812
|
);
|
|
1747
1813
|
for (const entry of changelogEntries) {
|
|
1748
1814
|
lines.push("");
|
|
1749
1815
|
lines.push(`### ${entry.title}`);
|
|
1750
1816
|
lines.push(
|
|
1751
|
-
`URL: ${this.buildAbsoluteSiteUrl(data.siteUrl,
|
|
1817
|
+
`URL: ${this.buildAbsoluteSiteUrl(data.siteUrl, `${data.changelogUrl}/${entry.slug}`)}`
|
|
1752
1818
|
);
|
|
1753
1819
|
if (entry.formattedDate || entry.date) {
|
|
1754
1820
|
lines.push(`Date: ${entry.formattedDate || entry.date}`);
|
|
@@ -1765,6 +1831,16 @@ var DoculaBuilder = class {
|
|
|
1765
1831
|
lines.push("");
|
|
1766
1832
|
return lines.join("\n");
|
|
1767
1833
|
}
|
|
1834
|
+
buildUrlPath(...segments) {
|
|
1835
|
+
const cleaned = segments.filter((s) => Boolean(s)).map((s) => {
|
|
1836
|
+
let start = 0;
|
|
1837
|
+
let end = s.length;
|
|
1838
|
+
while (start < end && s[start] === "/") start++;
|
|
1839
|
+
while (end > start && s[end - 1] === "/") end--;
|
|
1840
|
+
return s.slice(start, end);
|
|
1841
|
+
});
|
|
1842
|
+
return `/${cleaned.filter(Boolean).join("/")}`;
|
|
1843
|
+
}
|
|
1768
1844
|
buildAbsoluteSiteUrl(siteUrl, urlPath) {
|
|
1769
1845
|
const normalizedSiteUrl = siteUrl.endsWith("/") ? siteUrl.slice(0, -1) : siteUrl;
|
|
1770
1846
|
const normalizedPath = urlPath.startsWith("/") ? urlPath : `/${urlPath}`;
|
|
@@ -1949,7 +2025,9 @@ var DoculaBuilder = class {
|
|
|
1949
2025
|
async buildDocsPages(data) {
|
|
1950
2026
|
if (data.templates && data.documents?.length) {
|
|
1951
2027
|
const documentsTemplate = `${data.templatePath}/${data.templates.docPage}`;
|
|
1952
|
-
|
|
2028
|
+
const resolvedDocsPath = data.docsPath;
|
|
2029
|
+
const docsOutputDir = resolvedDocsPath ? `${data.output}/${resolvedDocsPath}` : `${data.output}`;
|
|
2030
|
+
await fs3.promises.mkdir(docsOutputDir, { recursive: true });
|
|
1953
2031
|
data.sidebarItems = this.generateSidebarItems(data);
|
|
1954
2032
|
const promises = data.documents.map(async (document) => {
|
|
1955
2033
|
const folder = document.urlPath.split("/").slice(0, -1).join("/");
|
|
@@ -1974,7 +2052,7 @@ var DoculaBuilder = class {
|
|
|
1974
2052
|
throw new Error("No API template or openApiUrl found");
|
|
1975
2053
|
}
|
|
1976
2054
|
const swaggerSource = `${data.sitePath}/api/swagger.json`;
|
|
1977
|
-
const apiOutputPath = `${data.output}
|
|
2055
|
+
const apiOutputPath = `${data.output}/${data.apiPath}`;
|
|
1978
2056
|
await fs3.promises.mkdir(apiOutputPath, { recursive: true });
|
|
1979
2057
|
if (fs3.existsSync(swaggerSource)) {
|
|
1980
2058
|
await fs3.promises.copyFile(
|
|
@@ -2016,7 +2094,7 @@ var DoculaBuilder = class {
|
|
|
2016
2094
|
if (!data.openApiUrl || !data.templates?.api) {
|
|
2017
2095
|
return;
|
|
2018
2096
|
}
|
|
2019
|
-
const apiPath = `${data.output}/
|
|
2097
|
+
const apiPath = `${data.output}/${data.apiPath}/index.html`;
|
|
2020
2098
|
const apiContent = await this.renderApiContent(data);
|
|
2021
2099
|
await fs3.promises.writeFile(apiPath, apiContent, "utf8");
|
|
2022
2100
|
}
|
|
@@ -2103,7 +2181,7 @@ var DoculaBuilder = class {
|
|
|
2103
2181
|
generatedHtml: new Writr(markdownContent).renderSync({ mdx: isMdx }),
|
|
2104
2182
|
preview: this.generateChangelogPreview(markdownContent, 500, isMdx),
|
|
2105
2183
|
previewImage,
|
|
2106
|
-
urlPath:
|
|
2184
|
+
urlPath: `/${this.options.changelogPath}/${slug}/index.html`,
|
|
2107
2185
|
lastModified: fs3.statSync(filePath).mtime.toISOString().split("T")[0]
|
|
2108
2186
|
};
|
|
2109
2187
|
}
|
|
@@ -2200,7 +2278,7 @@ var DoculaBuilder = class {
|
|
|
2200
2278
|
content: body,
|
|
2201
2279
|
generatedHtml: new Writr(body).renderSync(),
|
|
2202
2280
|
preview: this.generateChangelogPreview(body),
|
|
2203
|
-
urlPath:
|
|
2281
|
+
urlPath: `/${this.options.changelogPath}/${slug}/index.html`,
|
|
2204
2282
|
lastModified: dateString
|
|
2205
2283
|
};
|
|
2206
2284
|
}
|
|
@@ -2226,7 +2304,8 @@ var DoculaBuilder = class {
|
|
|
2226
2304
|
for (let page = 1; page <= totalPages; page++) {
|
|
2227
2305
|
const startIndex = (page - 1) * perPage;
|
|
2228
2306
|
const pageEntries = allEntries.slice(startIndex, startIndex + perPage);
|
|
2229
|
-
const
|
|
2307
|
+
const changelogOutputBase = `${data.output}/${data.changelogPath}`;
|
|
2308
|
+
const outputPath = page === 1 ? changelogOutputBase : `${changelogOutputBase}/page/${page}`;
|
|
2230
2309
|
const indexPath = `${outputPath}/index.html`;
|
|
2231
2310
|
const paginationData = {
|
|
2232
2311
|
...data,
|
|
@@ -2236,8 +2315,8 @@ var DoculaBuilder = class {
|
|
|
2236
2315
|
hasPagination: totalPages > 1,
|
|
2237
2316
|
hasNextPage: page < totalPages,
|
|
2238
2317
|
hasPrevPage: page > 1,
|
|
2239
|
-
nextPageUrl: page < totalPages ?
|
|
2240
|
-
prevPageUrl: page > 1 ? page === 2 ?
|
|
2318
|
+
nextPageUrl: page < totalPages ? `${data.changelogUrl}/page/${page + 1}/` : "",
|
|
2319
|
+
prevPageUrl: page > 1 ? page === 2 ? `${data.changelogUrl}/` : `${data.changelogUrl}/page/${page - 1}/` : ""
|
|
2241
2320
|
};
|
|
2242
2321
|
promises.push(
|
|
2243
2322
|
(async () => {
|
|
@@ -2259,7 +2338,7 @@ var DoculaBuilder = class {
|
|
|
2259
2338
|
}
|
|
2260
2339
|
const entryTemplate = `${data.templatePath}/${data.templates.changelogEntry}`;
|
|
2261
2340
|
const promises = data.changelogEntries.map(async (entry) => {
|
|
2262
|
-
const entryOutputPath = `${data.output}
|
|
2341
|
+
const entryOutputPath = `${data.output}/${data.changelogPath}/${entry.slug}`;
|
|
2263
2342
|
await fs3.promises.mkdir(entryOutputPath, { recursive: true });
|
|
2264
2343
|
const entryContent = await this._ecto.renderFromFile(
|
|
2265
2344
|
entryTemplate,
|
|
@@ -2281,7 +2360,7 @@ var DoculaBuilder = class {
|
|
|
2281
2360
|
for (const document of data.documents ?? []) {
|
|
2282
2361
|
if (document.isRoot) {
|
|
2283
2362
|
sidebarItems.unshift({
|
|
2284
|
-
path: document.urlPath.replace("index.html", "")
|
|
2363
|
+
path: `${data.baseUrl}${document.urlPath.replace("index.html", "")}`,
|
|
2285
2364
|
name: document.navTitle,
|
|
2286
2365
|
order: document.order
|
|
2287
2366
|
});
|
|
@@ -2303,7 +2382,7 @@ var DoculaBuilder = class {
|
|
|
2303
2382
|
}
|
|
2304
2383
|
sidebarItems[sectionIndex].children ??= [];
|
|
2305
2384
|
sidebarItems[sectionIndex].children.push({
|
|
2306
|
-
path: document.urlPath.replace("index.html", "")
|
|
2385
|
+
path: `${data.baseUrl}${document.urlPath.replace("index.html", "")}`,
|
|
2307
2386
|
name: document.navTitle,
|
|
2308
2387
|
order: document.order
|
|
2309
2388
|
});
|
|
@@ -2425,13 +2504,19 @@ var DoculaBuilder = class {
|
|
|
2425
2504
|
const isMdx = documentPath.endsWith(".mdx");
|
|
2426
2505
|
const fileExtension = isMdx ? ".mdx" : ".md";
|
|
2427
2506
|
const documentsFolderIndex = documentPath.lastIndexOf("/docs/");
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2507
|
+
const relativePath = documentPath.slice(documentsFolderIndex + 6);
|
|
2508
|
+
const docsPrefix = this.options.docsPath ? `/${this.options.docsPath}` : "";
|
|
2509
|
+
let urlPath = `${docsPrefix}/${relativePath}`.replace(
|
|
2510
|
+
fileExtension,
|
|
2511
|
+
"/index.html"
|
|
2512
|
+
);
|
|
2513
|
+
const isRoot = !relativePath.includes("/");
|
|
2514
|
+
if (isRoot) {
|
|
2515
|
+
if (relativePath === "index.md" || relativePath === "index.mdx") {
|
|
2516
|
+
urlPath = `${docsPrefix}/${relativePath}`.replace(
|
|
2517
|
+
fileExtension,
|
|
2518
|
+
".html"
|
|
2519
|
+
);
|
|
2435
2520
|
}
|
|
2436
2521
|
}
|
|
2437
2522
|
if (!this.hasTableOfContents(markdownContent)) {
|
|
@@ -2801,7 +2886,11 @@ ${entry}
|
|
|
2801
2886
|
openApiUrl: this.options.openApiUrl,
|
|
2802
2887
|
themeMode: this.options.themeMode,
|
|
2803
2888
|
cookieAuth: this.options.cookieAuth,
|
|
2804
|
-
headerLinks: this.options.headerLinks
|
|
2889
|
+
headerLinks: this.options.headerLinks,
|
|
2890
|
+
baseUrl: this.options.baseUrl,
|
|
2891
|
+
docsPath: this.options.docsPath,
|
|
2892
|
+
apiPath: this.options.apiPath,
|
|
2893
|
+
changelogPath: this.options.changelogPath
|
|
2805
2894
|
};
|
|
2806
2895
|
return this._hash.toHashSync(JSON.stringify(relevant));
|
|
2807
2896
|
}
|
package/package.json
CHANGED
package/templates/modern/api.hbs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
<head>
|
|
5
5
|
{{> header }}
|
|
6
|
-
<link rel="stylesheet" href="/css/api.css">
|
|
6
|
+
<link rel="stylesheet" href="{{baseUrl}}/css/api.css">
|
|
7
7
|
<title>API Reference - {{ siteTitle }}</title>
|
|
8
8
|
<meta name="description" content="API Reference for {{ siteTitle }}" />
|
|
9
9
|
</head>
|
|
@@ -250,7 +250,7 @@
|
|
|
250
250
|
{{> footer }}
|
|
251
251
|
{{> scripts }}
|
|
252
252
|
|
|
253
|
-
<script src="/js/api.js"></script>
|
|
253
|
+
<script src="{{baseUrl}}/js/api.js"></script>
|
|
254
254
|
</body>
|
|
255
255
|
|
|
256
256
|
</html>
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<main class="versions-container">
|
|
13
13
|
<div class="versions-content">
|
|
14
14
|
<div class="changelog-entry-nav">
|
|
15
|
-
<a href="/
|
|
15
|
+
<a href="{{changelogUrl}}/">← Back to Changelog</a>
|
|
16
16
|
</div>
|
|
17
17
|
<div class="changelog-entry changelog-entry-single">
|
|
18
18
|
<div class="changelog-entry-header">
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
{{#each entries as |entry|}}
|
|
17
17
|
<div class="changelog-entry">
|
|
18
18
|
<div class="changelog-entry-header">
|
|
19
|
-
<a class="changelog-entry-title" href="/
|
|
19
|
+
<a class="changelog-entry-title" href="{{changelogUrl}}/{{entry.slug}}/">{{entry.title}}</a>
|
|
20
20
|
{{#if entry.tag}}
|
|
21
21
|
<span class="changelog-tag changelog-tag-{{entry.tagClass}}">{{entry.tag}}</span>
|
|
22
22
|
{{/if}}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
<head>
|
|
5
5
|
{{> header }}
|
|
6
|
-
<link rel="stylesheet" href="/css/home.css">
|
|
6
|
+
<link rel="stylesheet" href="{{baseUrl}}/css/home.css">
|
|
7
7
|
<title>{{ siteTitle }}</title>
|
|
8
8
|
</head>
|
|
9
9
|
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
|
|
25
25
|
{{#if content}}
|
|
26
26
|
<header class="home-hero">
|
|
27
|
-
<img src="/logo.svg" alt="logo" />
|
|
27
|
+
<img src="{{baseUrl}}/logo.svg" alt="logo" />
|
|
28
28
|
{{#if announcement}}
|
|
29
29
|
<div class="announcement">{{{announcement}}}</div>
|
|
30
30
|
{{/if}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<a href="
|
|
1
|
+
<a href="{{apiUrl}}" class="home-docs-button">API Reference</a>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<a href="
|
|
1
|
+
<a href="{{docsUrl}}" class="home-docs-button">Documentation</a>
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<footer>
|
|
2
2
|
{{#if enableLlmsTxt}}
|
|
3
|
-
<a href="/llms.txt" class="footer__link">llms.txt</a>
|
|
3
|
+
<a href="{{baseUrl}}/llms.txt" class="footer__link">llms.txt</a>
|
|
4
4
|
{{/if}}
|
|
5
5
|
{{#if hasFeed}}
|
|
6
|
-
<a href="/feed.xml" class="footer__link" aria-label="RSS Feed">
|
|
6
|
+
<a href="{{baseUrl}}/feed.xml" class="footer__link" aria-label="RSS Feed">
|
|
7
7
|
<svg class="footer__icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><circle cx="6.18" cy="17.82" r="2.18"/><path d="M4 4.44v2.83c7.03 0 12.73 5.7 12.73 12.73h2.83c0-8.59-6.97-15.56-15.56-15.56zm0 5.66v2.83c3.9 0 7.07 3.17 7.07 7.07h2.83c0-5.47-4.43-9.9-9.9-9.9z"/></svg>
|
|
8
8
|
</a>
|
|
9
9
|
{{/if}}
|
|
@@ -4,24 +4,24 @@
|
|
|
4
4
|
<button class="mobile-menu-toggle" id="mobile-menu-toggle" aria-label="Toggle navigation menu">
|
|
5
5
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="4" x2="20" y1="12" y2="12"/><line x1="4" x2="20" y1="6" y2="6"/><line x1="4" x2="20" y1="18" y2="18"/></svg>
|
|
6
6
|
</button>
|
|
7
|
-
<a href="/">
|
|
8
|
-
<img alt="{{siteTitle}}" class="logo__img" src="/logo.svg">
|
|
7
|
+
<a href="{{baseUrl}}/">
|
|
8
|
+
<img alt="{{siteTitle}}" class="logo__img" src="{{baseUrl}}/logo.svg">
|
|
9
9
|
</a>
|
|
10
10
|
<nav class="header-bottom__nav">
|
|
11
11
|
{{#if hasDocuments}}
|
|
12
|
-
<a class="header-bottom__item" href="/
|
|
12
|
+
<a class="header-bottom__item" href="{{docsUrl}}/" id="nav-docs">
|
|
13
13
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 7v14"/><path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z"/></svg>
|
|
14
14
|
<span>Documentation</span>
|
|
15
15
|
</a>
|
|
16
16
|
{{/if}}
|
|
17
17
|
{{#if openApiUrl}}
|
|
18
|
-
<a class="header-bottom__item" href="
|
|
18
|
+
<a class="header-bottom__item" href="{{apiUrl}}" id="nav-api">
|
|
19
19
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m16 18 6-6-6-6"/><path d="m8 6-6 6 6 6"/></svg>
|
|
20
20
|
<span>API Reference</span>
|
|
21
21
|
</a>
|
|
22
22
|
{{/if}}
|
|
23
23
|
{{#if hasChangelog}}
|
|
24
|
-
<a class="header-bottom__item" href="
|
|
24
|
+
<a class="header-bottom__item" href="{{changelogUrl}}" id="nav-changelog">
|
|
25
25
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 6a13 13 0 0 0 8.4-2.8A1 1 0 0 1 21 4v12a1 1 0 0 1-1.6.8A13 13 0 0 0 11 14H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2z"/><path d="M6 14a12 12 0 0 0 2.4 7.2 2 2 0 0 0 3.2-2.4A8 8 0 0 1 10 14"/><path d="M8 6v8"/></svg>
|
|
26
26
|
<span>Changelog</span>
|
|
27
27
|
</a>
|
|
@@ -68,19 +68,19 @@
|
|
|
68
68
|
<aside class="mobile-sidebar" id="mobile-sidebar">
|
|
69
69
|
<nav class="mobile-nav">
|
|
70
70
|
{{#if hasDocuments}}
|
|
71
|
-
<a class="mobile-nav__item" href="/
|
|
71
|
+
<a class="mobile-nav__item" href="{{docsUrl}}/">
|
|
72
72
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 7v14"/><path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z"/></svg>
|
|
73
73
|
<span>Documentation</span>
|
|
74
74
|
</a>
|
|
75
75
|
{{/if}}
|
|
76
76
|
{{#if openApiUrl}}
|
|
77
|
-
<a class="mobile-nav__item" href="
|
|
77
|
+
<a class="mobile-nav__item" href="{{apiUrl}}">
|
|
78
78
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m16 18 6-6-6-6"/><path d="m8 6-6 6 6 6"/></svg>
|
|
79
79
|
<span>API Reference</span>
|
|
80
80
|
</a>
|
|
81
81
|
{{/if}}
|
|
82
82
|
{{#if hasChangelog}}
|
|
83
|
-
<a class="mobile-nav__item" href="
|
|
83
|
+
<a class="mobile-nav__item" href="{{changelogUrl}}">
|
|
84
84
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 6a13 13 0 0 0 8.4-2.8A1 1 0 0 1 21 4v12a1 1 0 0 1-1.6.8A13 13 0 0 0 11 14H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2z"/><path d="M6 14a12 12 0 0 0 2.4 7.2 2 2 0 0 0 3.2-2.4A8 8 0 0 1 10 14"/><path d="M8 6v8"/></svg>
|
|
85
85
|
<span>Changelog</span>
|
|
86
86
|
</a>
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<meta charset="UTF-8">
|
|
2
2
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
3
3
|
<meta name="description" content="{{siteDescription}}">
|
|
4
|
-
<link rel="stylesheet" href="/css/variables.css">
|
|
5
|
-
<link rel="stylesheet" href="/css/styles.css">
|
|
6
|
-
<link rel="stylesheet" href="/css/highlight/styles/base16/docula.css">
|
|
7
|
-
<link rel="icon" href="/favicon.ico">
|
|
4
|
+
<link rel="stylesheet" href="{{baseUrl}}/css/variables.css">
|
|
5
|
+
<link rel="stylesheet" href="{{baseUrl}}/css/styles.css">
|
|
6
|
+
<link rel="stylesheet" href="{{baseUrl}}/css/highlight/styles/base16/docula.css">
|
|
7
|
+
<link rel="icon" href="{{baseUrl}}/favicon.ico">
|
|
8
8
|
<script>
|
|
9
9
|
(function(){
|
|
10
10
|
window.__doculaThemeKey = 'docula:theme:' + ({{#if siteUrl}}'{{siteUrl}}'{{else}}location.origin{{/if}}).replace(/^https?:\/\//, '');
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<script src="/css/highlight/highlight.min.js"></script>
|
|
1
|
+
<script src="{{baseUrl}}/css/highlight/highlight.min.js"></script>
|
|
2
2
|
<script>
|
|
3
3
|
document.addEventListener('DOMContentLoaded', () => {
|
|
4
4
|
document.querySelectorAll('pre code').forEach(el => { el.textContent = el.textContent.trimEnd(); });
|