eleventy-auto-cache-buster 0.8.4 → 0.9.1

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.
@@ -2,6 +2,7 @@ const fs = require("fs");
2
2
  const path = require("path");
3
3
  const crypto = require("crypto");
4
4
  const glob = require("glob");
5
+ const escape = require("regexp.escape");
5
6
 
6
7
  let enableLogging = false;
7
8
  let algorithm = "md5";
@@ -53,14 +54,16 @@ const defaultOptions = {
53
54
 
54
55
  function collectLocalAssets(globResults=[], outputDir, extensions=defaultOptions.extensions) {
55
56
  const assetPaths = [];
56
- globResults.forEach((assetPath) => {
57
- assetPath = assetPath.replace(/\\/g, "/")
57
+ globResults.forEach((assetFullPath) => {
58
+ assetFullPath = assetFullPath.replace(/\\/g, "/");
59
+ const assetPath = assetFullPath.replace(outputDir, "")
60
+
58
61
  if (!extensions.includes(path.extname(assetPath).substring(1))) {
59
62
  return;
60
63
  }
61
64
 
62
65
  logGreen(`[ACB] ${assetPath} is an asset! Calculating hash...`);
63
- const assetHash = hashFunction(fs.readFileSync(assetPath));
66
+ const assetHash = hashFunction(fs.readFileSync(assetFullPath));
64
67
  logGreen(`[ACB] ${assetPath} hash = ${assetHash}`);
65
68
 
66
69
  assetPaths.push({
@@ -91,47 +94,37 @@ function writeAsync(outputPath, outputData) {
91
94
  function replaceAssetsInFile(fileData, filePath, assetPathsAndHashes, writeFunc) {
92
95
  let outputString = fileData;
93
96
  let outputChanged = false; // Check if any hashes have been added
94
-
95
- // Check for every asset
96
97
  assetPathsAndHashes.forEach(({assetPath, assetHash}) => {
97
- let found = false;
98
- let indexPush = 0; // With values being replaced, the index values will need to be adjusted
99
- const regex = new RegExp(assetPath.replaceAll("/", "\\/").replaceAll("?", "\\?") + '.*?(?=")', "g")
100
- const matches = outputString.matchAll(regex);
101
-
102
- while ((match = matches.next()).done != true) {
103
- found = true;
104
- const value = match.value
105
- const path = value[0]
106
- logGreen(`[ACB] ${filePath} contains asset ${assetPath} (matched on: ${path})`)
107
-
108
- // Optionally truncate
109
- if (hashTruncate > 0) {
110
- assetHash = assetHash.substring(0, hashTruncate);
111
- }
112
-
113
- const seperator = path.includes("?") ? "&" : "?";
114
- const newPath = `${path}${seperator}v=${assetHash}`;
115
- // Replace asset path with asset path with hash
116
- outputString = outputString.substring(0, value.index + indexPush)
117
- + newPath
118
- + outputString.substring(value.index + indexPush + path.length)
119
-
120
- indexPush += newPath.length - path.length;
121
-
122
- // Write changes to file
123
- outputChanged = true;
98
+ // Optionally truncate
99
+ if (hashTruncate > 0) {
100
+ assetHash = assetHash.substring(0, hashTruncate);
124
101
  }
125
- if (!found) {
126
- logRegular(`[ACB] ${filePath} does NOT contain asset ${assetPath}. Skipping`)
102
+ // find and replace all instances of the asset URL
103
+ const assetPathRegexString = escape(assetPath);
104
+ const regexWithQueryString = new RegExp(`${assetPathRegexString}\\?`, 'g')
105
+ const regexWithoutQueryString = new RegExp(`${assetPathRegexString}(?!\\?)`, 'g')
106
+ const newOutputString = outputString
107
+ .replaceAll(regexWithQueryString, `${assetPath}?v=${assetHash}&`)
108
+ .replaceAll(regexWithoutQueryString, `${assetPath}?v=${assetHash}`);
109
+ // If anything was replaced, track that to write the file after all asset checks
110
+ if (newOutputString != outputString) {
111
+ logGreen(`[ACB] ${filePath} contains asset ${assetPath}`)
112
+ outputChanged = true;
113
+ outputString = newOutputString;
114
+ } else {
115
+ logRegular(`[ACB] ${filePath} does NOT contain asset ${assetPath}. Skipping`)
127
116
  }
128
- });
129
-
117
+ })
130
118
  if (outputChanged) {
131
119
  writeFunc(filePath, outputString);
132
120
  }
133
121
  }
134
122
 
123
+ // Meant to normalise eleventt.after directories.output to dir.output style
124
+ function stripPath(path) {
125
+ return path.replace(/^\.\//m, "");
126
+ }
127
+
135
128
  module.exports = function(eleventyConfig, options=defaultOptions) {
136
129
  // Override default options with set options
137
130
  options = Object.assign(defaultOptions, options, {
@@ -154,9 +147,10 @@ module.exports = function(eleventyConfig, options=defaultOptions) {
154
147
  }
155
148
 
156
149
  if (runAsync) {
157
- eleventyConfig.on("eleventy.after", async ({ dir, results, runMode, outputMode }) => {
158
- logYellow(`[ACB] Collecting assets & calculating hashes using ${globstring}...`);
159
- const assetPathsAndHashes = collectLocalAssets(await glob.glob(dir.output + "/" + globstring, globOptions), dir.output, extensions);
150
+ eleventyConfig.on("eleventy.after", async ({ directories, results, runMode, outputMode }) => {
151
+ const outputDir = stripPath(directories.output);
152
+ logYellow(`[ACB] Collecting assets & calculating hashes using ${globstring} in ${outputDir}...`);
153
+ const assetPathsAndHashes = collectLocalAssets(await glob.glob(outputDir + "/" + globstring, globOptions), outputDir, extensions);
160
154
 
161
155
  logRegular(`[ACB] Replacing in output...`);
162
156
  results.forEach(({inputPath, outputPath, url, content}) => {
@@ -173,9 +167,10 @@ module.exports = function(eleventyConfig, options=defaultOptions) {
173
167
  });
174
168
  });
175
169
  } else {
176
- eleventyConfig.on("eleventy.after", ({ dir, results, runMode, outputMode }) => {
170
+ eleventyConfig.on("eleventy.after", ({ directories, results, runMode, outputMode }) => {
171
+ const outputDir = stripPath(directories.output);
177
172
  logYellow(`[ACB] Collecting assets & calculating hashes using ${globstring}...`);
178
- const assetPathsAndHashes = collectLocalAssets(glob.globSync(dir.output + "/" + globstring, globOptions), dir.output, extensions);
173
+ const assetPathsAndHashes = collectLocalAssets(glob.globSync(outputDir + "/" + globstring, globOptions), outputDir, extensions);
179
174
 
180
175
  logRegular(`[ACB] Replacing in output...`);
181
176
  results.forEach(({inputPath, outputPath, url, content}) => {
package/package.json CHANGED
@@ -1,21 +1,26 @@
1
1
  {
2
2
  "name": "eleventy-auto-cache-buster",
3
- "version": "0.8.4",
3
+ "version": "0.9.1",
4
4
  "description": "Busts cache using ?v= with minimal configuration!",
5
5
  "main": "11tyAutoCacheBuster.js",
6
6
  "repository": "https://github.com/Denperidge/eleventy-auto-cache-buster.git",
7
7
  "author": "Denperidge",
8
8
  "license": "MIT",
9
9
  "scripts": {
10
- "start": "pushd tests && RUNASYNC=0 USESERVE=1 HASHTRUNCATE=16 eleventy && popd",
10
+ "start": "pushd tests/scenarios/8-sync@3 && eleventy && popd",
11
11
  "test": "ava tests/test.mjs --timeout=30s"
12
12
  },
13
13
  "dependencies": {
14
- "glob": "^13.0.6"
14
+ "glob": "^13.0.6",
15
+ "regexp.escape": "^2.0.1"
15
16
  },
16
17
  "devDependencies": {
17
18
  "@11ty/eleventy": "^3.1.2",
19
+ "@codestitchofficial/eleventy-plugin-minify": "^1.1.3",
18
20
  "ava": "^7.0.0",
19
- "jsdom": "^28.1.0"
21
+ "eleventy-test": "^2.0.0",
22
+ "html-minifier-terser": "^7.2.0",
23
+ "jsdom": "^28.1.0",
24
+ "rss-parser": "^3.13.0"
20
25
  }
21
26
  }