@knowcode/doc-builder 1.9.20 ā 1.9.22
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/cli.js +15 -1
- package/doc-builder.config.js +4 -2
- package/doc-builder.config.js.backup.1754567425847 +124 -0
- package/doc-builder.config.js.backup.1754568137859 +126 -0
- package/html/README.html +3 -3
- package/html/about-doc-builder.html +3 -3
- package/html/documentation-index.html +3 -3
- package/html/guides/authentication-default-change.html +3 -3
- package/html/guides/authentication-guide.html +3 -3
- package/html/guides/claude-workflow-guide.html +3 -3
- package/html/guides/configuration-guide.html +3 -3
- package/html/guides/documentation-standards.html +3 -3
- package/html/guides/html-embedding-guide.html +3 -3
- package/html/guides/image-modal-guide.html +3 -3
- package/html/guides/phosphor-icons-guide.html +3 -3
- package/html/guides/private-directory-authentication-troubleshooting.html +3 -3
- package/html/guides/private-directory-authentication.html +3 -3
- package/html/guides/public-site-deployment.html +3 -3
- package/html/guides/search-engine-verification-guide.html +3 -3
- package/html/guides/seo-guide.html +3 -3
- package/html/guides/seo-optimization-guide.html +3 -3
- package/html/guides/supabase-authentication-complete-guide.html +3 -3
- package/html/guides/troubleshooting-guide.html +3 -3
- package/html/guides/windows-setup-guide.html +3 -3
- package/html/image-modal-test.html +3 -3
- package/html/index.html +3 -3
- package/html/private/cache-control-anti-pattern.html +3 -3
- package/html/private/launch/README.html +3 -3
- package/html/private/launch/auth-cleanup-summary.html +3 -3
- package/html/private/launch/bubble-plugin-specification.html +3 -3
- package/html/private/launch/go-to-market-strategy.html +3 -3
- package/html/private/launch/launch-announcements.html +3 -3
- package/html/private/launch/vercel-deployment-auth-setup.html +3 -3
- package/html/private/next-steps-walkthrough.html +3 -3
- package/html/private/supabase-auth-implementation-completed.html +3 -3
- package/html/private/supabase-auth-implementation-plan.html +3 -3
- package/html/private/supabase-auth-integration-plan.html +3 -3
- package/html/private/supabase-auth-setup-guide.html +3 -3
- package/html/private/test-private-doc.html +3 -3
- package/html/private/user-management-tooling.html +3 -3
- package/html/prompts/beautiful-documentation-design.html +3 -3
- package/html/prompts/markdown-document-standards.html +3 -3
- package/html/prompts/project-rename-strategy-sasha-publish.html +3 -3
- package/html/sitemap.xml +59 -59
- package/html/test-questions/how-does-it-work%3F.html +3 -3
- package/html/test-questions/step-1%3A%20getting-started.html +3 -3
- package/html/test-questions/what-is-the-purpose.html +3 -3
- package/html/vercel-cli-setup-guide.html +3 -3
- package/html/vercel-first-time-setup-guide.html +3 -3
- package/html-static/404.html +115 -0
- package/html-static/README.html +456 -0
- package/html-static/about-doc-builder.html +425 -0
- package/html-static/css/notion-style.css +2426 -0
- package/html-static/documentation-index.html +405 -0
- package/html-static/guides/authentication-default-change.html +304 -0
- package/html-static/guides/authentication-guide.html +443 -0
- package/html-static/guides/claude-workflow-guide.html +1008 -0
- package/html-static/guides/configuration-guide.html +406 -0
- package/html-static/guides/documentation-standards.html +628 -0
- package/html-static/guides/html-embedding-guide.html +395 -0
- package/html-static/guides/image-modal-guide.html +449 -0
- package/html-static/guides/phosphor-icons-guide.html +518 -0
- package/html-static/guides/private-directory-authentication-troubleshooting.html +489 -0
- package/html-static/guides/private-directory-authentication.html +475 -0
- package/html-static/guides/public-site-deployment.html +365 -0
- package/html-static/guides/search-engine-verification-guide.html +476 -0
- package/html-static/guides/seo-guide.html +595 -0
- package/html-static/guides/seo-optimization-guide.html +821 -0
- package/html-static/guides/supabase-authentication-complete-guide.html +800 -0
- package/html-static/guides/troubleshooting-guide.html +567 -0
- package/html-static/guides/windows-setup-guide.html +793 -0
- package/html-static/image-modal-test.html +252 -0
- package/html-static/index.html +456 -0
- package/html-static/js/main.js +1692 -0
- package/html-static/prompts/Screenshot 2025-08-02 at 08.49.55.png +0 -0
- package/html-static/prompts/beautiful-documentation-design.html +718 -0
- package/html-static/prompts/markdown-document-standards.html +356 -0
- package/html-static/prompts/project-rename-strategy-sasha-publish.html +464 -0
- package/html-static/robots.txt +5 -0
- package/html-static/sitemap.xml +195 -0
- package/html-static/test-questions/how-does-it-work%3F.html +228 -0
- package/html-static/test-questions/step-1%3A%20getting-started.html +223 -0
- package/html-static/test-questions/what-is-the-purpose.html +227 -0
- package/html-static/vercel-cli-setup-guide.html +429 -0
- package/html-static/vercel-first-time-setup-guide.html +388 -0
- package/lib/config.js +9 -2
- package/lib/core-builder.js +177 -14
- package/package.json +1 -1
package/lib/core-builder.js
CHANGED
|
@@ -361,10 +361,38 @@ function generateFaviconTag(favicon) {
|
|
|
361
361
|
return `<link rel="icon" href="${favicon}">`;
|
|
362
362
|
}
|
|
363
363
|
|
|
364
|
+
// Generate static HTML (without authentication and with relative paths)
|
|
365
|
+
function generateStaticHTML(title, content, navigation, currentPath = '', config = {}, originalContent = '', frontMatter = {}) {
|
|
366
|
+
// Use regular generateHTML but force disable auth features and use relative paths
|
|
367
|
+
const staticConfig = {
|
|
368
|
+
...config,
|
|
369
|
+
features: {
|
|
370
|
+
...config.features,
|
|
371
|
+
authentication: false,
|
|
372
|
+
privateDirectoryAuth: false
|
|
373
|
+
},
|
|
374
|
+
// Special flag to indicate this is static output (for relative paths)
|
|
375
|
+
isStaticOutput: true
|
|
376
|
+
};
|
|
377
|
+
|
|
378
|
+
return generateHTML(title, content, navigation, currentPath, staticConfig, originalContent, frontMatter);
|
|
379
|
+
}
|
|
380
|
+
|
|
364
381
|
// Generate HTML from template
|
|
365
382
|
function generateHTML(title, content, navigation, currentPath = '', config = {}, originalContent = '', frontMatter = {}) {
|
|
366
|
-
|
|
367
|
-
const
|
|
383
|
+
// For normal output, use standard depth calculation
|
|
384
|
+
const pathParts = currentPath.split('/').filter(p => p);
|
|
385
|
+
let depth = pathParts.length;
|
|
386
|
+
let relativePath = depth > 0 ? '../'.repeat(depth) : '';
|
|
387
|
+
|
|
388
|
+
// For static output, calculate depth differently (exclude the filename)
|
|
389
|
+
if (config.isStaticOutput) {
|
|
390
|
+
depth = pathParts.length > 1 ? pathParts.length - 1 : 0;
|
|
391
|
+
relativePath = depth > 0 ? '../'.repeat(depth) : '';
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// For static output, use relative paths; for normal output, use absolute paths
|
|
395
|
+
const resourcePath = config.isStaticOutput ? relativePath : '/';
|
|
368
396
|
|
|
369
397
|
const siteName = config.siteName || 'Documentation';
|
|
370
398
|
const siteDescription = config.siteDescription || 'Documentation site';
|
|
@@ -471,7 +499,7 @@ ${seoTags}
|
|
|
471
499
|
<script src="https://cdn.jsdelivr.net/npm/mermaid@10.6.1/dist/mermaid.min.js"></script>
|
|
472
500
|
|
|
473
501
|
<!-- Styles -->
|
|
474
|
-
<link rel="stylesheet" href="
|
|
502
|
+
<link rel="stylesheet" href="${resourcePath}css/notion-style.css">
|
|
475
503
|
|
|
476
504
|
${(config.features?.authentication === 'supabase' || config.features?.privateDirectoryAuth === true) ? `
|
|
477
505
|
<!-- Hide content until auth check -->
|
|
@@ -517,7 +545,7 @@ ${seoTags}
|
|
|
517
545
|
<!-- Header -->
|
|
518
546
|
<header class="header">
|
|
519
547
|
<div class="header-content">
|
|
520
|
-
<a href="/index.html" class="logo">${siteName}</a>
|
|
548
|
+
<a href="${config.isStaticOutput ? relativePath + 'index.html' : '/index.html'}" class="logo">${siteName}</a>
|
|
521
549
|
|
|
522
550
|
<div class="header-actions">
|
|
523
551
|
<div class="deployment-info">
|
|
@@ -603,9 +631,9 @@ ${seoTags}
|
|
|
603
631
|
}
|
|
604
632
|
};
|
|
605
633
|
</script>
|
|
606
|
-
<script src="
|
|
634
|
+
<script src="${resourcePath}js/main.js"></script>
|
|
607
635
|
${(config.features?.authentication === 'supabase' || config.features?.privateDirectoryAuth === true) ? `<script src="https://unpkg.com/@supabase/supabase-js@2"></script>
|
|
608
|
-
<script src="
|
|
636
|
+
<script src="${resourcePath}js/auth.js"></script>` : ''}
|
|
609
637
|
</body>
|
|
610
638
|
</html>`;
|
|
611
639
|
}
|
|
@@ -733,7 +761,9 @@ function buildNavigationStructure(files, currentFile, config = {}) {
|
|
|
733
761
|
|
|
734
762
|
// Check if this folder has a README.md file to link to
|
|
735
763
|
const readmeFile = folderData.files.find(f => f.displayName === 'README');
|
|
736
|
-
const folderLink = readmeFile ?
|
|
764
|
+
const folderLink = readmeFile ?
|
|
765
|
+
`href="${config.isStaticOutput ? readmeFile.urlPath : '/' + readmeFile.urlPath}"` :
|
|
766
|
+
'href="#"';
|
|
737
767
|
|
|
738
768
|
// Get folder description for tooltip
|
|
739
769
|
const folderDescription = folderDescriptions[folderName] || '';
|
|
@@ -789,7 +819,8 @@ function buildNavigationStructure(files, currentFile, config = {}) {
|
|
|
789
819
|
isActive = ' active';
|
|
790
820
|
}
|
|
791
821
|
|
|
792
|
-
|
|
822
|
+
// Use relative paths for static output
|
|
823
|
+
const linkPath = config.isStaticOutput ? file.urlPath : '/' + file.urlPath;
|
|
793
824
|
const tooltip = file.summary ? ` data-tooltip="${escapeHtml(file.summary)}"` : '';
|
|
794
825
|
const icon = getIconForStatus(file.status || 'default', false, config);
|
|
795
826
|
|
|
@@ -854,7 +885,8 @@ function buildNavigationStructure(files, currentFile, config = {}) {
|
|
|
854
885
|
if (currentFile === file.urlPath) {
|
|
855
886
|
isActive = ' active';
|
|
856
887
|
}
|
|
857
|
-
|
|
888
|
+
// Use relative paths for static output
|
|
889
|
+
const linkPath = config.isStaticOutput ? file.urlPath : '/' + file.urlPath;
|
|
858
890
|
const tooltip = file.summary ? ` data-tooltip="${escapeHtml(file.summary)}"` : '';
|
|
859
891
|
const icon = getIconForStatus(file.status || 'default', false, config);
|
|
860
892
|
additionalFiles += `
|
|
@@ -873,7 +905,7 @@ function buildNavigationStructure(files, currentFile, config = {}) {
|
|
|
873
905
|
}
|
|
874
906
|
|
|
875
907
|
// Process single markdown file
|
|
876
|
-
async function processMarkdownFile(filePath, outputPath, allFiles, config) {
|
|
908
|
+
async function processMarkdownFile(filePath, outputPath, allFiles, config, useStaticHTML = false) {
|
|
877
909
|
const rawContent = await fs.readFile(filePath, 'utf-8');
|
|
878
910
|
const fileName = path.basename(filePath, '.md');
|
|
879
911
|
const relativePath = path.relative(config.docsDir, filePath);
|
|
@@ -903,10 +935,14 @@ async function processMarkdownFile(filePath, outputPath, allFiles, config) {
|
|
|
903
935
|
const htmlContent = processMarkdownContent(content, config);
|
|
904
936
|
|
|
905
937
|
// Build navigation - pass config to handle private file filtering
|
|
906
|
-
|
|
938
|
+
// For static HTML, we need to build navigation with relative paths
|
|
939
|
+
const navConfig = useStaticHTML ? { ...config, isStaticOutput: true } : config;
|
|
940
|
+
const navigation = buildNavigationStructure(allFiles, urlPath, navConfig);
|
|
907
941
|
|
|
908
942
|
// Generate full HTML (pass original content and front matter for SEO)
|
|
909
|
-
const html =
|
|
943
|
+
const html = useStaticHTML
|
|
944
|
+
? generateStaticHTML(title, htmlContent, navigation, urlPath, config, content, frontMatter)
|
|
945
|
+
: generateHTML(title, htmlContent, navigation, urlPath, config, content, frontMatter);
|
|
910
946
|
|
|
911
947
|
// Write file
|
|
912
948
|
await fs.ensureDir(path.dirname(outputPath));
|
|
@@ -916,7 +952,7 @@ async function processMarkdownFile(filePath, outputPath, allFiles, config) {
|
|
|
916
952
|
}
|
|
917
953
|
|
|
918
954
|
// Get all markdown files
|
|
919
|
-
async function getAllMarkdownFiles(dir, baseDir = dir) {
|
|
955
|
+
async function getAllMarkdownFiles(dir, baseDir = dir, options = {}) {
|
|
920
956
|
const files = [];
|
|
921
957
|
const items = await fs.readdir(dir);
|
|
922
958
|
|
|
@@ -924,8 +960,13 @@ async function getAllMarkdownFiles(dir, baseDir = dir) {
|
|
|
924
960
|
const fullPath = path.join(dir, item);
|
|
925
961
|
const stat = await fs.stat(fullPath);
|
|
926
962
|
|
|
963
|
+
// Skip private directories if excludePrivate is true
|
|
964
|
+
if (stat.isDirectory() && options.excludePrivate && item === 'private') {
|
|
965
|
+
continue;
|
|
966
|
+
}
|
|
967
|
+
|
|
927
968
|
if (stat.isDirectory() && !item.startsWith('.') && !item.startsWith('_')) {
|
|
928
|
-
const subFiles = await getAllMarkdownFiles(fullPath, baseDir);
|
|
969
|
+
const subFiles = await getAllMarkdownFiles(fullPath, baseDir, options);
|
|
929
970
|
files.push(...subFiles);
|
|
930
971
|
} else if (item.endsWith('.md') && !item.startsWith('_')) {
|
|
931
972
|
const relativePath = path.relative(baseDir, fullPath);
|
|
@@ -950,6 +991,11 @@ async function getAllMarkdownFiles(dir, baseDir = dir) {
|
|
|
950
991
|
relativePath.startsWith('private/') ||
|
|
951
992
|
relativePath.startsWith('private\\');
|
|
952
993
|
|
|
994
|
+
// Skip private files if excludePrivate is true
|
|
995
|
+
if (options.excludePrivate && isPrivate) {
|
|
996
|
+
continue;
|
|
997
|
+
}
|
|
998
|
+
|
|
953
999
|
files.push({
|
|
954
1000
|
path: fullPath,
|
|
955
1001
|
relativePath,
|
|
@@ -1251,6 +1297,122 @@ async function buildDocumentation(config) {
|
|
|
1251
1297
|
}
|
|
1252
1298
|
}
|
|
1253
1299
|
|
|
1300
|
+
// Generate static version if enabled
|
|
1301
|
+
if (config.features?.staticOutput !== false) {
|
|
1302
|
+
console.log(chalk.blue('\nš Generating static version (no auth, no private content)...'));
|
|
1303
|
+
|
|
1304
|
+
const staticOutputDir = path.join(process.cwd(), config.staticOutputDir || 'html-static');
|
|
1305
|
+
|
|
1306
|
+
// Ensure static output directory exists
|
|
1307
|
+
await fs.ensureDir(staticOutputDir);
|
|
1308
|
+
|
|
1309
|
+
// Get files excluding private directories
|
|
1310
|
+
const staticFiles = await getAllMarkdownFiles(docsDir, docsDir, { excludePrivate: true });
|
|
1311
|
+
console.log(chalk.gray(` Found ${staticFiles.length} public files (private files excluded)`));
|
|
1312
|
+
|
|
1313
|
+
// Process files for static output
|
|
1314
|
+
for (const file of staticFiles) {
|
|
1315
|
+
const outputPath = path.join(staticOutputDir, file.urlPath);
|
|
1316
|
+
await processMarkdownFile(file.path, outputPath, staticFiles, config, true);
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1319
|
+
// Copy assets to static directory
|
|
1320
|
+
const assetsDir = path.join(__dirname, '../assets');
|
|
1321
|
+
const cssSource = path.join(assetsDir, 'css');
|
|
1322
|
+
const jsSource = path.join(assetsDir, 'js');
|
|
1323
|
+
|
|
1324
|
+
if (fs.existsSync(cssSource)) {
|
|
1325
|
+
await fs.copy(cssSource, path.join(staticOutputDir, 'css'), { overwrite: true });
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
if (fs.existsSync(jsSource)) {
|
|
1329
|
+
await fs.copy(jsSource, path.join(staticOutputDir, 'js'), { overwrite: true });
|
|
1330
|
+
// Don't generate auth.js for static version
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
// Copy 404.html for handling .md redirects
|
|
1334
|
+
const notFoundSource = path.join(assetsDir, '404.html');
|
|
1335
|
+
if (fs.existsSync(notFoundSource)) {
|
|
1336
|
+
await fs.copy(notFoundSource, path.join(staticOutputDir, '404.html'), { overwrite: true });
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
// Create index.html from README.html or generate default
|
|
1340
|
+
const staticIndexPath = path.join(staticOutputDir, 'index.html');
|
|
1341
|
+
const staticReadmePath = path.join(staticOutputDir, 'README.html');
|
|
1342
|
+
|
|
1343
|
+
if (fs.existsSync(staticReadmePath)) {
|
|
1344
|
+
await fs.copy(staticReadmePath, staticIndexPath);
|
|
1345
|
+
} else if (staticFiles.length > 0) {
|
|
1346
|
+
// Generate a default index that lists available pages
|
|
1347
|
+
const defaultIndex = await createDefaultIndexPage(staticOutputDir, config, packageJson.version);
|
|
1348
|
+
await fs.writeFile(staticIndexPath, defaultIndex);
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
// Copy attachments to static directory if enabled
|
|
1352
|
+
if (config.features?.attachments !== false) {
|
|
1353
|
+
const attachmentTypes = config.attachmentTypes || [
|
|
1354
|
+
'.pdf', '.doc', '.docx', '.xls', '.xlsx', '.csv', '.ppt', '.pptx', '.txt', '.rtf',
|
|
1355
|
+
'.html', '.htm',
|
|
1356
|
+
'.zip', '.tar', '.gz', '.7z', '.rar',
|
|
1357
|
+
'.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp', '.ico', '.bmp',
|
|
1358
|
+
'.json', '.xml', '.yaml', '.yml', '.toml',
|
|
1359
|
+
'.mp4', '.mp3', '.wav', '.avi', '.mov'
|
|
1360
|
+
];
|
|
1361
|
+
|
|
1362
|
+
try {
|
|
1363
|
+
// Get attachment files excluding private directories
|
|
1364
|
+
const allAttachmentFiles = await getAllAttachmentFiles(docsDir, docsDir, attachmentTypes);
|
|
1365
|
+
const staticAttachmentFiles = [];
|
|
1366
|
+
for (const file of allAttachmentFiles) {
|
|
1367
|
+
if (!file.relativePath.startsWith('private/') && !file.relativePath.startsWith('private\\')) {
|
|
1368
|
+
staticAttachmentFiles.push(file);
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
if (staticAttachmentFiles.length > 0) {
|
|
1373
|
+
await copyAttachmentFiles(staticAttachmentFiles, docsDir, staticOutputDir);
|
|
1374
|
+
}
|
|
1375
|
+
} catch (error) {
|
|
1376
|
+
console.warn(chalk.yellow(`Warning: Error copying attachments to static output: ${error.message}`));
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
// Generate SEO files for static version if enabled
|
|
1381
|
+
if (config.seo?.enabled && config.seo?.siteUrl) {
|
|
1382
|
+
// Collect all HTML files for sitemap
|
|
1383
|
+
const staticPages = [];
|
|
1384
|
+
const walkDir = (dir, baseDir = '') => {
|
|
1385
|
+
const items = fs.readdirSync(dir);
|
|
1386
|
+
items.forEach(item => {
|
|
1387
|
+
const fullPath = path.join(dir, item);
|
|
1388
|
+
const stat = fs.statSync(fullPath);
|
|
1389
|
+
if (stat.isDirectory()) {
|
|
1390
|
+
walkDir(fullPath, path.join(baseDir, item));
|
|
1391
|
+
} else if (item.endsWith('.html')) {
|
|
1392
|
+
staticPages.push({
|
|
1393
|
+
path: baseDir ? path.join(baseDir, item) : item,
|
|
1394
|
+
modified: stat.mtime
|
|
1395
|
+
});
|
|
1396
|
+
}
|
|
1397
|
+
});
|
|
1398
|
+
};
|
|
1399
|
+
|
|
1400
|
+
walkDir(staticOutputDir);
|
|
1401
|
+
|
|
1402
|
+
if (config.seo.generateSitemap) {
|
|
1403
|
+
await generateSitemap(staticPages, config.seo.siteUrl, staticOutputDir);
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
if (config.seo.generateRobotsTxt) {
|
|
1407
|
+
await generateRobotsTxt(config.seo.siteUrl, staticOutputDir, {
|
|
1408
|
+
hasAuthentication: false
|
|
1409
|
+
});
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
console.log(chalk.green(`ā
Static version generated in ${config.staticOutputDir || 'html-static'}/`));
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1254
1416
|
console.log(chalk.green('\nā
Documentation build complete!'));
|
|
1255
1417
|
}
|
|
1256
1418
|
|
|
@@ -1571,6 +1733,7 @@ module.exports = {
|
|
|
1571
1733
|
buildDocumentation,
|
|
1572
1734
|
processMarkdownContent,
|
|
1573
1735
|
generateHTML,
|
|
1736
|
+
generateStaticHTML,
|
|
1574
1737
|
createPlaceholderReadme,
|
|
1575
1738
|
createDefaultIndexPage
|
|
1576
1739
|
};
|