ultimate-jekyll-manager 0.0.109 → 0.0.111
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.md +41 -1
- package/dist/commands/migrate.js +122 -69
- package/dist/commands/setup.js +124 -0
- package/dist/defaults/.github/workflows/build.yml +1 -1
- package/dist/defaults/src/_config.yml +3 -3
- package/dist/defaults/src/_includes/frontend/sections/footer.json +1 -1
- package/dist/defaults/ultimate-jekyll-manager.json +8 -1
- package/dist/gulp/tasks/defaults.js +5 -1
- package/dist/index.js +8 -5
- package/firebase-debug.log +56 -0
- package/package.json +1 -1
package/CLAUDE.md
CHANGED
|
@@ -17,15 +17,55 @@ The "consuming" project has the following structure:
|
|
|
17
17
|
## Local Development
|
|
18
18
|
When working with a consuming project, the local development server URL can be found in the `.temp/_config_browsersync.yml` file in the consuming project's root directory. You should read this file to determine the correct local URL for browsing and testing the site.
|
|
19
19
|
|
|
20
|
-
Other Ultimate Jekyll Components:
|
|
20
|
+
## Other Ultimate Jekyll Components:
|
|
21
21
|
src/assets/css/ultimate-jekyll-manager.scss = Main stylesheet used by Ultimate Jekyll to style the site
|
|
22
22
|
src/assets/css/global = Global styles that are used by Ultimate Jekyll
|
|
23
23
|
src/assets/css/pages = Page-specific styles that are used by Ultimate Jekyll
|
|
24
24
|
* If you are making a page, put the styles in this directory like so: `src/assets/css/pages/[page-name]/index.scss`
|
|
25
25
|
|
|
26
|
+
src/assets/css/main.scss
|
|
27
|
+
* This file runs on EVERY page and should be edited to contain site-wide CSS styles.
|
|
28
|
+
|
|
29
|
+
|
|
26
30
|
src/assets/js/ultimate-jekyll-manager.js = Main JavaScript file used by Ultimate Jekyll to manage the site
|
|
27
31
|
src/assets/js/pages = Page-specific JavaScript files that are used by Ultimate Jekyll
|
|
28
32
|
* If you are making a page, put the JavaScript in this directory like so: `src/assets/js/pages/[page-name]/index.js`
|
|
33
|
+
* The page-specific JS and CSS files are automatically included in the page based on the page's canonical path.
|
|
34
|
+
* You need to use our standardized structure:
|
|
35
|
+
* Notice how how the helpers are outside the main export function.
|
|
36
|
+
```js
|
|
37
|
+
/**
|
|
38
|
+
* XXX Page JavaScript
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
// Libraries
|
|
42
|
+
let webManager = null;
|
|
43
|
+
|
|
44
|
+
// Module
|
|
45
|
+
export default (Manager) => {
|
|
46
|
+
return new Promise(async function (resolve) {
|
|
47
|
+
// Shortcuts
|
|
48
|
+
webManager = Manager.webManager;
|
|
49
|
+
|
|
50
|
+
// Initialize when DOM is ready
|
|
51
|
+
await webManager.dom().ready();
|
|
52
|
+
|
|
53
|
+
// We just need to pause videos when switching tabs for better UX
|
|
54
|
+
helper1();
|
|
55
|
+
|
|
56
|
+
// Resolve after initialization
|
|
57
|
+
return resolve();
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// Helper functions
|
|
62
|
+
function helper1() {
|
|
63
|
+
// ...
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
/src/assets/js/main.js
|
|
68
|
+
* This file runs on EVERY page and should be edited to contain site-wide JavaScript functionality.
|
|
29
69
|
|
|
30
70
|
src/assets/themes = Theme scss and js files that are can be picked and used by the consuming project.
|
|
31
71
|
|
package/dist/commands/migrate.js
CHANGED
|
@@ -41,47 +41,47 @@ async function migratePosts() {
|
|
|
41
41
|
return;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
const targetExists = jetpack.exists(targetPath);
|
|
44
|
+
logger.log(`Migrating _posts from root to src/...`);
|
|
46
45
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
logger.log('Checking for conflicts...');
|
|
46
|
+
// Get all files recursively from source (not directories)
|
|
47
|
+
const sourceFiles = jetpack.find(sourcePath, { matching: '**/*', directories: false }) || [];
|
|
50
48
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
if (sourceFiles.length === 0) {
|
|
50
|
+
logger.log('No files found in _posts directory');
|
|
51
|
+
jetpack.remove(sourcePath);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
let movedCount = 0;
|
|
56
|
+
let overwrittenCount = 0;
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
}
|
|
58
|
+
// Just move everything, overwrite if needed
|
|
59
|
+
sourceFiles.forEach((sourceFile) => {
|
|
60
|
+
const relativePath = path.relative(sourcePath, sourceFile);
|
|
61
|
+
const targetFile = path.join(targetPath, relativePath);
|
|
64
62
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
logger.log(` Source: ${sourcePath}`);
|
|
68
|
-
logger.log(` Target: ${targetPath}`);
|
|
63
|
+
// Check if target exists
|
|
64
|
+
const targetExists = jetpack.exists(targetFile);
|
|
69
65
|
|
|
70
|
-
|
|
71
|
-
|
|
66
|
+
// Ensure parent directory exists
|
|
67
|
+
jetpack.dir(path.dirname(targetFile));
|
|
72
68
|
|
|
73
|
-
|
|
74
|
-
|
|
69
|
+
// Move the file (this overwrites if target exists)
|
|
70
|
+
jetpack.move(sourceFile, targetFile, { overwrite: true });
|
|
75
71
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
72
|
+
if (targetExists) {
|
|
73
|
+
overwrittenCount++;
|
|
74
|
+
logger.log(` ✓ Overwrote: ${relativePath}`);
|
|
75
|
+
} else {
|
|
76
|
+
movedCount++;
|
|
77
|
+
logger.log(` ✓ Moved: ${relativePath}`);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
79
80
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
81
|
+
// Remove the source directory
|
|
82
|
+
jetpack.remove(sourcePath);
|
|
83
|
+
|
|
84
|
+
logger.log(logger.format.green(`✓ Successfully migrated _posts: ${movedCount} moved, ${overwrittenCount} overwritten`));
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
async function migrateAssets() {
|
|
@@ -100,47 +100,101 @@ async function migrateAssets() {
|
|
|
100
100
|
const targetExists = jetpack.exists(targetPath);
|
|
101
101
|
|
|
102
102
|
if (targetExists) {
|
|
103
|
-
logger.
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
103
|
+
logger.log(`Target directory ${targetPath} already exists - will merge contents...`);
|
|
104
|
+
|
|
105
|
+
// Get all files recursively from source (not directories)
|
|
106
|
+
const sourceFiles = jetpack.find(sourcePath, { matching: '**/*', directories: false }) || [];
|
|
107
|
+
|
|
108
|
+
let movedCount = 0;
|
|
109
|
+
let identicalCount = 0;
|
|
110
|
+
const conflicts = [];
|
|
111
|
+
|
|
112
|
+
// First pass: check for conflicts
|
|
113
|
+
sourceFiles.forEach((sourceFile) => {
|
|
114
|
+
const relativePath = path.relative(sourcePath, sourceFile);
|
|
115
|
+
const targetFile = path.join(targetPath, relativePath);
|
|
116
|
+
|
|
117
|
+
// Only care about file conflicts, not directory existence
|
|
118
|
+
if (jetpack.exists(targetFile) === 'file') {
|
|
119
|
+
// Check if files are identical
|
|
120
|
+
const sourceStats = jetpack.inspect(sourceFile);
|
|
121
|
+
const targetStats = jetpack.inspect(targetFile);
|
|
122
|
+
|
|
123
|
+
// Compare file sizes first (faster than reading content)
|
|
124
|
+
if (sourceStats.size !== targetStats.size) {
|
|
125
|
+
// Different sizes, definitely a conflict
|
|
126
|
+
conflicts.push(relativePath);
|
|
127
|
+
} else {
|
|
128
|
+
// Same size, need to compare content for small files
|
|
129
|
+
if (sourceStats.size < 1024 * 1024) { // Less than 1MB
|
|
130
|
+
const sourceContent = jetpack.read(sourceFile, 'buffer');
|
|
131
|
+
const targetContent = jetpack.read(targetFile, 'buffer');
|
|
132
|
+
|
|
133
|
+
if (Buffer.compare(sourceContent, targetContent) !== 0) {
|
|
134
|
+
// Files differ - this is a real conflict
|
|
135
|
+
conflicts.push(relativePath);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// For large files with same size, we assume they're identical
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
});
|
|
116
142
|
|
|
143
|
+
// If we have actual file conflicts, throw error
|
|
117
144
|
if (conflicts.length > 0) {
|
|
118
|
-
logger.
|
|
119
|
-
conflicts.slice(0, 10).forEach((file) => logger.
|
|
145
|
+
logger.error(`Found ${conflicts.length} conflicting file(s) with different content:`);
|
|
146
|
+
conflicts.slice(0, 10).forEach((file) => logger.error(` - ${file}`));
|
|
120
147
|
if (conflicts.length > 10) {
|
|
121
|
-
logger.
|
|
148
|
+
logger.error(` ... and ${conflicts.length - 10} more`);
|
|
122
149
|
}
|
|
123
|
-
throw new Error('Cannot migrate assets:
|
|
150
|
+
throw new Error('Cannot migrate assets: duplicate files with different content detected. Please resolve manually.');
|
|
124
151
|
}
|
|
125
152
|
|
|
126
|
-
//
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
153
|
+
// No conflicts, proceed with migration
|
|
154
|
+
sourceFiles.forEach((sourceFile) => {
|
|
155
|
+
const relativePath = path.relative(sourcePath, sourceFile);
|
|
156
|
+
const targetFile = path.join(targetPath, relativePath);
|
|
157
|
+
|
|
158
|
+
if (jetpack.exists(targetFile) === 'file') {
|
|
159
|
+
// Files are identical (we checked above), just remove source
|
|
160
|
+
jetpack.remove(sourceFile);
|
|
161
|
+
identicalCount++;
|
|
162
|
+
logger.log(` ✓ Skipped identical file: ${relativePath}`);
|
|
163
|
+
} else {
|
|
164
|
+
// No file conflict, move it (directory will be created if needed)
|
|
165
|
+
jetpack.dir(path.dirname(targetFile));
|
|
166
|
+
jetpack.move(sourceFile, targetFile);
|
|
167
|
+
movedCount++;
|
|
168
|
+
logger.log(` ✓ Moved: ${relativePath}`);
|
|
135
169
|
}
|
|
136
170
|
});
|
|
137
171
|
|
|
138
|
-
//
|
|
139
|
-
jetpack.
|
|
172
|
+
// Clean up empty directories in source
|
|
173
|
+
const remainingItems = jetpack.list(sourcePath) || [];
|
|
174
|
+
if (remainingItems.length === 0) {
|
|
175
|
+
jetpack.remove(sourcePath);
|
|
176
|
+
logger.log(` ✓ Removed empty source directory`);
|
|
177
|
+
} else {
|
|
178
|
+
// Try to clean up empty subdirectories
|
|
179
|
+
const remainingDirs = jetpack.find(sourcePath, { matching: '*/', directories: true, files: false }) || [];
|
|
180
|
+
remainingDirs.reverse().forEach((dir) => {
|
|
181
|
+
const contents = jetpack.list(dir) || [];
|
|
182
|
+
if (contents.length === 0) {
|
|
183
|
+
jetpack.remove(dir);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
// Check again if root is empty
|
|
188
|
+
const finalCheck = jetpack.list(sourcePath) || [];
|
|
189
|
+
if (finalCheck.length === 0) {
|
|
190
|
+
jetpack.remove(sourcePath);
|
|
191
|
+
logger.log(` ✓ Removed empty source directory after cleanup`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
140
194
|
|
|
141
|
-
logger.log(logger.format.green(
|
|
195
|
+
logger.log(logger.format.green(`✓ Successfully merged assets: ${movedCount} moved, ${identicalCount} identical files skipped`));
|
|
142
196
|
} else {
|
|
143
|
-
//
|
|
197
|
+
// Simple move when target doesn't exist
|
|
144
198
|
logger.log(`Migrating assets from root to src/...`);
|
|
145
199
|
logger.log(` Source: ${sourcePath}`);
|
|
146
200
|
logger.log(` Target: ${targetPath}`);
|
|
@@ -152,8 +206,7 @@ async function migrateAssets() {
|
|
|
152
206
|
jetpack.move(sourcePath, targetPath);
|
|
153
207
|
|
|
154
208
|
// Verify the move
|
|
155
|
-
const moveSuccessful = jetpack.exists(targetPath)
|
|
156
|
-
&& !jetpack.exists(sourcePath);
|
|
209
|
+
const moveSuccessful = jetpack.exists(targetPath) && !jetpack.exists(sourcePath);
|
|
157
210
|
|
|
158
211
|
if (moveSuccessful) {
|
|
159
212
|
logger.log(logger.format.green('✓ Successfully migrated assets to src/assets'));
|
|
@@ -349,16 +402,16 @@ async function cleanupOldDirectories() {
|
|
|
349
402
|
return;
|
|
350
403
|
}
|
|
351
404
|
|
|
352
|
-
// Check if directory
|
|
353
|
-
const
|
|
405
|
+
// Check if directory has any FILES (not just subdirectories)
|
|
406
|
+
const files = jetpack.find(dirPath, { matching: '**/*', directories: false }) || [];
|
|
354
407
|
|
|
355
|
-
if (
|
|
356
|
-
// Directory
|
|
408
|
+
if (files.length === 0) {
|
|
409
|
+
// Directory has no files (might have empty subdirectories), delete it
|
|
357
410
|
jetpack.remove(dirPath);
|
|
358
411
|
logger.log(` ✓ Deleted empty ${name} directory`);
|
|
359
412
|
deletedCount++;
|
|
360
413
|
} else {
|
|
361
|
-
logger.warn(` ⚠ ${name} directory still exists
|
|
414
|
+
logger.warn(` ⚠ ${name} directory still exists with ${files.length} file(s)`);
|
|
362
415
|
logger.warn(` Please manually review: ${dirPath}`);
|
|
363
416
|
}
|
|
364
417
|
});
|
package/dist/commands/setup.js
CHANGED
|
@@ -41,6 +41,7 @@ module.exports = async function (options) {
|
|
|
41
41
|
options.checkLocality = options.checkLocality !== 'false';
|
|
42
42
|
options.updateBundle = options.updateBundle !== 'false';
|
|
43
43
|
options.publishGitHubToken = options.publishGitHubToken !== 'false';
|
|
44
|
+
options.updateGitHubPages = options.updateGitHubPages !== 'false';
|
|
44
45
|
|
|
45
46
|
// Log
|
|
46
47
|
logger.log(`Welcome to ${package.name} v${package.version}!`);
|
|
@@ -115,6 +116,11 @@ module.exports = async function (options) {
|
|
|
115
116
|
await publishGitHubToken();
|
|
116
117
|
}
|
|
117
118
|
|
|
119
|
+
// Update GitHub Pages settings
|
|
120
|
+
if (options.updateGitHubPages) {
|
|
121
|
+
await updateGitHubPages(options);
|
|
122
|
+
}
|
|
123
|
+
|
|
118
124
|
// Check which locality we are using
|
|
119
125
|
if (options.updateBundle && !Manager.isServer()) {
|
|
120
126
|
await updateBundle();
|
|
@@ -498,3 +504,121 @@ async function publishGitHubToken() {
|
|
|
498
504
|
// Don't throw - this is not critical for setup to continue
|
|
499
505
|
}
|
|
500
506
|
}
|
|
507
|
+
|
|
508
|
+
// Update GitHub Pages settings
|
|
509
|
+
async function updateGitHubPages(options) {
|
|
510
|
+
options = options || {};
|
|
511
|
+
|
|
512
|
+
// Check if GH_TOKEN is available
|
|
513
|
+
if (!process.env.GH_TOKEN) {
|
|
514
|
+
logger.warn('⚠️ GH_TOKEN not found in environment variables. Skipping GitHub Pages update.');
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
// Check if GITHUB_REPOSITORY is available
|
|
519
|
+
if (!process.env.GITHUB_REPOSITORY) {
|
|
520
|
+
logger.warn('⚠️ GITHUB_REPOSITORY not detected. Skipping GitHub Pages update.');
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// Quit if in build mode
|
|
525
|
+
if (Manager.isBuildMode()) {
|
|
526
|
+
logger.log('⚠️ Skipping GitHub Pages update in build mode.');
|
|
527
|
+
return;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
try {
|
|
531
|
+
// Parse owner and repo
|
|
532
|
+
const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/');
|
|
533
|
+
|
|
534
|
+
// Initialize Octokit
|
|
535
|
+
const octokit = new Octokit({
|
|
536
|
+
auth: process.env.GH_TOKEN,
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
logger.log(`📄 Configuring GitHub Pages for ${owner}/${repo}...`);
|
|
540
|
+
|
|
541
|
+
// Get current repository info to check if Pages is already enabled
|
|
542
|
+
let pagesInfo;
|
|
543
|
+
try {
|
|
544
|
+
const { data } = await octokit.repos.getPages({
|
|
545
|
+
owner,
|
|
546
|
+
repo,
|
|
547
|
+
});
|
|
548
|
+
pagesInfo = data;
|
|
549
|
+
logger.log('GitHub Pages already enabled, updating configuration...');
|
|
550
|
+
} catch (error) {
|
|
551
|
+
if (error.status === 404) {
|
|
552
|
+
logger.log('GitHub Pages not yet enabled, creating Pages site...');
|
|
553
|
+
pagesInfo = null;
|
|
554
|
+
} else {
|
|
555
|
+
throw error;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// Determine the source configuration
|
|
560
|
+
const sourceConfig = options.source || { branch: 'gh-pages', path: '/' };
|
|
561
|
+
|
|
562
|
+
// If custom domain is provided in config, use it
|
|
563
|
+
const customDomain = options.customDomain || (config.url ? new URL(config.url).host : null);
|
|
564
|
+
|
|
565
|
+
// Build options for API call
|
|
566
|
+
const pagesOptions = {
|
|
567
|
+
owner,
|
|
568
|
+
repo,
|
|
569
|
+
source: sourceConfig,
|
|
570
|
+
};
|
|
571
|
+
|
|
572
|
+
// Add custom domain if available and not github.io domain
|
|
573
|
+
if (customDomain && !customDomain.includes('github.io')) {
|
|
574
|
+
pagesOptions.cname = customDomain;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
// Add HTTPS enforcement (recommended)
|
|
578
|
+
if (options.httpsEnforced !== false) {
|
|
579
|
+
pagesOptions.https_enforced = true;
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// Create or update Pages configuration
|
|
583
|
+
if (!pagesInfo) {
|
|
584
|
+
// Create new Pages site
|
|
585
|
+
const { data } = await octokit.repos.createPagesSite(pagesOptions);
|
|
586
|
+
logger.log(`✅ GitHub Pages enabled successfully!`);
|
|
587
|
+
logger.log(` URL: ${data.html_url}`);
|
|
588
|
+
if (data.cname) {
|
|
589
|
+
logger.log(` Custom domain: ${data.cname}`);
|
|
590
|
+
}
|
|
591
|
+
} else {
|
|
592
|
+
// Update existing Pages site
|
|
593
|
+
const updateOptions = {
|
|
594
|
+
owner,
|
|
595
|
+
repo,
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
// Only include fields that can be updated
|
|
599
|
+
if (customDomain && !customDomain.includes('github.io')) {
|
|
600
|
+
updateOptions.cname = customDomain;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
if (options.httpsEnforced !== false) {
|
|
604
|
+
updateOptions.https_enforced = true;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
// Update source if different
|
|
608
|
+
if (JSON.stringify(pagesInfo.source) !== JSON.stringify(sourceConfig)) {
|
|
609
|
+
updateOptions.source = sourceConfig;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
const { data } = await octokit.repos.updateInformationAboutPagesSite(updateOptions);
|
|
613
|
+
logger.log(`✅ GitHub Pages configuration updated successfully!`);
|
|
614
|
+
logger.log(` URL: ${data.html_url}`);
|
|
615
|
+
if (data.cname) {
|
|
616
|
+
logger.log(` Custom domain: ${data.cname}`);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
} catch (error) {
|
|
621
|
+
logger.error(`❌ Failed to update GitHub Pages: ${error.message}`);
|
|
622
|
+
// Don't throw - this is not critical for setup to continue
|
|
623
|
+
}
|
|
624
|
+
}
|
|
@@ -8,7 +8,7 @@ on:
|
|
|
8
8
|
- main
|
|
9
9
|
- template
|
|
10
10
|
schedule:
|
|
11
|
-
|
|
11
|
+
- cron: '{ github.workflows.build.schedule }' # auto-build schedule (configurable in ultimate-jekyll-manager.json)
|
|
12
12
|
|
|
13
13
|
concurrency:
|
|
14
14
|
group: ${{ github.ref }}
|
|
@@ -86,11 +86,11 @@ web_manager:
|
|
|
86
86
|
config:
|
|
87
87
|
palette:
|
|
88
88
|
popup:
|
|
89
|
-
background: "#
|
|
89
|
+
background: "#237afc"
|
|
90
90
|
text: "#fff"
|
|
91
91
|
button:
|
|
92
92
|
background: "#fff"
|
|
93
|
-
text: "#
|
|
93
|
+
text: "#237afc"
|
|
94
94
|
chatsy:
|
|
95
95
|
enabled: true
|
|
96
96
|
config:
|
|
@@ -98,7 +98,7 @@ web_manager:
|
|
|
98
98
|
chatId: ""
|
|
99
99
|
settings:
|
|
100
100
|
openChatButton:
|
|
101
|
-
background: "#
|
|
101
|
+
background: "#237afc"
|
|
102
102
|
text: "#fff"
|
|
103
103
|
sentry:
|
|
104
104
|
enabled: true
|
|
@@ -18,6 +18,10 @@ const config = Manager.getConfig('project');
|
|
|
18
18
|
const rootPathPackage = Manager.getRootPath('main');
|
|
19
19
|
const rootPathProject = Manager.getRootPath('project');
|
|
20
20
|
|
|
21
|
+
// Load ultimate-jekyll-manager.json config
|
|
22
|
+
const ujConfigPath = path.join(rootPathPackage, 'dist/defaults/ultimate-jekyll-manager.json');
|
|
23
|
+
const ujConfig = jetpack.exists(ujConfigPath) ? JSON5.parse(jetpack.read(ujConfigPath)) : {};
|
|
24
|
+
|
|
21
25
|
// Get clean versions
|
|
22
26
|
// const cleanVersions = { versions: Manager.getCleanVersions()};
|
|
23
27
|
const cleanVersions = { versions: package.engines };
|
|
@@ -65,7 +69,7 @@ const FILE_MAP = {
|
|
|
65
69
|
|
|
66
70
|
// Files to run templating on
|
|
67
71
|
'.github/workflows/build.yml': {
|
|
68
|
-
template: cleanVersions,
|
|
72
|
+
template: { ...cleanVersions, ...ujConfig },
|
|
69
73
|
},
|
|
70
74
|
'.nvmrc': {
|
|
71
75
|
template: cleanVersions,
|
package/dist/index.js
CHANGED
|
@@ -62,7 +62,10 @@ class Manager {
|
|
|
62
62
|
);
|
|
63
63
|
|
|
64
64
|
/* @dev-only:start */
|
|
65
|
-
|
|
65
|
+
{
|
|
66
|
+
console.log(`Page-specific module loading: #main/${pageModulePathFull}`);
|
|
67
|
+
console.log(`Page-specific module loading: #project/${pageModulePathFull}`);
|
|
68
|
+
}
|
|
66
69
|
/* @dev-only:end */
|
|
67
70
|
|
|
68
71
|
// Load page-specific scripts
|
|
@@ -74,9 +77,9 @@ class Manager {
|
|
|
74
77
|
})
|
|
75
78
|
.catch(e => {
|
|
76
79
|
if (this.isNotFound(e, pageModulePath)) {
|
|
77
|
-
console.warn(`Page module #main
|
|
80
|
+
console.warn(`Page-specific module missing: #main/${pageModulePathFull}`);
|
|
78
81
|
} else {
|
|
79
|
-
console.error(`Page module #main
|
|
82
|
+
console.error(`Page-specific module error: #main/${pageModulePathFull}`, e);
|
|
80
83
|
}
|
|
81
84
|
})
|
|
82
85
|
);
|
|
@@ -89,9 +92,9 @@ class Manager {
|
|
|
89
92
|
})
|
|
90
93
|
.catch(e => {
|
|
91
94
|
if (this.isNotFound(e, pageModulePath)) {
|
|
92
|
-
console.warn(`
|
|
95
|
+
console.warn(`Page-specific module missing: #project/${pageModulePathFull}`);
|
|
93
96
|
} else {
|
|
94
|
-
console.error(`
|
|
97
|
+
console.error(`Page-specific module error: #project/${pageModulePathFull}`, e);
|
|
95
98
|
}
|
|
96
99
|
})
|
|
97
100
|
);
|
package/firebase-debug.log
CHANGED
|
@@ -198,3 +198,59 @@
|
|
|
198
198
|
[debug] [2025-10-27T23:48:17.927Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
199
199
|
[debug] [2025-10-27T23:48:17.927Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
200
200
|
[debug] [2025-10-27T23:48:17.927Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
201
|
+
[debug] [2025-10-30T00:06:03.831Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
202
|
+
[debug] [2025-10-30T00:06:03.832Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
203
|
+
[debug] [2025-10-30T00:06:03.834Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
204
|
+
[debug] [2025-10-30T00:06:03.834Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
205
|
+
[debug] [2025-10-30T00:06:03.834Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
206
|
+
[debug] [2025-10-30T00:06:03.847Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
207
|
+
[debug] [2025-10-30T00:06:03.847Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
208
|
+
[debug] [2025-10-30T00:06:03.833Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
209
|
+
[debug] [2025-10-30T00:06:03.833Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
210
|
+
[debug] [2025-10-30T00:06:03.833Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
211
|
+
[debug] [2025-10-30T00:06:03.847Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
212
|
+
[debug] [2025-10-30T00:06:03.847Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
213
|
+
[debug] [2025-10-30T00:06:03.984Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
214
|
+
[debug] [2025-10-30T00:06:03.984Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
215
|
+
[debug] [2025-10-30T00:06:03.984Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
216
|
+
[debug] [2025-10-30T00:06:03.985Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
217
|
+
[debug] [2025-10-30T00:06:03.985Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
218
|
+
[debug] [2025-10-30T00:06:03.986Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
219
|
+
[debug] [2025-10-30T00:06:03.986Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
220
|
+
[debug] [2025-10-30T00:06:03.987Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
221
|
+
[debug] [2025-10-30T00:06:03.987Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
222
|
+
[debug] [2025-10-30T00:06:03.984Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
223
|
+
[debug] [2025-10-30T00:06:03.985Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
224
|
+
[debug] [2025-10-30T00:06:03.985Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
225
|
+
[debug] [2025-10-30T00:06:03.986Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
226
|
+
[debug] [2025-10-30T00:06:03.986Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
227
|
+
[debug] [2025-10-30T00:06:03.987Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
228
|
+
[debug] [2025-10-30T00:06:03.987Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
229
|
+
[debug] [2025-11-04T23:58:14.817Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
230
|
+
[debug] [2025-11-04T23:58:14.817Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
231
|
+
[debug] [2025-11-04T23:58:14.819Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
232
|
+
[debug] [2025-11-04T23:58:14.819Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
233
|
+
[debug] [2025-11-04T23:58:14.819Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
234
|
+
[debug] [2025-11-04T23:58:14.835Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
235
|
+
[debug] [2025-11-04T23:58:14.836Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
236
|
+
[debug] [2025-11-04T23:58:14.819Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
237
|
+
[debug] [2025-11-04T23:58:14.819Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
238
|
+
[debug] [2025-11-04T23:58:14.820Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
239
|
+
[debug] [2025-11-04T23:58:14.836Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
240
|
+
[debug] [2025-11-04T23:58:14.836Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
241
|
+
[debug] [2025-11-04T23:58:14.969Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
242
|
+
[debug] [2025-11-04T23:58:14.969Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
243
|
+
[debug] [2025-11-04T23:58:14.970Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
244
|
+
[debug] [2025-11-04T23:58:14.970Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
245
|
+
[debug] [2025-11-04T23:58:14.971Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
246
|
+
[debug] [2025-11-04T23:58:14.971Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
247
|
+
[debug] [2025-11-04T23:58:14.972Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
248
|
+
[debug] [2025-11-04T23:58:14.972Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
249
|
+
[debug] [2025-11-04T23:58:14.975Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
250
|
+
[debug] [2025-11-04T23:58:14.975Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
251
|
+
[debug] [2025-11-04T23:58:14.976Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
252
|
+
[debug] [2025-11-04T23:58:14.976Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
253
|
+
[debug] [2025-11-04T23:58:14.977Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
254
|
+
[debug] [2025-11-04T23:58:14.977Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|
|
255
|
+
[debug] [2025-11-04T23:58:14.978Z] > command requires scopes: ["email","openid","https://www.googleapis.com/auth/cloudplatformprojects.readonly","https://www.googleapis.com/auth/firebase","https://www.googleapis.com/auth/cloud-platform"]
|
|
256
|
+
[debug] [2025-11-04T23:58:14.978Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
|