@knowcode/doc-builder 1.7.4 → 1.7.6
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/.claude/settings.local.json +6 -1
- package/CHANGELOG.md +50 -0
- package/README.md +47 -7
- package/RELEASE-NOTES-1.7.5.md +64 -0
- package/add-user-clive.sql +35 -0
- package/add-user-lindsay-fixed.sql +85 -0
- package/add-user-lindsay.sql +68 -0
- package/add-user-pmorgan.sql +35 -0
- package/add-user-robbie.sql +35 -0
- package/add-wru-users.sql +105 -0
- package/cli.js +223 -8
- package/grant-access.sql +15 -0
- package/html/README.html +14 -4
- package/html/auth.js +97 -0
- package/html/documentation-index.html +14 -4
- package/html/guides/authentication-default-change.html +302 -0
- package/html/guides/authentication-guide.html +32 -14
- package/html/guides/cache-control-anti-pattern.html +361 -0
- package/html/guides/claude-workflow-guide.html +14 -4
- package/html/guides/documentation-standards.html +14 -4
- package/html/guides/next-steps-walkthrough.html +638 -0
- package/html/guides/phosphor-icons-guide.html +14 -4
- package/html/guides/public-site-deployment.html +363 -0
- package/html/guides/search-engine-verification-guide.html +14 -4
- package/html/guides/seo-guide.html +14 -4
- package/html/guides/seo-optimization-guide.html +14 -4
- package/html/guides/supabase-auth-implementation-plan.html +543 -0
- package/html/guides/supabase-auth-integration-plan.html +671 -0
- package/html/guides/supabase-auth-setup-guide.html +498 -0
- package/html/guides/troubleshooting-guide.html +14 -4
- package/html/guides/vercel-deployment-auth-setup.html +337 -0
- package/html/guides/windows-setup-guide.html +14 -4
- package/html/index.html +14 -4
- package/html/launch/README.html +14 -4
- package/html/launch/bubble-plugin-specification.html +14 -4
- package/html/launch/go-to-market-strategy.html +14 -4
- package/html/launch/launch-announcements.html +14 -4
- package/html/login.html +102 -0
- package/html/logout.html +18 -0
- package/html/sitemap.xml +69 -21
- package/html/vercel-cli-setup-guide.html +14 -4
- package/html/vercel-first-time-setup-guide.html +14 -4
- package/lib/config.js +33 -29
- package/lib/core-builder.js +142 -88
- package/lib/supabase-auth.js +295 -0
- package/manage-users.sql +191 -0
- package/package.json +2 -1
- package/public-config.js +22 -0
- package/public-html/404.html +115 -0
- package/public-html/README.html +149 -0
- package/public-html/css/notion-style.css +2036 -0
- package/public-html/index.html +149 -0
- package/public-html/js/main.js +1485 -0
- package/quick-test-commands.md +40 -0
- package/recordings/Screenshot 2025-07-24 at 18.22.01.png +0 -0
- package/setup-database.sql +41 -0
- package/test-auth-config.js +17 -0
- package/test-docs/README.md +39 -0
- package/test-html/404.html +115 -0
- package/test-html/README.html +172 -0
- package/test-html/auth.js +97 -0
- package/test-html/css/notion-style.css +2036 -0
- package/test-html/index.html +172 -0
- package/test-html/js/auth.js +97 -0
- package/test-html/js/main.js +1485 -0
- package/test-html/login.html +102 -0
- package/test-html/logout.html +18 -0
- package/update-domain.sql +9 -0
- package/view-all-users.sql +40 -0
- package/wru-auth-config.js +17 -0
- /package/{assets → public-html}/js/auth.js +0 -0
package/lib/config.js
CHANGED
|
@@ -19,7 +19,7 @@ const defaultConfig = {
|
|
|
19
19
|
|
|
20
20
|
// Features
|
|
21
21
|
features: {
|
|
22
|
-
authentication: false,
|
|
22
|
+
authentication: false, // false (no auth) or 'supabase' (secure auth)
|
|
23
23
|
changelog: true,
|
|
24
24
|
mermaid: true,
|
|
25
25
|
tooltips: true,
|
|
@@ -30,13 +30,15 @@ const defaultConfig = {
|
|
|
30
30
|
phosphorSize: '1.2em', // Relative to text size
|
|
31
31
|
normalizeTitle: true, // Auto-normalize all-caps titles to title case
|
|
32
32
|
showPdfDownload: true, // Show PDF download icon in header
|
|
33
|
-
menuDefaultOpen: true
|
|
33
|
+
menuDefaultOpen: true, // Menu/sidebar open by default
|
|
34
|
+
attachments: true // Copy attachments (Excel, PDF, etc.) to output
|
|
34
35
|
},
|
|
35
36
|
|
|
36
|
-
// Authentication (
|
|
37
|
+
// Authentication - Supabase only (basic auth removed for security)
|
|
37
38
|
auth: {
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
supabaseUrl: '',
|
|
40
|
+
supabaseAnonKey: '',
|
|
41
|
+
siteId: ''
|
|
40
42
|
},
|
|
41
43
|
|
|
42
44
|
// Changelog settings
|
|
@@ -77,7 +79,21 @@ const defaultConfig = {
|
|
|
77
79
|
generateSitemap: true,
|
|
78
80
|
generateRobotsTxt: true,
|
|
79
81
|
customMetaTags: []
|
|
80
|
-
}
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
// Attachment file types to copy
|
|
85
|
+
attachmentTypes: [
|
|
86
|
+
// Documents
|
|
87
|
+
'.pdf', '.doc', '.docx', '.xls', '.xlsx', '.csv', '.ppt', '.pptx', '.txt', '.rtf',
|
|
88
|
+
// Archives
|
|
89
|
+
'.zip', '.tar', '.gz', '.7z', '.rar',
|
|
90
|
+
// Images
|
|
91
|
+
'.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp', '.ico', '.bmp',
|
|
92
|
+
// Data files
|
|
93
|
+
'.json', '.xml', '.yaml', '.yml', '.toml',
|
|
94
|
+
// Other
|
|
95
|
+
'.mp4', '.mp3', '.wav', '.avi', '.mov'
|
|
96
|
+
]
|
|
81
97
|
};
|
|
82
98
|
|
|
83
99
|
/**
|
|
@@ -90,7 +106,7 @@ const notionInspiredPreset = {
|
|
|
90
106
|
siteDescription: 'Transforming complex sales through intelligent automation',
|
|
91
107
|
|
|
92
108
|
features: {
|
|
93
|
-
authentication:
|
|
109
|
+
authentication: false, // Default to no auth - can be enabled with 'supabase'
|
|
94
110
|
changelog: true,
|
|
95
111
|
mermaid: true,
|
|
96
112
|
tooltips: true,
|
|
@@ -101,12 +117,14 @@ const notionInspiredPreset = {
|
|
|
101
117
|
phosphorSize: '1.2em',
|
|
102
118
|
normalizeTitle: true,
|
|
103
119
|
showPdfDownload: true,
|
|
104
|
-
menuDefaultOpen: true
|
|
120
|
+
menuDefaultOpen: true,
|
|
121
|
+
attachments: true
|
|
105
122
|
},
|
|
106
123
|
|
|
107
124
|
auth: {
|
|
108
|
-
|
|
109
|
-
|
|
125
|
+
supabaseUrl: process.env.SUPABASE_URL || '',
|
|
126
|
+
supabaseAnonKey: process.env.SUPABASE_ANON_KEY || '',
|
|
127
|
+
siteId: process.env.DOC_SITE_ID || ''
|
|
110
128
|
},
|
|
111
129
|
|
|
112
130
|
changelog: {
|
|
@@ -259,6 +277,9 @@ async function loadConfig(configPath, options = {}) {
|
|
|
259
277
|
if (options.menuClosed === true) {
|
|
260
278
|
config.features.menuDefaultOpen = false;
|
|
261
279
|
}
|
|
280
|
+
if (options.attachments === false) {
|
|
281
|
+
config.features.attachments = false;
|
|
282
|
+
}
|
|
262
283
|
|
|
263
284
|
// Legacy mode - auto-detect structure
|
|
264
285
|
if (options.legacy) {
|
|
@@ -307,32 +328,15 @@ async function createDefaultConfig() {
|
|
|
307
328
|
{
|
|
308
329
|
type: 'confirm',
|
|
309
330
|
name: 'authentication',
|
|
310
|
-
message: 'Enable authentication?',
|
|
331
|
+
message: 'Enable Supabase authentication?',
|
|
311
332
|
initial: false
|
|
312
|
-
},
|
|
313
|
-
{
|
|
314
|
-
type: prev => prev ? 'text' : null,
|
|
315
|
-
name: 'authUsername',
|
|
316
|
-
message: 'Authentication username:',
|
|
317
|
-
initial: 'admin'
|
|
318
|
-
},
|
|
319
|
-
{
|
|
320
|
-
type: prev => prev ? 'password' : null,
|
|
321
|
-
name: 'authPassword',
|
|
322
|
-
message: 'Authentication password:',
|
|
323
|
-
initial: 'password'
|
|
324
333
|
}
|
|
325
334
|
]);
|
|
326
335
|
|
|
327
336
|
const config = { ...defaultConfig };
|
|
328
337
|
config.siteName = answers.siteName;
|
|
329
338
|
config.siteDescription = answers.siteDescription;
|
|
330
|
-
config.features.authentication = answers.authentication;
|
|
331
|
-
|
|
332
|
-
if (answers.authentication) {
|
|
333
|
-
config.auth.username = answers.authUsername;
|
|
334
|
-
config.auth.password = answers.authPassword;
|
|
335
|
-
}
|
|
339
|
+
config.features.authentication = answers.authentication ? 'supabase' : false;
|
|
336
340
|
|
|
337
341
|
return config;
|
|
338
342
|
}
|
package/lib/core-builder.js
CHANGED
|
@@ -3,6 +3,7 @@ const path = require('path');
|
|
|
3
3
|
const marked = require('marked');
|
|
4
4
|
const chalk = require('chalk');
|
|
5
5
|
const matter = require('gray-matter');
|
|
6
|
+
const SupabaseAuth = require('./supabase-auth');
|
|
6
7
|
const {
|
|
7
8
|
generateMetaTags,
|
|
8
9
|
generateJSONLD,
|
|
@@ -344,6 +345,26 @@ ${seoTags}
|
|
|
344
345
|
<!-- Styles -->
|
|
345
346
|
<link rel="stylesheet" href="/css/notion-style.css">
|
|
346
347
|
|
|
348
|
+
${config.features?.authentication === 'supabase' ? `
|
|
349
|
+
<!-- Hide content until auth check -->
|
|
350
|
+
<style>
|
|
351
|
+
body {
|
|
352
|
+
visibility: hidden;
|
|
353
|
+
opacity: 0;
|
|
354
|
+
transition: opacity 0.3s ease;
|
|
355
|
+
}
|
|
356
|
+
body.authenticated {
|
|
357
|
+
visibility: visible;
|
|
358
|
+
opacity: 1;
|
|
359
|
+
}
|
|
360
|
+
/* Show login/logout pages immediately */
|
|
361
|
+
body.auth-page {
|
|
362
|
+
visibility: visible;
|
|
363
|
+
opacity: 1;
|
|
364
|
+
}
|
|
365
|
+
</style>
|
|
366
|
+
` : ''}
|
|
367
|
+
|
|
347
368
|
<!-- Favicon -->
|
|
348
369
|
${generateFaviconTag(config.favicon || '✨')}
|
|
349
370
|
|
|
@@ -367,7 +388,7 @@ ${seoTags}
|
|
|
367
388
|
})} UTC</span>
|
|
368
389
|
</div>
|
|
369
390
|
|
|
370
|
-
${config.features?.authentication ? `
|
|
391
|
+
${config.features?.authentication === 'supabase' ? `
|
|
371
392
|
<a href="${relativePath}logout.html" class="logout-btn" title="Logout">
|
|
372
393
|
<i class="fas fa-sign-out-alt"></i>
|
|
373
394
|
</a>
|
|
@@ -435,7 +456,8 @@ ${seoTags}
|
|
|
435
456
|
};
|
|
436
457
|
</script>
|
|
437
458
|
<script src="/js/main.js"></script>
|
|
438
|
-
${config.features?.authentication ? `<script src="/js
|
|
459
|
+
${config.features?.authentication === 'supabase' ? `<script src="https://unpkg.com/@supabase/supabase-js@2"></script>
|
|
460
|
+
<script src="/js/auth.js"></script>` : ''}
|
|
439
461
|
</body>
|
|
440
462
|
</html>`;
|
|
441
463
|
}
|
|
@@ -731,6 +753,62 @@ async function getAllMarkdownFiles(dir, baseDir = dir) {
|
|
|
731
753
|
return files;
|
|
732
754
|
}
|
|
733
755
|
|
|
756
|
+
// Get all attachment files
|
|
757
|
+
async function getAllAttachmentFiles(dir, baseDir = dir, attachmentTypes) {
|
|
758
|
+
const files = [];
|
|
759
|
+
const items = await fs.readdir(dir);
|
|
760
|
+
|
|
761
|
+
for (const item of items) {
|
|
762
|
+
const fullPath = path.join(dir, item);
|
|
763
|
+
const stat = await fs.stat(fullPath);
|
|
764
|
+
|
|
765
|
+
if (stat.isDirectory() && !item.startsWith('.')) {
|
|
766
|
+
// Recursively scan subdirectories
|
|
767
|
+
const subFiles = await getAllAttachmentFiles(fullPath, baseDir, attachmentTypes);
|
|
768
|
+
files.push(...subFiles);
|
|
769
|
+
} else {
|
|
770
|
+
// Check if file is an attachment type
|
|
771
|
+
const ext = path.extname(item).toLowerCase();
|
|
772
|
+
if (attachmentTypes.includes(ext) && !item.startsWith('.')) {
|
|
773
|
+
const relativePath = path.relative(baseDir, fullPath);
|
|
774
|
+
files.push({
|
|
775
|
+
path: fullPath,
|
|
776
|
+
relativePath,
|
|
777
|
+
size: stat.size
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
return files;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
// Copy attachment files to output directory
|
|
787
|
+
async function copyAttachmentFiles(attachmentFiles, docsDir, outputDir) {
|
|
788
|
+
let totalSize = 0;
|
|
789
|
+
let copiedCount = 0;
|
|
790
|
+
|
|
791
|
+
for (const file of attachmentFiles) {
|
|
792
|
+
try {
|
|
793
|
+
const outputPath = path.join(outputDir, file.relativePath);
|
|
794
|
+
const outputDirPath = path.dirname(outputPath);
|
|
795
|
+
|
|
796
|
+
// Create directory if it doesn't exist
|
|
797
|
+
await fs.ensureDir(outputDirPath);
|
|
798
|
+
|
|
799
|
+
// Copy the file
|
|
800
|
+
await fs.copy(file.path, outputPath, { overwrite: true });
|
|
801
|
+
|
|
802
|
+
totalSize += file.size;
|
|
803
|
+
copiedCount++;
|
|
804
|
+
} catch (error) {
|
|
805
|
+
console.warn(chalk.yellow(`Warning: Could not copy ${file.relativePath}: ${error.message}`));
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
return { copiedCount, totalSize };
|
|
810
|
+
}
|
|
811
|
+
|
|
734
812
|
// Main build function
|
|
735
813
|
async function buildDocumentation(config) {
|
|
736
814
|
const docsDir = path.join(process.cwd(), config.docsDir);
|
|
@@ -778,21 +856,12 @@ async function buildDocumentation(config) {
|
|
|
778
856
|
if (fs.existsSync(jsSource)) {
|
|
779
857
|
await fs.copy(jsSource, path.join(outputDir, 'js'), { overwrite: true });
|
|
780
858
|
|
|
781
|
-
//
|
|
782
|
-
if (config.features?.authentication) {
|
|
783
|
-
|
|
784
|
-
const authDest = path.join(outputDir, 'auth.js');
|
|
785
|
-
if (fs.existsSync(authSource)) {
|
|
786
|
-
await fs.copy(authSource, authDest, { overwrite: true });
|
|
787
|
-
}
|
|
859
|
+
// Generate Supabase auth script if authentication is enabled
|
|
860
|
+
if (config.features?.authentication === 'supabase') {
|
|
861
|
+
await generateSupabaseAuthFiles(outputDir, config);
|
|
788
862
|
}
|
|
789
863
|
}
|
|
790
864
|
|
|
791
|
-
// Create auth pages if needed
|
|
792
|
-
if (config.features?.authentication) {
|
|
793
|
-
await createAuthPages(outputDir, config);
|
|
794
|
-
}
|
|
795
|
-
|
|
796
865
|
// Copy 404.html for handling .md redirects
|
|
797
866
|
const notFoundSource = path.join(assetsDir, '404.html');
|
|
798
867
|
if (fs.existsSync(notFoundSource)) {
|
|
@@ -928,12 +997,46 @@ async function buildDocumentation(config) {
|
|
|
928
997
|
// Generate robots.txt if enabled
|
|
929
998
|
if (config.seo.generateRobotsTxt) {
|
|
930
999
|
await generateRobotsTxt(config.seo.siteUrl, outputDir, {
|
|
931
|
-
hasAuthentication: config.features?.authentication
|
|
1000
|
+
hasAuthentication: config.features?.authentication === 'supabase'
|
|
932
1001
|
});
|
|
933
1002
|
}
|
|
934
1003
|
}
|
|
935
1004
|
|
|
936
|
-
|
|
1005
|
+
// Copy attachment files if feature is enabled
|
|
1006
|
+
if (config.features?.attachments !== false) {
|
|
1007
|
+
console.log(chalk.blue('\n📎 Processing attachments...'));
|
|
1008
|
+
|
|
1009
|
+
const attachmentTypes = config.attachmentTypes || [
|
|
1010
|
+
'.pdf', '.doc', '.docx', '.xls', '.xlsx', '.csv', '.ppt', '.pptx', '.txt', '.rtf',
|
|
1011
|
+
'.zip', '.tar', '.gz', '.7z', '.rar',
|
|
1012
|
+
'.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp', '.ico', '.bmp',
|
|
1013
|
+
'.json', '.xml', '.yaml', '.yml', '.toml',
|
|
1014
|
+
'.mp4', '.mp3', '.wav', '.avi', '.mov'
|
|
1015
|
+
];
|
|
1016
|
+
|
|
1017
|
+
try {
|
|
1018
|
+
const attachmentFiles = await getAllAttachmentFiles(docsDir, docsDir, attachmentTypes);
|
|
1019
|
+
|
|
1020
|
+
if (attachmentFiles.length > 0) {
|
|
1021
|
+
const { copiedCount, totalSize } = await copyAttachmentFiles(attachmentFiles, docsDir, outputDir);
|
|
1022
|
+
|
|
1023
|
+
// Format file size
|
|
1024
|
+
const formatSize = (bytes) => {
|
|
1025
|
+
if (bytes < 1024) return bytes + ' B';
|
|
1026
|
+
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
|
|
1027
|
+
return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
|
|
1028
|
+
};
|
|
1029
|
+
|
|
1030
|
+
console.log(chalk.green(`✅ Copied ${copiedCount} attachments (${formatSize(totalSize)} total)`));
|
|
1031
|
+
} else {
|
|
1032
|
+
console.log(chalk.gray(' No attachments found to copy'));
|
|
1033
|
+
}
|
|
1034
|
+
} catch (error) {
|
|
1035
|
+
console.warn(chalk.yellow(`Warning: Error processing attachments: ${error.message}`));
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
console.log(chalk.green('\n✅ Documentation build complete!'));
|
|
937
1040
|
}
|
|
938
1041
|
|
|
939
1042
|
// Create placeholder README.md if missing
|
|
@@ -1047,82 +1150,33 @@ For help with @knowcode/doc-builder:
|
|
|
1047
1150
|
}
|
|
1048
1151
|
}
|
|
1049
1152
|
|
|
1050
|
-
//
|
|
1051
|
-
async function
|
|
1052
|
-
//
|
|
1053
|
-
const
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
1058
|
-
<title>Login - ${config.siteName}</title>
|
|
1059
|
-
<link rel="stylesheet" href="css/notion-style.css">
|
|
1060
|
-
</head>
|
|
1061
|
-
<body>
|
|
1062
|
-
<div class="auth-container">
|
|
1063
|
-
<div class="auth-box">
|
|
1064
|
-
<h1>Login to ${config.siteName}</h1>
|
|
1065
|
-
<form id="login-form">
|
|
1066
|
-
<div class="form-group">
|
|
1067
|
-
<label for="username">Username</label>
|
|
1068
|
-
<input type="text" id="username" name="username" required>
|
|
1069
|
-
</div>
|
|
1070
|
-
<div class="form-group">
|
|
1071
|
-
<label for="password">Password</label>
|
|
1072
|
-
<input type="password" id="password" name="password" required>
|
|
1073
|
-
</div>
|
|
1074
|
-
<button type="submit" class="auth-button">Login</button>
|
|
1075
|
-
</form>
|
|
1076
|
-
<div id="error-message" class="error-message"></div>
|
|
1077
|
-
</div>
|
|
1078
|
-
</div>
|
|
1079
|
-
<script>
|
|
1080
|
-
document.getElementById('login-form').addEventListener('submit', function(e) {
|
|
1081
|
-
e.preventDefault();
|
|
1082
|
-
const username = document.getElementById('username').value;
|
|
1083
|
-
const password = document.getElementById('password').value;
|
|
1084
|
-
|
|
1085
|
-
// Validate credentials
|
|
1086
|
-
if (username === '${config.auth.username}' && password === '${config.auth.password}') {
|
|
1087
|
-
// Set auth cookie
|
|
1088
|
-
const token = btoa(username + ':' + password);
|
|
1089
|
-
document.cookie = 'doc-auth=' + token + '; path=/';
|
|
1090
|
-
|
|
1091
|
-
// Redirect
|
|
1092
|
-
const params = new URLSearchParams(window.location.search);
|
|
1093
|
-
const redirect = params.get('redirect') || '/';
|
|
1094
|
-
window.location.href = redirect;
|
|
1095
|
-
} else {
|
|
1096
|
-
document.getElementById('error-message').textContent = 'Invalid username or password';
|
|
1097
|
-
}
|
|
1098
|
-
});
|
|
1099
|
-
</script>
|
|
1100
|
-
</body>
|
|
1101
|
-
</html>`;
|
|
1153
|
+
// Generate all Supabase authentication files
|
|
1154
|
+
async function generateSupabaseAuthFiles(outputDir, config) {
|
|
1155
|
+
// Validate Supabase configuration
|
|
1156
|
+
const validationErrors = SupabaseAuth.validateConfig(config);
|
|
1157
|
+
if (validationErrors.length > 0) {
|
|
1158
|
+
throw new Error(`Supabase authentication configuration errors:\n${validationErrors.join('\n')}`);
|
|
1159
|
+
}
|
|
1102
1160
|
|
|
1103
|
-
|
|
1161
|
+
// Create Supabase auth instance
|
|
1162
|
+
const supabaseAuth = new SupabaseAuth(config.auth);
|
|
1104
1163
|
|
|
1105
|
-
//
|
|
1106
|
-
const
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
<title>Logged Out - ${config.siteName}</title>
|
|
1112
|
-
<link rel="stylesheet" href="css/notion-style.css">
|
|
1113
|
-
</head>
|
|
1114
|
-
<body>
|
|
1115
|
-
<div class="auth-container">
|
|
1116
|
-
<div class="auth-box">
|
|
1117
|
-
<h1>You have been logged out</h1>
|
|
1118
|
-
<p>Thank you for using ${config.siteName}.</p>
|
|
1119
|
-
<a href="login.html" class="auth-button">Login Again</a>
|
|
1120
|
-
</div>
|
|
1121
|
-
</div>
|
|
1122
|
-
</body>
|
|
1123
|
-
</html>`;
|
|
1164
|
+
// Generate auth script and save to js/auth.js
|
|
1165
|
+
const authScript = supabaseAuth.generateAuthScript();
|
|
1166
|
+
await fs.writeFile(path.join(outputDir, 'js', 'auth.js'), authScript);
|
|
1167
|
+
|
|
1168
|
+
// Also copy to root for backward compatibility
|
|
1169
|
+
await fs.writeFile(path.join(outputDir, 'auth.js'), authScript);
|
|
1124
1170
|
|
|
1171
|
+
// Generate and write login page
|
|
1172
|
+
const loginHTML = supabaseAuth.generateLoginPage(config);
|
|
1173
|
+
await fs.writeFile(path.join(outputDir, 'login.html'), loginHTML);
|
|
1174
|
+
|
|
1175
|
+
// Generate and write logout page
|
|
1176
|
+
const logoutHTML = supabaseAuth.generateLogoutPage(config);
|
|
1125
1177
|
await fs.writeFile(path.join(outputDir, 'logout.html'), logoutHTML);
|
|
1178
|
+
|
|
1179
|
+
console.log(chalk.green('✓ Generated Supabase authentication files'));
|
|
1126
1180
|
}
|
|
1127
1181
|
|
|
1128
1182
|
// Create default index page when no documentation exists
|