@blaaiz/docs-core 0.2.0 → 0.4.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/{chunk-3ZX4WIE3.js → chunk-JHN5XQPU.js} +184 -45
- package/dist/chunk-JHN5XQPU.js.map +1 -0
- package/dist/generator.cjs +114 -44
- package/dist/generator.cjs.map +1 -1
- package/dist/generator.js +20 -3
- package/dist/generator.js.map +1 -1
- package/dist/index.cjs +182 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +108 -7
- package/dist/index.d.ts +108 -7
- package/dist/index.js +1 -1
- package/dist/ui.cjs +1 -1
- package/dist/ui.cjs.map +1 -1
- package/dist/ui.js +1 -1
- package/dist/ui.js.map +1 -1
- package/package.json +1 -1
- package/skills/SKILL.md +59 -45
- package/dist/chunk-3ZX4WIE3.js.map +0 -1
|
@@ -1544,6 +1544,20 @@ function dirname(file) {
|
|
|
1544
1544
|
const i = file.lastIndexOf("/");
|
|
1545
1545
|
return i === -1 ? "" : file.slice(0, i);
|
|
1546
1546
|
}
|
|
1547
|
+
function firstDocFile(items) {
|
|
1548
|
+
for (const item of items) {
|
|
1549
|
+
if (item.kind === "doc") {
|
|
1550
|
+
return item.file;
|
|
1551
|
+
}
|
|
1552
|
+
if (item.kind === "group") {
|
|
1553
|
+
const found = firstDocFile(item.items);
|
|
1554
|
+
if (found !== void 0) {
|
|
1555
|
+
return found;
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
return void 0;
|
|
1560
|
+
}
|
|
1547
1561
|
function planDocsTree(navigation, options = {}) {
|
|
1548
1562
|
const apiDir = options.apiDir ?? "api";
|
|
1549
1563
|
const specs = [];
|
|
@@ -1551,6 +1565,9 @@ function planDocsTree(navigation, options = {}) {
|
|
|
1551
1565
|
const apiGroups = [];
|
|
1552
1566
|
const metas = [];
|
|
1553
1567
|
const rootPages = [];
|
|
1568
|
+
const apiTabDocPages = [];
|
|
1569
|
+
const apiTabs = navigation.filter((tab) => hasOpenApi(tab.items));
|
|
1570
|
+
const soleApiTab = apiTabs.length === 1;
|
|
1554
1571
|
for (const tab of navigation) {
|
|
1555
1572
|
if (hasOpenApi(tab.items)) {
|
|
1556
1573
|
planApiTab(tab);
|
|
@@ -1559,38 +1576,52 @@ function planDocsTree(navigation, options = {}) {
|
|
|
1559
1576
|
planDocTab(tab);
|
|
1560
1577
|
}
|
|
1561
1578
|
metas.unshift({ path: "meta.json", content: { pages: rootPages } });
|
|
1562
|
-
return { specs, apiPages, apiGroups, metas };
|
|
1579
|
+
return { specs, apiPages, apiGroups, metas, apiTabDocPages };
|
|
1563
1580
|
function planApiTab(tab) {
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1581
|
+
const tabDir = soleApiTab ? apiDir : slugify(tab.title);
|
|
1582
|
+
rootPages.push(tabDir);
|
|
1583
|
+
const at = apiGroups.length;
|
|
1584
|
+
const children = planApiItems(tab.items, tabDir);
|
|
1585
|
+
apiGroups.splice(at, 0, {
|
|
1586
|
+
dir: tabDir,
|
|
1587
|
+
title: tab.title,
|
|
1588
|
+
root: true,
|
|
1589
|
+
...tab.icon ? { icon: tab.icon } : {},
|
|
1590
|
+
children
|
|
1591
|
+
});
|
|
1592
|
+
}
|
|
1593
|
+
function planApiItems(items, dir) {
|
|
1594
|
+
const children = [];
|
|
1595
|
+
const takenFolders = /* @__PURE__ */ new Set();
|
|
1596
|
+
let order = 0;
|
|
1597
|
+
for (const item of items) {
|
|
1598
|
+
if (item.kind === "group") {
|
|
1599
|
+
const folder = slugify(item.title);
|
|
1600
|
+
if (takenFolders.has(folder)) {
|
|
1601
|
+
throw new Error(
|
|
1602
|
+
`[docs-core] Two sibling groups under '${dir}' share the folder name '${folder}'. Rename one of the groups in docs.json.`
|
|
1603
|
+
);
|
|
1604
|
+
}
|
|
1605
|
+
takenFolders.add(folder);
|
|
1606
|
+
const childDir = `${dir}/${folder}`;
|
|
1607
|
+
const at = apiGroups.length;
|
|
1608
|
+
const sub = planApiItems(item.items, childDir);
|
|
1609
|
+
apiGroups.splice(at, 0, { dir: childDir, title: item.title, children: sub });
|
|
1610
|
+
children.push({ order, folder });
|
|
1611
|
+
order += 1;
|
|
1568
1612
|
continue;
|
|
1569
1613
|
}
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
let order = 0;
|
|
1574
|
-
for (const page of item.items) {
|
|
1575
|
-
if (page.kind !== "openapi") {
|
|
1576
|
-
continue;
|
|
1577
|
-
}
|
|
1578
|
-
if (!specs.includes(page.file)) {
|
|
1579
|
-
specs.push(page.file);
|
|
1614
|
+
if (item.kind === "openapi") {
|
|
1615
|
+
if (!specs.includes(item.file)) {
|
|
1616
|
+
specs.push(item.file);
|
|
1580
1617
|
}
|
|
1581
|
-
apiPages.push({ file:
|
|
1618
|
+
apiPages.push({ file: item.file, method: item.method, apiPath: item.apiPath, dir, order });
|
|
1582
1619
|
order += 1;
|
|
1620
|
+
continue;
|
|
1583
1621
|
}
|
|
1622
|
+
apiTabDocPages.push(item.file);
|
|
1584
1623
|
}
|
|
1585
|
-
|
|
1586
|
-
path: `${apiDir}/meta.json`,
|
|
1587
|
-
content: {
|
|
1588
|
-
title: tab.title,
|
|
1589
|
-
root: true,
|
|
1590
|
-
...tab.icon ? { icon: tab.icon } : {},
|
|
1591
|
-
pages: groupDirs
|
|
1592
|
-
}
|
|
1593
|
-
});
|
|
1624
|
+
return children;
|
|
1594
1625
|
}
|
|
1595
1626
|
function planDocTab(tab) {
|
|
1596
1627
|
const directPages = tab.items.filter((item) => item.kind === "doc");
|
|
@@ -1601,36 +1632,58 @@ function planDocsTree(navigation, options = {}) {
|
|
|
1601
1632
|
}
|
|
1602
1633
|
return;
|
|
1603
1634
|
}
|
|
1604
|
-
const firstFile =
|
|
1635
|
+
const firstFile = firstDocFile(tab.items);
|
|
1605
1636
|
if (firstFile === void 0) {
|
|
1606
1637
|
return;
|
|
1607
1638
|
}
|
|
1608
1639
|
const tabDir = firstFile.split("/")[0] ?? "";
|
|
1609
1640
|
rootPages.push(tabDir);
|
|
1610
|
-
const tabPages = directPages.map((page) => basename(page.file));
|
|
1611
|
-
for (const group of groups) {
|
|
1612
|
-
const pages = group.items.filter((item) => item.kind === "doc");
|
|
1613
|
-
const groupDir = dirname(pages[0]?.file ?? "");
|
|
1614
|
-
const folder = groupDir.split("/").slice(1).join("/");
|
|
1615
|
-
if (folder === "") {
|
|
1616
|
-
tabPages.push(...pages.map((page) => basename(page.file)));
|
|
1617
|
-
continue;
|
|
1618
|
-
}
|
|
1619
|
-
tabPages.push(folder);
|
|
1620
|
-
metas.push({
|
|
1621
|
-
path: `${groupDir}/meta.json`,
|
|
1622
|
-
content: { title: group.title, pages: pages.map((page) => basename(page.file)) }
|
|
1623
|
-
});
|
|
1624
|
-
}
|
|
1625
1641
|
metas.push({
|
|
1626
1642
|
path: `${tabDir}/meta.json`,
|
|
1627
1643
|
content: {
|
|
1628
1644
|
title: tab.title,
|
|
1629
1645
|
root: true,
|
|
1630
1646
|
...tab.icon ? { icon: tab.icon } : {},
|
|
1631
|
-
pages:
|
|
1647
|
+
pages: planDocItems(tab.items, tabDir)
|
|
1648
|
+
}
|
|
1649
|
+
});
|
|
1650
|
+
}
|
|
1651
|
+
function planDocItems(items, dir) {
|
|
1652
|
+
const entries = [];
|
|
1653
|
+
for (const item of items) {
|
|
1654
|
+
if (item.kind === "doc") {
|
|
1655
|
+
entries.push(basename(item.file));
|
|
1656
|
+
continue;
|
|
1657
|
+
}
|
|
1658
|
+
if (item.kind !== "group") {
|
|
1659
|
+
continue;
|
|
1660
|
+
}
|
|
1661
|
+
const groupDir = planDocGroup(item, dir);
|
|
1662
|
+
if (groupDir === null) {
|
|
1663
|
+
continue;
|
|
1664
|
+
}
|
|
1665
|
+
if (groupDir === dir) {
|
|
1666
|
+
entries.push(...planDocItems(item.items, dir));
|
|
1667
|
+
continue;
|
|
1632
1668
|
}
|
|
1669
|
+
entries.push(groupDir.slice(dir.length + 1));
|
|
1670
|
+
}
|
|
1671
|
+
return entries;
|
|
1672
|
+
}
|
|
1673
|
+
function planDocGroup(group, dir) {
|
|
1674
|
+
const firstFile = firstDocFile(group.items);
|
|
1675
|
+
if (firstFile === void 0) {
|
|
1676
|
+
return null;
|
|
1677
|
+
}
|
|
1678
|
+
const groupDir = dirname(firstFile);
|
|
1679
|
+
if (groupDir === dir || groupDir === "") {
|
|
1680
|
+
return dir;
|
|
1681
|
+
}
|
|
1682
|
+
metas.push({
|
|
1683
|
+
path: `${groupDir}/meta.json`,
|
|
1684
|
+
content: { title: group.title, pages: planDocItems(group.items, groupDir) }
|
|
1633
1685
|
});
|
|
1686
|
+
return groupDir;
|
|
1634
1687
|
}
|
|
1635
1688
|
}
|
|
1636
1689
|
|
|
@@ -2526,6 +2579,92 @@ function createSignOut(options = {}) {
|
|
|
2526
2579
|
};
|
|
2527
2580
|
}
|
|
2528
2581
|
|
|
2582
|
+
// src/core/auth/site-auth.ts
|
|
2583
|
+
var notConfigured = () => new Response("This sign-in method is not configured for this site.", { status: 501 });
|
|
2584
|
+
var PUBLIC_SITE = {
|
|
2585
|
+
enabled: false,
|
|
2586
|
+
signInPath: "/signin",
|
|
2587
|
+
secretEnabled: false,
|
|
2588
|
+
googleEnabled: false,
|
|
2589
|
+
emailSignIn: () => Promise.resolve(notConfigured()),
|
|
2590
|
+
secretSignIn: () => Promise.resolve(notConfigured()),
|
|
2591
|
+
google: {
|
|
2592
|
+
start: () => notConfigured(),
|
|
2593
|
+
callback: () => Promise.resolve(notConfigured())
|
|
2594
|
+
}
|
|
2595
|
+
};
|
|
2596
|
+
function createSiteAuth(auth, options = {}) {
|
|
2597
|
+
if (auth === "public") {
|
|
2598
|
+
return {
|
|
2599
|
+
...PUBLIC_SITE,
|
|
2600
|
+
gate: () => Promise.resolve(null),
|
|
2601
|
+
signOut: createSignOut()
|
|
2602
|
+
};
|
|
2603
|
+
}
|
|
2604
|
+
return workspaceSiteAuth(auth, options);
|
|
2605
|
+
}
|
|
2606
|
+
function workspaceSiteAuth(auth, options) {
|
|
2607
|
+
const env = options.env ?? ((name) => process.env[name]);
|
|
2608
|
+
const signInPath = auth.signInPath ?? "/signin";
|
|
2609
|
+
const secure = auth.secureCookies ?? true;
|
|
2610
|
+
const ttlSeconds = auth.sessionTtlSeconds;
|
|
2611
|
+
const sessionSecretEnv = auth.sessionSecretEnv ?? "DOCS_SESSION_SECRET";
|
|
2612
|
+
const secret = env(sessionSecretEnv) ?? "";
|
|
2613
|
+
if (secret === "") {
|
|
2614
|
+
throw new DocsConfigError(
|
|
2615
|
+
`auth.mode is 'workspace': set the ${sessionSecretEnv} environment variable to a long random value (for example: openssl rand -hex 32).`
|
|
2616
|
+
);
|
|
2617
|
+
}
|
|
2618
|
+
const shared = {
|
|
2619
|
+
secret,
|
|
2620
|
+
allowedDomains: auth.allowedDomains,
|
|
2621
|
+
secureCookies: secure,
|
|
2622
|
+
signInPath,
|
|
2623
|
+
...ttlSeconds === void 0 ? {} : { ttlSeconds }
|
|
2624
|
+
};
|
|
2625
|
+
const emailEnabled = auth.providers.email === true;
|
|
2626
|
+
const accessSecret = auth.providers.secret ? env(auth.providers.secret.secretEnv ?? "DOCS_ACCESS_SECRET") ?? "" : "";
|
|
2627
|
+
const secretEnabled = accessSecret !== "";
|
|
2628
|
+
const googleConfig = auth.providers.google;
|
|
2629
|
+
const clientId = googleConfig ? env(googleConfig.clientIdEnv ?? "GOOGLE_CLIENT_ID") : void 0;
|
|
2630
|
+
const clientSecret = googleConfig ? env(googleConfig.clientSecretEnv ?? "GOOGLE_CLIENT_SECRET") : void 0;
|
|
2631
|
+
const googleEnabled = Boolean(googleConfig && clientId && clientSecret);
|
|
2632
|
+
const emailSignIn = emailEnabled ? createEmailSignIn(shared) : null;
|
|
2633
|
+
const secretSignIn = secretEnabled ? createSecretSignIn({ ...shared, accessSecret }) : null;
|
|
2634
|
+
const googleFor = (request) => {
|
|
2635
|
+
if (!googleEnabled || !googleConfig || !clientId || !clientSecret) {
|
|
2636
|
+
return null;
|
|
2637
|
+
}
|
|
2638
|
+
const origin = new URL(request.url).origin;
|
|
2639
|
+
const redirectPath = googleConfig.redirectPath ?? "/api/auth/google/callback";
|
|
2640
|
+
return createGoogleAuth({
|
|
2641
|
+
...shared,
|
|
2642
|
+
clientId,
|
|
2643
|
+
clientSecret,
|
|
2644
|
+
redirectUri: `${origin}${redirectPath}`
|
|
2645
|
+
});
|
|
2646
|
+
};
|
|
2647
|
+
return {
|
|
2648
|
+
enabled: true,
|
|
2649
|
+
signInPath,
|
|
2650
|
+
secretEnabled,
|
|
2651
|
+
googleEnabled,
|
|
2652
|
+
gate: createAuthGate({
|
|
2653
|
+
secret,
|
|
2654
|
+
allowedDomains: auth.allowedDomains,
|
|
2655
|
+
signInPath,
|
|
2656
|
+
publicPaths: [...options.publicPaths ?? ["/api/proxy"]]
|
|
2657
|
+
}),
|
|
2658
|
+
emailSignIn: (request) => emailSignIn?.(request) ?? Promise.resolve(notConfigured()),
|
|
2659
|
+
secretSignIn: (request) => secretSignIn?.(request) ?? Promise.resolve(notConfigured()),
|
|
2660
|
+
google: {
|
|
2661
|
+
start: (request) => googleFor(request)?.start(request) ?? notConfigured(),
|
|
2662
|
+
callback: (request) => googleFor(request)?.callback(request) ?? Promise.resolve(notConfigured())
|
|
2663
|
+
},
|
|
2664
|
+
signOut: createSignOut({ secureCookies: secure, redirectTo: signInPath })
|
|
2665
|
+
};
|
|
2666
|
+
}
|
|
2667
|
+
|
|
2529
2668
|
// src/core/proxy.ts
|
|
2530
2669
|
var DEFAULT_RATE_LIMIT_PER_MINUTE2 = 60;
|
|
2531
2670
|
var ProxyTargetError = class extends Error {
|
|
@@ -2979,6 +3118,6 @@ function mergeOpenApiDocuments(inputs, options) {
|
|
|
2979
3118
|
};
|
|
2980
3119
|
}
|
|
2981
3120
|
|
|
2982
|
-
export { AI_PROVIDER_MODELS, AI_PROVIDER_NAMES, AiConfigError, DocsConfigError, InvalidNavigationError, OpenApiMergeError, ProxyTargetError, SESSION_COOKIE, assertAllowedTarget, buildMetadata, buildRobots, buildSearchIndex, buildSessionCookie, buildSitemap, buildThemeCss, clearSessionCookie, createAskAiRoute, createAuthGate, createEmailSignIn, createGoogleAuth, createMarkdownRoute, createSecretSignIn, createSignOut, createTryItProxy, createTryItProxyRoute, defineDocsConfig, isAllowedEmail, mdxToMarkdown, mergeOpenApiDocuments, openApiOperationToMarkdown, parseNavigation, planDocsTree, readCookie, resolveAiConfig, searchIndex, signSession, unwrapProxyTarget, validateDocsConfig, verifySession };
|
|
2983
|
-
//# sourceMappingURL=chunk-
|
|
2984
|
-
//# sourceMappingURL=chunk-
|
|
3121
|
+
export { AI_PROVIDER_MODELS, AI_PROVIDER_NAMES, AiConfigError, DocsConfigError, InvalidNavigationError, OpenApiMergeError, ProxyTargetError, SESSION_COOKIE, assertAllowedTarget, buildMetadata, buildRobots, buildSearchIndex, buildSessionCookie, buildSitemap, buildThemeCss, clearSessionCookie, createAskAiRoute, createAuthGate, createEmailSignIn, createGoogleAuth, createMarkdownRoute, createSecretSignIn, createSignOut, createSiteAuth, createTryItProxy, createTryItProxyRoute, defineDocsConfig, isAllowedEmail, mdxToMarkdown, mergeOpenApiDocuments, openApiOperationToMarkdown, parseNavigation, planDocsTree, readCookie, resolveAiConfig, searchIndex, signSession, unwrapProxyTarget, validateDocsConfig, verifySession };
|
|
3122
|
+
//# sourceMappingURL=chunk-JHN5XQPU.js.map
|
|
3123
|
+
//# sourceMappingURL=chunk-JHN5XQPU.js.map
|