@knowcode/doc-builder 1.2.5 ā 1.2.7
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/CHANGELOG.md +25 -0
- package/lib/core-builder.js +205 -2
- package/lib/deploy.js +55 -32
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,31 @@ All notable changes to @knowcode/doc-builder will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.2.7] - 2025-07-19
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- Comprehensive debugging output showing package version and file existence checks
|
|
12
|
+
- Support for `index.md` as primary source for index.html (higher priority than README.md)
|
|
13
|
+
- Informative default index.html page when no README.md or index.md exists
|
|
14
|
+
- List of available HTML files in default index page
|
|
15
|
+
- Version and debug information in generated pages
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
- Fixed infinite redirect loop in deploy.js when no README.html exists
|
|
19
|
+
- Improved index.html creation reliability with better file detection
|
|
20
|
+
- Better error messages and guidance when documentation is missing
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- Enhanced logging throughout build and deploy processes
|
|
24
|
+
- Redirect to first available HTML file instead of infinite loop
|
|
25
|
+
- More descriptive console output during index.html creation
|
|
26
|
+
|
|
27
|
+
## [1.2.6] - 2025-07-19
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
- **Index.html creation** - Fixed root URL not serving documentation by creating index.html from README.html
|
|
31
|
+
- Added index.html creation in both build and deploy processes for reliability
|
|
32
|
+
|
|
8
33
|
## [1.2.5] - 2025-07-19
|
|
9
34
|
|
|
10
35
|
### Fixed
|
package/lib/core-builder.js
CHANGED
|
@@ -448,6 +448,10 @@ async function buildDocumentation(config) {
|
|
|
448
448
|
const docsDir = path.join(process.cwd(), config.docsDir);
|
|
449
449
|
const outputDir = path.join(process.cwd(), config.outputDir);
|
|
450
450
|
|
|
451
|
+
// Log version for debugging
|
|
452
|
+
const packageJson = require('../package.json');
|
|
453
|
+
console.log(chalk.blue(`š¦ Using @knowcode/doc-builder v${packageJson.version}`));
|
|
454
|
+
|
|
451
455
|
// Check and create placeholder README.md if missing
|
|
452
456
|
console.log(chalk.blue('š Checking documentation structure...'));
|
|
453
457
|
const readmeGenerated = await createPlaceholderReadme(docsDir, config);
|
|
@@ -490,18 +494,49 @@ async function buildDocumentation(config) {
|
|
|
490
494
|
await createAuthPages(outputDir, config);
|
|
491
495
|
}
|
|
492
496
|
|
|
497
|
+
// Create index.html from index.html, README.html, or generate default
|
|
498
|
+
const indexPath = path.join(outputDir, 'index.html');
|
|
499
|
+
const indexSourcePath = path.join(outputDir, 'index.html'); // from index.md
|
|
500
|
+
const readmePath = path.join(outputDir, 'README.html');
|
|
501
|
+
|
|
502
|
+
console.log(chalk.blue('š Checking for index.html creation...'));
|
|
503
|
+
console.log(chalk.gray(` - index.html exists: ${fs.existsSync(indexPath)})`));
|
|
504
|
+
console.log(chalk.gray(` - README.html exists: ${fs.existsSync(readmePath)})`));
|
|
505
|
+
|
|
506
|
+
if (!fs.existsSync(indexPath)) {
|
|
507
|
+
if (fs.existsSync(readmePath)) {
|
|
508
|
+
await fs.copy(readmePath, indexPath);
|
|
509
|
+
console.log(chalk.green('ā
Created index.html from README.html'));
|
|
510
|
+
} else {
|
|
511
|
+
// No README.html, create informative default page
|
|
512
|
+
console.log(chalk.yellow('ā ļø No README.html found, creating default index.html'));
|
|
513
|
+
const defaultIndex = await createDefaultIndexPage(outputDir, config, packageJson.version);
|
|
514
|
+
await fs.writeFile(indexPath, defaultIndex);
|
|
515
|
+
console.log(chalk.green('ā
Created default index.html with instructions'));
|
|
516
|
+
}
|
|
517
|
+
} else {
|
|
518
|
+
console.log(chalk.gray('ā¹ļø index.html already exists (likely from index.md)'));
|
|
519
|
+
}
|
|
520
|
+
|
|
493
521
|
console.log(chalk.green('ā
Documentation build complete!'));
|
|
494
522
|
}
|
|
495
523
|
|
|
496
524
|
// Create placeholder README.md if missing
|
|
497
525
|
async function createPlaceholderReadme(docsDir, config) {
|
|
498
526
|
const readmePath = path.join(docsDir, 'README.md');
|
|
527
|
+
const indexPath = path.join(docsDir, 'index.md');
|
|
499
528
|
|
|
500
|
-
// Check if README.md already exists
|
|
529
|
+
// Check if README.md or index.md already exists
|
|
501
530
|
if (fs.existsSync(readmePath)) {
|
|
531
|
+
console.log(chalk.gray(' ā README.md found'));
|
|
502
532
|
return false; // README already exists, no need to create
|
|
503
533
|
}
|
|
504
534
|
|
|
535
|
+
if (fs.existsSync(indexPath)) {
|
|
536
|
+
console.log(chalk.gray(' ā index.md found'));
|
|
537
|
+
return false; // index.md exists, no need for README
|
|
538
|
+
}
|
|
539
|
+
|
|
505
540
|
const siteName = config.siteName || 'Documentation';
|
|
506
541
|
const currentDate = new Date().toISOString().split('T')[0];
|
|
507
542
|
|
|
@@ -664,9 +699,177 @@ async function createAuthPages(outputDir, config) {
|
|
|
664
699
|
await fs.writeFile(path.join(outputDir, 'logout.html'), logoutHTML);
|
|
665
700
|
}
|
|
666
701
|
|
|
702
|
+
// Create default index page when no documentation exists
|
|
703
|
+
async function createDefaultIndexPage(outputDir, config, version) {
|
|
704
|
+
const siteName = config.siteName || 'Documentation';
|
|
705
|
+
const currentDate = new Date().toISOString();
|
|
706
|
+
|
|
707
|
+
// List all HTML files in the output directory
|
|
708
|
+
const htmlFiles = [];
|
|
709
|
+
async function findHtmlFiles(dir, baseDir = dir) {
|
|
710
|
+
const items = await fs.readdir(dir);
|
|
711
|
+
for (const item of items) {
|
|
712
|
+
const fullPath = path.join(dir, item);
|
|
713
|
+
const stat = await fs.stat(fullPath);
|
|
714
|
+
if (stat.isDirectory() && !item.startsWith('.')) {
|
|
715
|
+
await findHtmlFiles(fullPath, baseDir);
|
|
716
|
+
} else if (item.endsWith('.html') && item !== 'index.html' && item !== 'login.html' && item !== 'logout.html') {
|
|
717
|
+
const relativePath = path.relative(baseDir, fullPath);
|
|
718
|
+
htmlFiles.push(relativePath);
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
await findHtmlFiles(outputDir);
|
|
724
|
+
|
|
725
|
+
let fileListHtml = '';
|
|
726
|
+
if (htmlFiles.length > 0) {
|
|
727
|
+
fileListHtml = `
|
|
728
|
+
<div class="existing-files">
|
|
729
|
+
<h2>š Available Documentation</h2>
|
|
730
|
+
<p>The following documentation files were found:</p>
|
|
731
|
+
<ul>
|
|
732
|
+
${htmlFiles.map(file => `<li><a href="${file}">${file}</a></li>`).join('\n ')}
|
|
733
|
+
</ul>
|
|
734
|
+
</div>`;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
return `<!DOCTYPE html>
|
|
738
|
+
<html lang="en">
|
|
739
|
+
<head>
|
|
740
|
+
<meta charset="UTF-8">
|
|
741
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
742
|
+
<title>Welcome to ${siteName}</title>
|
|
743
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
744
|
+
<link rel="stylesheet" href="/css/notion-style.css">
|
|
745
|
+
<link rel="stylesheet" href="/css/style.css">
|
|
746
|
+
<style>
|
|
747
|
+
.welcome-container {
|
|
748
|
+
max-width: 800px;
|
|
749
|
+
margin: 50px auto;
|
|
750
|
+
padding: 40px;
|
|
751
|
+
background: var(--bg-secondary);
|
|
752
|
+
border-radius: 12px;
|
|
753
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
754
|
+
}
|
|
755
|
+
.welcome-container h1 {
|
|
756
|
+
color: var(--text-primary);
|
|
757
|
+
margin-bottom: 20px;
|
|
758
|
+
}
|
|
759
|
+
.welcome-container h2 {
|
|
760
|
+
color: var(--text-primary);
|
|
761
|
+
margin-top: 30px;
|
|
762
|
+
margin-bottom: 15px;
|
|
763
|
+
}
|
|
764
|
+
.welcome-container p {
|
|
765
|
+
color: var(--text-secondary);
|
|
766
|
+
line-height: 1.6;
|
|
767
|
+
margin-bottom: 15px;
|
|
768
|
+
}
|
|
769
|
+
.welcome-container pre {
|
|
770
|
+
background: var(--bg-tertiary);
|
|
771
|
+
padding: 20px;
|
|
772
|
+
border-radius: 8px;
|
|
773
|
+
overflow-x: auto;
|
|
774
|
+
margin: 20px 0;
|
|
775
|
+
}
|
|
776
|
+
.welcome-container code {
|
|
777
|
+
font-family: 'JetBrains Mono', monospace;
|
|
778
|
+
font-size: 14px;
|
|
779
|
+
}
|
|
780
|
+
.welcome-container ul {
|
|
781
|
+
margin: 20px 0;
|
|
782
|
+
padding-left: 30px;
|
|
783
|
+
}
|
|
784
|
+
.welcome-container li {
|
|
785
|
+
margin: 8px 0;
|
|
786
|
+
}
|
|
787
|
+
.version-info {
|
|
788
|
+
margin-top: 40px;
|
|
789
|
+
padding-top: 20px;
|
|
790
|
+
border-top: 1px solid var(--border-color);
|
|
791
|
+
font-size: 12px;
|
|
792
|
+
color: var(--text-tertiary);
|
|
793
|
+
}
|
|
794
|
+
.existing-files {
|
|
795
|
+
background: var(--bg-primary);
|
|
796
|
+
padding: 20px;
|
|
797
|
+
border-radius: 8px;
|
|
798
|
+
margin: 30px 0;
|
|
799
|
+
}
|
|
800
|
+
.existing-files a {
|
|
801
|
+
color: var(--link-color);
|
|
802
|
+
text-decoration: none;
|
|
803
|
+
}
|
|
804
|
+
.existing-files a:hover {
|
|
805
|
+
text-decoration: underline;
|
|
806
|
+
}
|
|
807
|
+
</style>
|
|
808
|
+
</head>
|
|
809
|
+
<body>
|
|
810
|
+
<div class="welcome-container">
|
|
811
|
+
<h1>š Welcome to ${siteName}</h1>
|
|
812
|
+
|
|
813
|
+
<p>This documentation site was generated by <strong>@knowcode/doc-builder</strong>. To add your own content, follow the instructions below.</p>
|
|
814
|
+
|
|
815
|
+
<h2>š Getting Started</h2>
|
|
816
|
+
|
|
817
|
+
<p>To create your documentation homepage, create either of these files in your <code>docs/</code> directory:</p>
|
|
818
|
+
|
|
819
|
+
<ul>
|
|
820
|
+
<li><code>index.md</code> - Primary homepage (highest priority)</li>
|
|
821
|
+
<li><code>README.md</code> - Alternative homepage</li>
|
|
822
|
+
</ul>
|
|
823
|
+
|
|
824
|
+
<h2>š Example Content</h2>
|
|
825
|
+
|
|
826
|
+
<p>Create <code>docs/index.md</code> with content like:</p>
|
|
827
|
+
|
|
828
|
+
<pre><code># Welcome to My Project
|
|
829
|
+
|
|
830
|
+
This is the homepage for my documentation.
|
|
831
|
+
|
|
832
|
+
## Features
|
|
833
|
+
|
|
834
|
+
- Feature 1
|
|
835
|
+
- Feature 2
|
|
836
|
+
- Feature 3
|
|
837
|
+
|
|
838
|
+
## Getting Started
|
|
839
|
+
|
|
840
|
+
1. Install the package
|
|
841
|
+
2. Configure your settings
|
|
842
|
+
3. Start building!</code></pre>
|
|
843
|
+
|
|
844
|
+
<h2>š§ Next Steps</h2>
|
|
845
|
+
|
|
846
|
+
<ol>
|
|
847
|
+
<li>Create <code>docs/index.md</code> or <code>docs/README.md</code></li>
|
|
848
|
+
<li>Add more markdown files for additional pages</li>
|
|
849
|
+
<li>Rebuild: <code>npx @knowcode/doc-builder build</code></li>
|
|
850
|
+
<li>Deploy: <code>npx @knowcode/doc-builder deploy</code></li>
|
|
851
|
+
</ol>
|
|
852
|
+
|
|
853
|
+
${fileListHtml}
|
|
854
|
+
|
|
855
|
+
<div class="version-info">
|
|
856
|
+
<p><strong>Debug Information:</strong></p>
|
|
857
|
+
<ul>
|
|
858
|
+
<li>doc-builder version: ${version}</li>
|
|
859
|
+
<li>Generated: ${currentDate}</li>
|
|
860
|
+
<li>Site name: ${siteName}</li>
|
|
861
|
+
<li>No index.md or README.md found in docs directory</li>
|
|
862
|
+
</ul>
|
|
863
|
+
</div>
|
|
864
|
+
</div>
|
|
865
|
+
</body>
|
|
866
|
+
</html>`;
|
|
867
|
+
}
|
|
868
|
+
|
|
667
869
|
module.exports = {
|
|
668
870
|
buildDocumentation,
|
|
669
871
|
processMarkdownContent,
|
|
670
872
|
generateHTML,
|
|
671
|
-
createPlaceholderReadme
|
|
873
|
+
createPlaceholderReadme,
|
|
874
|
+
createDefaultIndexPage
|
|
672
875
|
};
|
package/lib/deploy.js
CHANGED
|
@@ -341,42 +341,41 @@ async function deployToVercel(config, isProd = false) {
|
|
|
341
341
|
async function prepareDeployment(config) {
|
|
342
342
|
const outputDir = path.join(process.cwd(), config.outputDir || 'html');
|
|
343
343
|
|
|
344
|
-
//
|
|
344
|
+
// Log version for debugging
|
|
345
|
+
const packageJson = require('../package.json');
|
|
346
|
+
console.log(chalk.blue(`\nš¦ Preparing deployment with @knowcode/doc-builder v${packageJson.version}`));
|
|
347
|
+
|
|
348
|
+
// Create index.html from README.html if needed
|
|
345
349
|
const indexPath = path.join(outputDir, 'index.html');
|
|
350
|
+
console.log(chalk.gray(` - Checking index.html: ${fs.existsSync(indexPath) ? 'exists' : 'missing'}}`));
|
|
351
|
+
|
|
346
352
|
if (!fs.existsSync(indexPath)) {
|
|
347
353
|
const readmePath = path.join(outputDir, 'README.html');
|
|
354
|
+
console.log(chalk.gray(` - Checking README.html: ${fs.existsSync(readmePath) ? 'exists' : 'missing'}}`));
|
|
355
|
+
|
|
348
356
|
if (fs.existsSync(readmePath)) {
|
|
349
|
-
//
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
<head>
|
|
353
|
-
<meta charset="UTF-8">
|
|
354
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
355
|
-
<title>${config.siteName || 'Documentation'}</title>
|
|
356
|
-
<link rel="stylesheet" href="/css/style.css">
|
|
357
|
-
<script>
|
|
358
|
-
// Immediate redirect with fallback
|
|
359
|
-
window.location.replace('/README.html');
|
|
360
|
-
</script>
|
|
361
|
-
</head>
|
|
362
|
-
<body>
|
|
363
|
-
<div style="text-align: center; margin-top: 50px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;">
|
|
364
|
-
<p>Loading documentation...</p>
|
|
365
|
-
<p>If you are not redirected automatically, <a href="/README.html">click here</a>.</p>
|
|
366
|
-
</div>
|
|
367
|
-
</body>
|
|
368
|
-
</html>`;
|
|
369
|
-
fs.writeFileSync(indexPath, redirectHtml);
|
|
370
|
-
console.log(chalk.green('ā
Created index.html redirect to README.html'));
|
|
357
|
+
// Copy README.html to index.html for proper root page
|
|
358
|
+
fs.copyFileSync(readmePath, indexPath);
|
|
359
|
+
console.log(chalk.green('ā
Created index.html from README.html'));
|
|
371
360
|
} else {
|
|
372
|
-
// If no README.html,
|
|
373
|
-
|
|
374
|
-
|
|
361
|
+
// If no README.html, find first available HTML file or create informative page
|
|
362
|
+
console.log(chalk.yellow('ā ļø No README.html found, looking for other HTML files...'));
|
|
363
|
+
|
|
364
|
+
// Find first available HTML file
|
|
365
|
+
const htmlFiles = fs.readdirSync(outputDir)
|
|
366
|
+
.filter(file => file.endsWith('.html') && file !== 'index.html' && file !== 'login.html' && file !== 'logout.html')
|
|
367
|
+
.sort();
|
|
368
|
+
|
|
369
|
+
if (htmlFiles.length > 0) {
|
|
370
|
+
// Redirect to first HTML file
|
|
371
|
+
const firstFile = htmlFiles[0];
|
|
372
|
+
console.log(chalk.green(`ā
Creating index.html redirect to ${firstFile}`));
|
|
373
|
+
const redirectIndex = `<!DOCTYPE html>
|
|
375
374
|
<html>
|
|
376
375
|
<head>
|
|
377
376
|
<meta charset="UTF-8">
|
|
378
377
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
379
|
-
<meta http-equiv="refresh" content="0; url
|
|
378
|
+
<meta http-equiv="refresh" content="0; url=${firstFile}">
|
|
380
379
|
<title>${config.siteName || 'Documentation'}</title>
|
|
381
380
|
<link rel="stylesheet" href="/css/style.css">
|
|
382
381
|
<link rel="stylesheet" href="/css/notion-style.css">
|
|
@@ -384,15 +383,39 @@ async function prepareDeployment(config) {
|
|
|
384
383
|
<body>
|
|
385
384
|
<div style="text-align: center; margin-top: 50px; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;">
|
|
386
385
|
<h1>š ${config.siteName || 'Documentation'}</h1>
|
|
387
|
-
<p>
|
|
388
|
-
<p><a href="
|
|
386
|
+
<p>Redirecting to documentation...</p>
|
|
387
|
+
<p><a href="${firstFile}" style="color: #0366d6;">Click here if not redirected automatically</a></p>
|
|
389
388
|
</div>
|
|
390
389
|
</body>
|
|
391
390
|
</html>`;
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
391
|
+
fs.writeFileSync(indexPath, redirectIndex);
|
|
392
|
+
console.log(chalk.green(`ā
Created index.html redirect to ${firstFile}`));
|
|
393
|
+
} else {
|
|
394
|
+
// No HTML files at all - this should never happen after build
|
|
395
|
+
console.log(chalk.red('ā No HTML files found in output directory!'));
|
|
396
|
+
console.log(chalk.yellow('š This indicates a build issue. Please run: npx @knowcode/doc-builder build'));
|
|
397
|
+
|
|
398
|
+
// Create emergency fallback page
|
|
399
|
+
const { createDefaultIndexPage } = require('./core-builder');
|
|
400
|
+
const fallbackIndex = await createDefaultIndexPage(outputDir, config, packageJson.version);
|
|
401
|
+
fs.writeFileSync(indexPath, fallbackIndex);
|
|
402
|
+
console.log(chalk.green('ā
Created fallback index.html with instructions'));
|
|
403
|
+
}
|
|
395
404
|
}
|
|
405
|
+
} else {
|
|
406
|
+
console.log(chalk.gray(' ā index.html already exists'));
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
// Final check - log what files exist
|
|
410
|
+
console.log(chalk.blue('\nš Final deployment state:'));
|
|
411
|
+
const finalFiles = fs.readdirSync(outputDir)
|
|
412
|
+
.filter(file => file.endsWith('.html'))
|
|
413
|
+
.slice(0, 5); // Show first 5 HTML files
|
|
414
|
+
finalFiles.forEach(file => {
|
|
415
|
+
console.log(chalk.gray(` - ${file}`));
|
|
416
|
+
});
|
|
417
|
+
if (fs.readdirSync(outputDir).filter(f => f.endsWith('.html')).length > 5) {
|
|
418
|
+
console.log(chalk.gray(` - ... and ${fs.readdirSync(outputDir).filter(f => f.endsWith('.html')).length - 5} more HTML files`));
|
|
396
419
|
}
|
|
397
420
|
}
|
|
398
421
|
|