ultimate-jekyll-manager 0.0.86 → 0.0.88

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/README.md CHANGED
@@ -115,7 +115,7 @@ npx uj imagemin
115
115
  The imagemin task will:
116
116
  - Process images from `src/assets/images/**/*.{jpg,jpeg,png}`
117
117
  - Generate multiple sizes (1024px, 425px) and WebP formats
118
- - Cache processed images in `uj-imagemin` branch (when using GitHub cache)
118
+ - Cache processed images in `cache-imagemin` branch (when using GitHub cache)
119
119
  - Skip already processed images on subsequent runs
120
120
 
121
121
  <!-- Developing -->
@@ -106,18 +106,18 @@ function getRandomElement(array) {
106
106
  function getRandomCategories() {
107
107
  // Determine how many categories (1-3)
108
108
  const numCategories = 1 + Math.floor(Math.random() * 3);
109
-
109
+
110
110
  // Copy array to avoid modifying original
111
111
  const availableCategories = [...blogCategories];
112
112
  const selectedCategories = [];
113
-
113
+
114
114
  // Select random categories without duplicates
115
115
  for (let i = 0; i < numCategories && availableCategories.length > 0; i++) {
116
116
  const index = Math.floor(Math.random() * availableCategories.length);
117
117
  selectedCategories.push(availableCategories[index]);
118
118
  availableCategories.splice(index, 1); // Remove selected to avoid duplicates
119
119
  }
120
-
120
+
121
121
  return selectedCategories;
122
122
  }
123
123
 
@@ -177,7 +177,7 @@ async function generatePostImages(postId, titleSuffix) {
177
177
  try {
178
178
  await downloadImage(imageUrl, imagePath);
179
179
  downloadedImages.push({
180
- path: `/assets/images/blog/post-${postId}/${randomName}.jpg`,
180
+ path: `/assets/images/blog/posts/post-${postId}/${randomName}.jpg`,
181
181
  alt: `${randomName.replace(/-/g, ' ')} image`
182
182
  });
183
183
  logger.log(` Downloaded image ${i}: ${randomName}.jpg`);
@@ -297,7 +297,7 @@ module.exports = async function (options) {
297
297
  // Generate random description
298
298
  const wordCount = 10 + Math.floor(Math.random() * 11); // 10-20 words
299
299
  const randomWords = getRandomWords(wordCount);
300
-
300
+
301
301
  // Generate random categories (1-3 from 5 possible)
302
302
  const postCategories = getRandomCategories();
303
303
 
@@ -64,7 +64,7 @@ newsletter:
64
64
  <time datetime="{{ page.date | date_to_xmlschema }}" class="text-muted small d-block">
65
65
  {{ page.date | date: "%b %d, %Y" }}
66
66
  </time>
67
- <div class="badge bg-primary">{% uj_readtime post.content %} min read</div>
67
+ <div class="badge bg-primary">{% uj_readtime content %} min read</div>
68
68
  </div>
69
69
  </div>
70
70
  </div>
@@ -72,7 +72,7 @@ newsletter:
72
72
 
73
73
  <div class="row justify-content-center">
74
74
  <div class="col-xl-10 col-lg-10 col-md-12 col-12 mb-5" data-lazy="@class animation-slide-up">
75
- {%- uj_post page.post.id, "image-tag", class="img-fluid rounded-3 w-100 blog-post-image", alt=page.post.title -%}
75
+ {%- uj_post page.post.id, "image-tag", class="img-fluid rounded-3 w-100 blog-post-image" -%}
76
76
  </div>
77
77
  </div>
78
78
 
@@ -0,0 +1,12 @@
1
+ // Libraries
2
+ const Manager = new (require('ultimate-jekyll-manager/build'));
3
+ const logger = Manager.logger('middleware:request');
4
+
5
+ // Hook
6
+ module.exports = async (context) => {
7
+ // Destructure context
8
+ const { req, res, pathname } = context;
9
+
10
+ // Log
11
+ // logger.log(`Processing request for ${pathname}`);
12
+ }
@@ -12,8 +12,8 @@ const GitHubCache = require('./utils/github-cache');
12
12
  const rootPathProject = Manager.getRootPath('project');
13
13
 
14
14
  // Settings
15
- const CACHE_DIR = '.temp/imagemin';
16
- const CACHE_BRANCH = 'uj-imagemin';
15
+ const CACHE_DIR = '.temp/cache/imagemin';
16
+ const CACHE_BRANCH = 'cache-uj-imagemin';
17
17
 
18
18
  // Variables
19
19
  let githubCache;
@@ -42,6 +42,9 @@ const input = [
42
42
  // Include plugin so we can live-reload it
43
43
  `${rootPathPackage}/../jekyll-uj-powertools/**/*`,
44
44
 
45
+ // Project hooks
46
+ `${rootPathProject}/hooks/**/*.js`,
47
+
45
48
  // Files to exclude
46
49
  '!dist/.jekyll-cache/**',
47
50
  '!dist/.jekyll-metadata',
@@ -197,6 +197,9 @@ async function processRequestMiddleware(req, res, next) {
197
197
  logger.log(`Serving ${pathname}`);
198
198
  }
199
199
 
200
+ // Run middleware:request hook to allow custom URL rewriting
201
+ await hook('middleware:request', { req, res, pathname });
202
+
200
203
  // Process the post request
201
204
  if (pathname.match(/\/_process/)) {
202
205
  const qsUrl = url.searchParams.get('url');
@@ -264,9 +267,14 @@ async function processRequestMiddleware(req, res, next) {
264
267
  }
265
268
 
266
269
  // Check if the URL is missing a trailing slash and does not have an extension
267
- if (!pathname.endsWith('/') && !path.extname(pathname)) {
270
+ // console.log('---URL 1', req.url);
271
+ if (
272
+ (!pathname.endsWith('/') || pathname.endsWith('/blog/'))
273
+ && !path.extname(pathname)
274
+ ) {
268
275
  // Get the new URL
269
- const newURL = `${pathname}.html`;
276
+ const strippedPath = pathname.replace(/\/$/, '');
277
+ const newURL = `${strippedPath}.html`;
270
278
 
271
279
  // Log
272
280
  // logger.log(`Rewriting ${pathname} to ${newURL}`);
@@ -274,6 +282,7 @@ async function processRequestMiddleware(req, res, next) {
274
282
  // Rewrite it to serve the .html extension
275
283
  req.url = newURL;
276
284
  }
285
+ // console.log('---URL 2', req.url);
277
286
 
278
287
  // Special LOCAL case: Rewrite /blog to blog.html since Jekyll fucks it up locally (probably due to pagination)
279
288
  // Disaboed because we moved it to the jekyll task
@@ -292,6 +301,9 @@ async function processRequestMiddleware(req, res, next) {
292
301
  req.url = '/404.html';
293
302
  }
294
303
 
304
+ // LOG REQUEST
305
+ // logger.log(`Serving file: ${req.url}`);
306
+
295
307
  // Continue
296
308
  return next();
297
309
  }
@@ -323,3 +335,37 @@ function receiveRequestBody(req) {
323
335
  });
324
336
  });
325
337
  }
338
+
339
+ // Run hooks
340
+ async function hook(file, context) {
341
+ // Full path
342
+ const fullPath = path.join(process.cwd(), 'hooks', `${file}.js`);
343
+
344
+ // Check if it exists
345
+ if (!jetpack.exists(fullPath)) {
346
+ // Silently skip if hook doesn't exist (it's optional)
347
+ return;
348
+ }
349
+
350
+ // Log
351
+ // logger.log(`Running hook: ${fullPath}`);
352
+
353
+ // Load hook
354
+ let hookFn;
355
+ try {
356
+ // Clear the cache to allow live reloading of hooks during development
357
+ delete require.cache[require.resolve(fullPath)];
358
+
359
+ // Load the hook
360
+ hookFn = require(fullPath);
361
+ } catch (e) {
362
+ throw new Error(`Error loading hook: ${fullPath} ${e.stack}`);
363
+ }
364
+
365
+ // Execute hook
366
+ try {
367
+ return await hookFn(context);
368
+ } catch (e) {
369
+ throw new Error(`Error running hook: ${fullPath} ${e.stack}`);
370
+ }
371
+ }
@@ -24,12 +24,12 @@ const rootPathPackage = Manager.getRootPath('main');
24
24
  const rootPathProject = Manager.getRootPath('project');
25
25
 
26
26
  // Check if BEM env variable is set
27
- // get cached translations JSON (only once per run, so keep track of how many times this has run) from branch uj-translation
27
+ // get cached translations JSON (only once per run, so keep track of how many times this has run) from branch cache-translation
28
28
  // loop thru all html and md pages in pages/ dir (main and project)
29
29
  // SKIP files in _translations dir
30
30
  // if there is no translation (or translation is too old), send to AI @ itw
31
31
  // save the translation into the cache (file path, date) and write the file to _translations/{code}/{original file path + name}
32
- // push the updated translation JSON to the branch uj-translation
32
+ // push the updated translation JSON to the branch cache-translation
33
33
 
34
34
  // Settings
35
35
  const AI = {
@@ -37,8 +37,8 @@ const AI = {
37
37
  inputCost: 0.40, // $0.40 per 1M tokens
38
38
  outputCost: 1.60, // $1.60 per 1M tokens
39
39
  }
40
- const CACHE_DIR = '.temp/translation';
41
- const CACHE_BRANCH = 'uj-translation';
40
+ const CACHE_DIR = '.temp/cache/translation';
41
+ const CACHE_BRANCH = 'cache-uj-translation';
42
42
  const RECHECK_DAYS = 0;
43
43
  // const LOUD = false;
44
44
  const LOUD = Manager.isServer() || process.env.UJ_LOUD_LOGS === 'true';
@@ -161,7 +161,7 @@ async function processTranslation() {
161
161
  const enabled = config?.translation?.enabled !== false;
162
162
  const languages = config?.translation?.languages || [];
163
163
  const updatedFiles = new Set();
164
-
164
+
165
165
  // Track timing
166
166
  const startTime = Date.now();
167
167
 
@@ -509,7 +509,7 @@ async function processTranslation() {
509
509
  const elapsedMs = endTime - startTime;
510
510
  const elapsedSeconds = Math.floor(elapsedMs / 1000);
511
511
  const elapsedMinutes = Math.floor(elapsedSeconds / 60);
512
- const elapsedFormatted = elapsedMinutes > 0
512
+ const elapsedFormatted = elapsedMinutes > 0
513
513
  ? `${elapsedMinutes}m ${elapsedSeconds % 60}s`
514
514
  : `${elapsedSeconds}s`;
515
515
 
@@ -521,13 +521,13 @@ async function processTranslation() {
521
521
  // Log detailed statistics
522
522
  logger.log('\nšŸ“Š Translation Statistics:');
523
523
  logger.log('═══════════════════════════════════════');
524
-
524
+
525
525
  // Timing
526
526
  logger.log('ā±ļø Timing:');
527
527
  logger.log(` Start time: ${new Date(startTime).toLocaleTimeString()}`);
528
528
  logger.log(` End time: ${new Date(endTime).toLocaleTimeString()}`);
529
529
  logger.log(` Total elapsed: ${elapsedFormatted}`);
530
-
530
+
531
531
  // File processing stats
532
532
  logger.log('\nšŸ“ File Processing:');
533
533
  logger.log(` Total processed: ${stats.totalProcessed}`);
@@ -550,13 +550,13 @@ async function processTranslation() {
550
550
  logger.log(` Output cost: $${outputCost.toFixed(4)}`);
551
551
  logger.log(` Total cost: $${totalCost.toFixed(4)}`);
552
552
  }
553
-
553
+
554
554
  logger.log('═══════════════════════════════════════\n');
555
555
 
556
556
  // Push updated translation cache back to cache branch
557
557
  if (githubCache && githubCache.hasCredentials()) {
558
558
  logger.log(`šŸ“Š Updating translation cache README with latest statistics...`);
559
-
559
+
560
560
  // Collect all cache files to push
561
561
  const allCacheFiles = glob(path.join(CACHE_DIR, '**/*'), { nodir: true });
562
562
 
@@ -6,3 +6,35 @@
6
6
  [debug] [2025-10-20T10:34:24.966Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
7
7
  [debug] [2025-10-20T10:34:24.966Z] > 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"]
8
8
  [debug] [2025-10-20T10:34:24.966Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
9
+ [debug] [2025-10-20T22:22:09.824Z] > 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"]
10
+ [debug] [2025-10-20T22:22:09.824Z] > 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"]
11
+ [debug] [2025-10-20T22:22:09.827Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
12
+ [debug] [2025-10-20T22:22:09.827Z] > 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"]
13
+ [debug] [2025-10-20T22:22:09.827Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
14
+ [debug] [2025-10-20T22:22:09.827Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
15
+ [debug] [2025-10-20T22:22:09.827Z] > 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"]
16
+ [debug] [2025-10-20T22:22:09.827Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
17
+ [debug] [2025-10-20T22:22:28.418Z] > 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"]
18
+ [debug] [2025-10-20T22:22:28.420Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
19
+ [debug] [2025-10-20T22:22:28.420Z] > 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"]
20
+ [debug] [2025-10-20T22:22:28.420Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
21
+ [debug] [2025-10-20T22:22:28.421Z] > 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"]
22
+ [debug] [2025-10-20T22:22:28.425Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
23
+ [debug] [2025-10-20T22:22:28.425Z] > 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"]
24
+ [debug] [2025-10-20T22:22:28.425Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
25
+ [debug] [2025-10-20T22:36:23.096Z] > 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"]
26
+ [debug] [2025-10-20T22:36:23.097Z] > 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"]
27
+ [debug] [2025-10-20T22:36:23.099Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
28
+ [debug] [2025-10-20T22:36:23.099Z] > 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"]
29
+ [debug] [2025-10-20T22:36:23.099Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
30
+ [debug] [2025-10-20T22:36:23.099Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
31
+ [debug] [2025-10-20T22:36:23.099Z] > 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"]
32
+ [debug] [2025-10-20T22:36:23.099Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
33
+ [debug] [2025-10-21T00:37:54.667Z] > 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"]
34
+ [debug] [2025-10-21T00:37:54.669Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
35
+ [debug] [2025-10-21T00:37:54.670Z] > 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"]
36
+ [debug] [2025-10-21T00:37:54.670Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
37
+ [debug] [2025-10-21T00:37:54.668Z] > 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"]
38
+ [debug] [2025-10-21T00:37:54.671Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
39
+ [debug] [2025-10-21T00:37:54.672Z] > 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"]
40
+ [debug] [2025-10-21T00:37:54.672Z] > authorizing via signed-in user (ian.wiedenman@gmail.com)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ultimate-jekyll-manager",
3
- "version": "0.0.86",
3
+ "version": "0.0.88",
4
4
  "description": "Ultimate Jekyll dependency manager",
5
5
  "main": "dist/index.js",
6
6
  "exports": {