@ideasonpurpose/build-tools-wordpress 2.9.1 → 2.10.0

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/AGENTS.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <!--
2
2
  Canonical AGENTS.md: https://gist.github.com/joemaller/d6154fbdb2e5f4670c0b9338d04189e9
3
- Last Modified: 2026-06-26
3
+ Last Modified: 2026-07-06
4
4
  -->
5
5
 
6
6
  # AI Coding Assistant Guidelines
@@ -35,14 +35,13 @@ Before implementing:
35
35
 
36
36
  **Minimum code that solves the problem. Nothing speculative.**
37
37
 
38
- - Look for existing solutions in standard libraries and native platform features.
38
+ - Use standard libraries and native platform features first. Suggest popular, well-maintained alternatives.
39
39
  - Prefer boring, obvious code over clever code.
40
40
  - No features beyond what was asked.
41
41
  - No abstractions for single-use code.
42
42
  - Look for solutions in existing dependencies. If different than the first-choice solution, show pros and cons.
43
43
  - No "flexibility" or "configurability" that wasn't requested.
44
44
  - Only add error handling for realistically possible cases given current scope and style.
45
- - Ask before introducing new dependencies.
46
45
  - If you write 200 lines and it could be 50, rewrite it.
47
46
 
48
47
  Ask yourself: "Would a senior engineer call this overcomplicated?" If yes, simplify.
@@ -53,33 +52,28 @@ Ask yourself: "Would a senior engineer call this overcomplicated?" If yes, simpl
53
52
 
54
53
  When editing existing code:
55
54
 
56
- - Preserve the spirit and conventions of the codebase.
55
+ - Preserve the codebase spirit conventions, and style.
57
56
  - Don't "improve" adjacent code, comments, or formatting.
58
- - Don't remove comments or commented-out code unless asked.
57
+ - Don't remove comments or dead code unless asked.
59
58
  - Don't refactor code that isn't broken.
60
- - Match existing style, even if you'd do it differently.
61
- - If you find dead code, mention it - don't delete it.
62
- - Never run tests unless explicitly asked.
63
- - Never run linters or formatters unless asked.
64
- - Never add code which logs secrets, API keys, tokens, or .env values. If that code exists, say something.
65
-
66
- When your changes create orphans:
67
-
68
- - Remove imports/variables/functions that _your_ changes made unused.
69
- - Do not remove pre-existing dead code unless asked.
59
+ - Never run tests, linters or formatters unless asked.
60
+ - Never log secrets, API keys, tokens, or .env values. If that code exists, say something.
61
+ - Remove imports/variables/functions that _your_ changes orphaned.
70
62
 
71
63
  Every changed line should trace directly to the user's request.
72
64
 
65
+ **Security exception**: Allow sweeping changes to fix real security problems. Explain.
66
+
73
67
  ## 4. Documentation and Comments
74
68
 
75
69
  - Prefer self-documenting code and descriptive names over comments.
76
70
  - Add comments only where the _why_ is not obvious from the code.
77
71
  - Update or remove comments directly invalidated by your changes.
78
72
  - Follow the existing codebase's conventions for types, docstrings, and documentation style.
79
- - When this file and the system prompt disagree, note the conflict and ask for guidance.
73
+ - Note conflicts with the system prompt and ask for guidance.
80
74
 
81
75
  ## 5. Additional Instructions
82
76
 
83
77
  Look for sibling `AGENTS-*.md` files for further instructions on specific concerns (e.g. stylesheets, WordPress development, static site development)
84
78
 
85
- Whenever this file is modified, update the timestamp in the top comment.
79
+ Whenever this file is modified, update the timestamp in the top comment.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. Dates are d
4
4
 
5
5
  Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
6
 
7
+ #### v2.9.1
8
+
9
+ > 26 June 2026
10
+
11
+ - bump deps, format action
12
+
7
13
  #### v2.9.0
8
14
 
9
15
  > 26 June 2026
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @ideasonpurpose/build-tools-wordpress
2
2
 
3
- #### Version 2.9.1
3
+ #### Version 2.10.0
4
4
 
5
5
  [![NPM Version](https://img.shields.io/npm/v/%40ideasonpurpose%2Fbuild-tools-wordpress?logo=npm)](https://www.npmjs.com/package/@ideasonpurpose/build-tools-wordpress)
6
6
  [![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/ideasonpurpose/build-tools-wordpress/npm-publish.yml?logo=github&logoColor=white)](https://github.com/ideasonpurpose/build-tools-wordpress#readme)
@@ -8,13 +8,14 @@
8
8
  }
9
9
  ],
10
10
  "config": {
11
+ "discard-changes": "stash",
11
12
  "optimize-autoloader": true,
12
- "sort-packages": true,
13
- "vendor-dir": "wp-content/themes/iop-theme/vendor",
14
13
  "platform": {
15
14
  "php": "8.4",
16
15
  "ext-intl": "0"
17
- }
16
+ },
17
+ "sort-packages": true,
18
+ "vendor-dir": "wp-content/themes/iop-theme/vendor"
18
19
  },
19
20
  "autoload": {
20
21
  "psr-4": {
@@ -1,3 +1,5 @@
1
+ // @ts-check
2
+
1
3
  import { posix as path } from "path";
2
4
 
3
5
  import { statSync } from "fs";
@@ -34,7 +36,7 @@ if (process.env.WEBPACK_BUNDLE_ANALYZER) process.env.NODE_ENV = "production";
34
36
 
35
37
  const isProduction = process.env.NODE_ENV === "production";
36
38
 
37
- const stats = {
39
+ const __stats = {
38
40
  preset: "normal",
39
41
  cachedAssets: false,
40
42
  assets: true,
@@ -79,6 +81,28 @@ const stats = {
79
81
  loggingDebug: ["sass-loader"],
80
82
  };
81
83
 
84
+ const stats = isProduction
85
+ ? {
86
+ preset: "normal",
87
+ colors: true,
88
+ }
89
+ : {
90
+ all: false,
91
+ errors: true,
92
+ warnings: true,
93
+ errorDetails: false,
94
+ colors: true,
95
+ modules: false,
96
+ assets: false, // ← hides the long asset list on every rebuild
97
+ entrypoints: false,
98
+ hash: false,
99
+ version: false,
100
+ performance: false,
101
+ reasons: false,
102
+ timings: false,
103
+ children: false,
104
+ loggingDebug: false, // only enable sass debug when you really need it
105
+ };
82
106
  /**
83
107
  * @param {Record<string, any>} env - Environment variables from Webpack CLI
84
108
  */
@@ -92,7 +116,6 @@ export default async (env) => {
92
116
 
93
117
  const proxy = isProduction ? {} : await devserverProxy(config);
94
118
 
95
-
96
119
  /**
97
120
  * Simple helper for encoding SVGs as data urls with proper encoding for special characters
98
121
  * @param {Buffer} content
@@ -121,12 +144,12 @@ export default async (env) => {
121
144
 
122
145
  const devtool = config.devtool || false;
123
146
 
124
- // Debug: Log the watchFiles paths
125
147
  const watchPath =
126
148
  path.resolve(config.src, "..") + "/**/*.{php,html,svg,json}";
127
- console.log(chalk.cyan("🔍 Watching files:"), watchPath);
149
+ console.log(chalk.cyan("🔍"), chalk.bold("Watching:"), watchPath);
128
150
  console.log(
129
- chalk.cyan("📁 Theme directory:"),
151
+ chalk.cyan("📁"),
152
+ chalk.bold("Theme:"),
130
153
  path.resolve(config.src, ".."),
131
154
  );
132
155
 
@@ -323,7 +346,11 @@ export default async (env) => {
323
346
  // hot: "only",
324
347
  static: [
325
348
  { directory: config.dist, watch: false },
326
- { directory: config.src, publicPath: config.publicPath.replace('/dist/', '/src/'), watch: false },
349
+ {
350
+ directory: config.src,
351
+ publicPath: config.publicPath.replace("/dist/", "/src/"),
352
+ watch: false,
353
+ },
327
354
  ],
328
355
 
329
356
  client: {
@@ -344,7 +371,9 @@ export default async (env) => {
344
371
 
345
372
  devMiddleware: {
346
373
  index: false, // enable root proxying
347
-
374
+ infrastructureLogging: {
375
+ level: "warn", // or "error" for even stricter
376
+ },
348
377
  writeToDisk: (filePath) => {
349
378
  // // // SHORT_CIRCUIT FOR TESTING
350
379
  // // console.log("DEBUG writeToDisk:", { filePath });
@@ -418,7 +447,11 @@ export default async (env) => {
418
447
  devServer.server.address().port;
419
448
  devServer.compiler._devServer = devServer;
420
449
 
421
- console.log("Listening on port:", port);
450
+ console.log(
451
+ chalk.cyan("●"),
452
+ chalk.bold("Listening:"),
453
+ chalk.blue.underline(`http://localhost:${port}`),
454
+ );
422
455
  },
423
456
 
424
457
  /**
@@ -435,7 +468,9 @@ export default async (env) => {
435
468
  * `/inform` requests with 404s, filling logs and cluttering
436
469
  * terminals. So that's why this is here. I hate it.
437
470
  */
438
- devServer.app.all("/inform", () => false);
471
+ devServer.app.all("/inform", (req, res) => {
472
+ res.status(204).end();
473
+ });
439
474
 
440
475
  /**
441
476
  * The "/webpack/reload" endpoint will trigger a full devServer refresh
@@ -448,7 +483,9 @@ export default async (env) => {
448
483
  */
449
484
  devServer.app.get("/webpack/reload", (req, res) => {
450
485
  console.log(
451
- chalk.yellow("Reload triggered by request to /webpack/reload"),
486
+ chalk.yellow(""),
487
+ chalk.yellow.bold("Reload:"),
488
+ "/webpack/reload",
452
489
  );
453
490
 
454
491
  devServer.sendMessage(
@@ -529,12 +566,13 @@ export default async (env) => {
529
566
  manifestFile: config.manifestFile,
530
567
  }),
531
568
 
532
- new AfterDoneReporterPlugin({
569
+ new WatchRunReporterPlugin({
533
570
  echo: env && env.WEBPACK_SERVE,
534
- // message:
535
- // "Dev site " + chalk.blue.bold(`http://localhost:${process.env.PORT}`),
536
571
  }),
537
572
 
573
+ new AfterDoneReporterPlugin({
574
+ echo: env && env.WEBPACK_SERVE,
575
+ }),
538
576
  new BundleAnalyzerPlugin({
539
577
  analyzerMode: isProduction ? "static" : "disabled",
540
578
  openAnalyzer: false,
@@ -1,78 +1,46 @@
1
+ // @ts-check
2
+
1
3
  import chalk from "chalk";
2
4
  import humanizeDuration from "humanize-duration";
3
5
 
4
6
  /**
5
- * Simple plugin for printing some text after compilation stats are displayed
6
- *
7
- * Messages should be configured in an argument object:
8
- *
9
- * new AfterDoneReporterPlugin({message: "Your Message Here"})
7
+ * Clean post-compilation summary for dev server.
8
+ * Shows status, duration, and the local URL without placeholder text or setTimeout hacks.
10
9
  */
11
10
  export class AfterDoneReporterPlugin {
12
11
  constructor(options = {}) {
13
12
  const defaults = {
14
13
  echo: true,
15
- prefix: `🟢${chalk.gray("(iop)")}:`,
16
- message: "",
17
14
  };
18
15
  this.config = { ...defaults, ...options };
19
- this.name = "IOP Reporter Plugin";
20
- this.messages = [];
16
+ this.name = "IOP AfterDone Reporter";
21
17
  }
22
18
 
23
19
  apply(compiler) {
24
- compiler.hooks.done.tapPromise(this.name, async (stats) => {
25
- if (this.config.echo) {
26
- /**
27
- * NOTE: As of webpack-dev-server vXX.XX.XXX, auto-assigned ports are
28
- * not propagated into the compiler.options.devServer object.
29
- *
30
- * As a workaround, this relies on the following line being added to
31
- * the webpack.config file's devServer.setupMiddlewares method:
32
- *
33
- * devServer.compiler.options.devServer.port = devServer.options.port;
34
- *
35
- */
36
- const { host, port } = compiler.options.devServer;
37
- const { startTime, endTime, modules, assetsInfo } = stats.compilation;
38
- const hostname = host === "0.0.0.0" ? "localhost" : host;
39
-
40
- const time = chalk.yellow.bold(
41
- humanizeDuration(endTime - startTime, { units: ["h", "m", "s"] }),
42
- );
43
- const mCount = chalk.yellow(modules.size);
44
- const aCount = chalk.yellow.bold(assetsInfo.size);
45
-
46
- const messages = [
47
- // `Compiled ${mCount} input modules into ${aCount} files in ${time}`,
48
- // "Dev site " + chalk.blue(`http://${hostname}:${chalk.bold(port)}`),
49
- "Dev site " + chalk.blue(`http://${hostname}:${chalk.bold(port)}`),
50
- this.config.message,
51
- ]
52
- .filter((m) => m.length)
53
- .join("\n" + this.config.prefix + " ");
54
-
55
- setTimeout(() =>
56
- // console.log("\n" + this.config.prefix + " " + messages),
57
- console.log( "🚧 " + messages),
58
- );
59
-
60
- setTimeout(() => {
61
- // console.log(Object.keys(compiler));
62
- // console.log(compiler.options);
63
- });
20
+ compiler.hooks.done.tap(this.name, (stats) => {
21
+ if (!this.config.echo) return;
22
+
23
+ const devServer = compiler.options.devServer || {};
24
+ const host = devServer.host === "0.0.0.0" ? "localhost" : devServer.host || "localhost";
25
+ const port = devServer.port || "auto";
26
+ const url = chalk.blue.underline(`http://${host}:${port}`);
27
+
28
+ const durationMs = stats.endTime && stats.startTime ? stats.endTime - stats.startTime : 0;
29
+ const time = humanizeDuration(durationMs, { units: ["s", "ms"], round: true });
30
+
31
+ const hasErrors = stats.hasErrors();
32
+ const hasWarnings = stats.hasWarnings();
33
+
34
+ let statusLine;
35
+ if (hasErrors) {
36
+ statusLine = `${chalk.red.bold("✖ Failed")} in ${chalk.yellow(time)}`;
37
+ } else if (hasWarnings) {
38
+ statusLine = `${chalk.yellow.bold("⚠ Compiled with warnings")} in ${chalk.yellow(time)}`;
39
+ } else {
40
+ statusLine = `${chalk.green.bold("✔ Compiled")} in ${chalk.yellow(time)}`;
64
41
  }
65
- });
66
-
67
-
68
- // compiler.hooks.done.tapPromise("webpack-dev-server", async (stats) => {
69
- // await stats;
70
- // setTimeout(() => {
71
- // console.log(chalk.bold.magenta("in webpack-dev-server hook"), {
72
- // stats, thing: Object.keys( compiler.options),
73
- // });
74
- // });
75
- // });
76
42
 
43
+ console.log(`\n${statusLine} → ${url}`);
44
+ });
77
45
  }
78
- }
46
+ }
@@ -1,56 +1,61 @@
1
+ import path from "path";
1
2
  import chalk from "chalk";
3
+
2
4
  /**
3
- * Simple plugin for restoring the starting compile message which vanished in
4
- * DevServer v4
5
- *
6
- * Messages should be configured in an argument object:
5
+ * Clean file-change reporting for watch/dev mode.
6
+ * Shows what triggered the recompile without flooding the terminal.
7
7
  *
8
- * new WatchRunReporterPlugin({message: "Your Message Here"})
8
+ * Tracks compiler.hooks.invalid to capture the triggering filename,
9
+ * falling back to compiler.modifiedFiles when available.
9
10
  */
10
11
  export class WatchRunReporterPlugin {
11
12
  constructor(options = {}) {
12
13
  const defaults = {
13
14
  echo: true,
14
- prefix: `🟢${chalk.gray("(iop)")}:`,
15
- message: chalk.bold("Compiling...", ""),
15
+ message: chalk.gray("recompiling..."),
16
16
  };
17
17
  this.config = { ...defaults, ...options };
18
- this.name = "IOP Reporter Plugin";
18
+ this.name = "IOP WatchRun Reporter";
19
+ this.invalidFile = null;
19
20
  }
20
21
 
21
22
  apply(compiler) {
22
- compiler.hooks.watchRun.tapPromise(this.name, async () => {
23
- if (this.config.echo) {
24
- /**
25
- * compiler.modifiedFiles is a Set containing the changed file or files
26
- * along ith the base path containing those files (or the entryPoint?)
27
- *
28
- * Sorting the set (as an Array) puts the base path first (it's the shortest)
29
- * then we remove it from the paths to clean up.
30
- *
31
- * Report a single changed path or the count of changed paths
32
- */
33
- let msg = "";
34
- if (compiler.modifiedFiles) {
35
- let modFiles = Array.from(compiler.modifiedFiles).sort();
36
- const basePath = modFiles[0];
37
- const basePathPattern = new RegExp(`${basePath}/?`, "gi");
38
- modFiles = modFiles
39
- .map((p) => p.replace(basePathPattern, ""))
40
- .filter((p) => p);
41
-
42
- if (modFiles.length > 1) {
43
- msg = `Modified ${modFiles.length - 1} files `;
44
- } else {
45
- msg = `Modified ${chalk.bold.yellow(modFiles[0] || basePath)} `;
46
- }
47
- }
48
- // console.log(this.config.prefix, msg + this.config.message);
49
- // console.clear();
50
- if (msg) {
51
- console.log("\n💫 ", msg);
52
- }
23
+ compiler.hooks.invalid.tap(this.name, (fileName) => {
24
+ this.invalidFile = fileName;
25
+ });
26
+
27
+ compiler.hooks.watchRun.tap(this.name, () => {
28
+ if (!this.config.echo) return;
29
+
30
+ const root = compiler.context || process.cwd();
31
+ const modFiles = compiler.modifiedFiles?.size
32
+ ? Array.from(compiler.modifiedFiles)
33
+ : null;
34
+ const changed =
35
+ modFiles || (this.invalidFile ? [this.invalidFile] : null);
36
+
37
+ this.invalidFile = null;
38
+
39
+ if (!changed) return;
40
+
41
+ const relFiles = changed
42
+ .map((p) => path.relative(root, p) || p)
43
+ .sort();
44
+
45
+ let changeMsg;
46
+ if (relFiles.length === 1) {
47
+ changeMsg = chalk.bold.yellow(relFiles[0]);
48
+ } else if (relFiles.length <= 3) {
49
+ changeMsg = chalk.bold.yellow(relFiles.join(", "));
50
+ } else {
51
+ changeMsg = chalk.bold.yellow(
52
+ `${relFiles.slice(0, 2).join(", ")} +${relFiles.length - 2} more`,
53
+ );
53
54
  }
55
+
56
+ console.log(
57
+ `\n${chalk.cyan("⟳")} Changed: ${changeMsg} ${this.config.message}`,
58
+ );
54
59
  });
55
60
  }
56
- }
61
+ }
@@ -19,13 +19,12 @@ export async function devserverProxy(config) {
19
19
  if (config.proxy === true) {
20
20
  const localPort = await findLocalPort();
21
21
  // console.log({ localPort });
22
- if (localPort && localPort.hostname && localPort.port) {
22
+ if (localPort && localPort.hostname && localPort.port) {
23
23
  target = new URL(`http://${localPort.hostname}:${localPort.port}`);
24
24
  console.log(
25
- chalk.cyan.bold(
26
- `PORT FROM DEVSERVER-PROXY: TRUE ${localPort.port}`,
27
- // target,
28
- ),
25
+ chalk.cyan("↔"),
26
+ chalk.bold("Proxy:"),
27
+ chalk.blue.underline(target.origin),
29
28
  );
30
29
  }
31
30
  } else if (!!isIP(config.proxy)) {
@@ -46,10 +45,11 @@ export async function devserverProxy(config) {
46
45
  if (localPort && localPort.hostname && localPort.port) {
47
46
  target = new URL(`http://${localPort.hostname}:${localPort.port}`);
48
47
  console.log(
49
- "PORT FROM DEVSERVER-PROXY:",
48
+ chalk.cyan(""),
49
+ chalk.bold("Proxy:"),
50
50
  chalk.cyan(config.proxy),
51
- chalk.bold(localPort.port),
52
- // target,
51
+ "→",
52
+ chalk.blue.underline(target.origin),
53
53
  );
54
54
  }
55
55
  }
@@ -64,7 +64,6 @@ export async function devserverProxy(config) {
64
64
  context: [
65
65
  "**",
66
66
  "!/ws",
67
- "!/sockjs-node",
68
67
  "!/__webpack_dev_server__",
69
68
  "!/webpack-dev-server",
70
69
  ],
@@ -76,84 +75,89 @@ export async function devserverProxy(config) {
76
75
  cookieDomainRewrite: "", // was `${config.host}:8080` ??
77
76
  headers: { "Accept-Encoding": "identity" },
78
77
  ws: true,
79
-
80
- onError: (err, req, res) => {
81
- if (err.code === "ECONNRESET") {
82
- console.log(chalk.yellow("Caught ECONNRESET error, ignoring..."));
83
- } else {
84
- console.log("Devserver Proxy Error: ", req.url, err, err.stack);
85
- res.writeHead(500, { "Content-Type": "text-plain" });
86
- res.end("Webpack DevServer Proxy Error: " + err);
87
- }
88
- },
89
-
90
- onProxyReqWs: (proxyReq, req, socket, options, head) => {
91
- socket.on("error", (err) => {
92
- if (err.code !== "EPIPE") {
93
- console.error("WebSocket proxy error:", err);
94
- }
95
- });
96
- },
97
-
98
- onProxyRes: function (proxyRes, req, res) {
99
- /**
100
- * Update urls in files with these content-types
101
- */
102
- const contentTypes = [
103
- "application/javascript",
104
- "application/json",
105
- "multipart/form-data",
106
- "text/css",
107
- "text/html",
108
- "text/plain",
109
- ];
110
-
111
- let originalBody = [];
112
-
113
- proxyRes.on("data", (data) => originalBody.push(data));
114
-
115
- proxyRes.on("end", () => {
116
- res.statusCode = proxyRes.statusCode;
117
- if (proxyRes.statusMessage) {
118
- res.statusMessage = proxyRes.statusMessage;
78
+ // prevent WDS from injecting its logger (stops per-request [HPM] GET spam)
79
+ logger: { info: () => {}, warn: () => {}, error: () => {} },
80
+
81
+ // http-proxy-middleware v3+ event API (webpack-dev-server v6)
82
+ on: {
83
+ error: (err, req, res) => {
84
+ if (err.code === "ECONNRESET") {
85
+ console.log(chalk.yellow("Proxy: connection reset, ignoring"));
86
+ } else {
87
+ console.log(chalk.red("Proxy error:"), req.url, err, err.stack);
88
+ res.writeHead(500, { "Content-Type": "text-plain" });
89
+ res.end("Webpack DevServer Proxy Error: " + err);
119
90
  }
91
+ },
120
92
 
121
- Object.keys(proxyRes.headers).forEach((key) => {
122
- let header = proxyRes.headers[key];
123
- if (typeof header == "string") {
124
- header = header.replace(
125
- new RegExp(target.host, "gi"),
126
- req.headers.host,
127
- );
93
+ proxyReqWs: (proxyReq, req, socket, options, head) => {
94
+ socket.on("error", (err) => {
95
+ if (err.code !== "EPIPE") {
96
+ console.error(chalk.red("WebSocket proxy error:"), err);
128
97
  }
129
- res.setHeader(String(key).trim(), header);
130
98
  });
99
+ },
100
+
101
+ proxyRes: function (proxyRes, req, res) {
102
+ /**
103
+ * Update urls in files with these content-types
104
+ */
105
+ const contentTypes = [
106
+ "application/javascript",
107
+ "application/json",
108
+ "multipart/form-data",
109
+ "text/css",
110
+ "text/html",
111
+ "text/plain",
112
+ ];
113
+
114
+ let originalBody = [];
115
+
116
+ proxyRes.on("data", (data) => originalBody.push(data));
117
+
118
+ proxyRes.on("end", () => {
119
+ res.statusCode = proxyRes.statusCode;
120
+ if (proxyRes.statusMessage) {
121
+ res.statusMessage = proxyRes.statusMessage;
122
+ }
131
123
 
132
- originalBody = Buffer.concat(originalBody);
133
- let newBody;
134
-
135
- // const type = proxyRes.headers["content-type"]?.split(";")[0].trim() ?? null;
136
- const type = proxyRes.headers["content-type"]?.split(";")[0].trim();
137
-
138
- const wpRegexp = new RegExp(
139
- "^/wp-(?:admin|includes|content/plugins).*(?:css|js|map)$",
140
- );
141
- const originRegExp = new RegExp(
142
- `(http:\\\\/\\\\/|http://)${target.host}`,
143
- "gi",
144
- );
145
-
146
- if (contentTypes.includes(type) && !wpRegexp.test(req.path)) {
147
- newBody = originalBody
148
- .toString("utf8")
149
- .replace(originRegExp, `$1${req.headers.host}`);
150
- res.setHeader("Content-Length", Buffer.byteLength(newBody));
151
- } else {
152
- newBody = originalBody;
153
- }
124
+ Object.keys(proxyRes.headers).forEach((key) => {
125
+ let header = proxyRes.headers[key];
126
+ if (typeof header == "string") {
127
+ header = header.replace(
128
+ new RegExp(target.host, "gi"),
129
+ req.headers.host,
130
+ );
131
+ }
132
+ res.setHeader(String(key).trim(), header);
133
+ });
134
+
135
+ originalBody = Buffer.concat(originalBody);
136
+ let newBody;
137
+
138
+ // const type = proxyRes.headers["content-type"]?.split(";")[0].trim() ?? null;
139
+ const type = proxyRes.headers["content-type"]?.split(";")[0].trim();
140
+
141
+ const wpRegexp = new RegExp(
142
+ "^/wp-(?:admin|includes|content/plugins).*(?:css|js|map)$",
143
+ );
144
+ const originRegExp = new RegExp(
145
+ `(http:\\\\/\\\\/|http://)${target.host}`,
146
+ "gi",
147
+ );
148
+
149
+ if (contentTypes.includes(type) && !wpRegexp.test(req.path)) {
150
+ newBody = originalBody
151
+ .toString("utf8")
152
+ .replace(originRegExp, `$1${req.headers.host}`);
153
+ res.setHeader("Content-Length", Buffer.byteLength(newBody));
154
+ } else {
155
+ newBody = originalBody;
156
+ }
154
157
 
155
- res.end(newBody);
156
- });
158
+ res.end(newBody);
159
+ });
160
+ },
157
161
  },
158
162
  },
159
163
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ideasonpurpose/build-tools-wordpress",
3
- "version": "2.9.1",
3
+ "version": "2.10.0",
4
4
  "description": "Build scripts and dependencies for IOP's WordPress development environments.",
5
5
  "homepage": "https://github.com/ideasonpurpose/build-tools-wordpress#readme",
6
6
  "bugs": {
@@ -41,38 +41,37 @@
41
41
  "@rollup/plugin-json": "^6.1.0",
42
42
  "@rollup/plugin-node-resolve": "^16.0.3",
43
43
  "@svgr/webpack": "^8.1.0",
44
- "@wordpress/dependency-extraction-webpack-plugin": "^6.49.0",
44
+ "@wordpress/dependency-extraction-webpack-plugin": "^6.51.0",
45
45
  "ansi-html": "^0.0.9",
46
46
  "archiver": "^8.0.0",
47
- "autoprefixer": "^10.5.2",
47
+ "autoprefixer": "^10.5.3",
48
48
  "babel-loader": "^10.1.1",
49
- "caniuse-lite": "^1.0.30001799",
49
+ "caniuse-lite": "^1.0.30001805",
50
50
  "chalk": "^5.6.2",
51
51
  "chalk-cli": "^6.0.0",
52
52
  "classnames": "^2.5.1",
53
- "cli-truncate": "^6.0.1",
53
+ "cli-truncate": "^6.1.1",
54
54
  "copy-webpack-plugin": "^14.0.0",
55
55
  "cosmiconfig": "^9.0.2",
56
56
  "css-loader": "^7.1.4",
57
57
  "cssnano": "^8.0.2",
58
58
  "dotenv": "^17.4.2",
59
59
  "esbuild-loader": "^4.5.0",
60
- "eslint": "^10.6.0",
61
- "filesize": "^11.0.19",
62
- "fs-extra": "^11.3.5",
63
- "globby": "^16.2.0",
60
+ "eslint": "^10.7.0",
61
+ "filesize": "^11.0.22",
62
+ "fs-extra": "^11.3.6",
63
+ "globby": "^16.2.1",
64
64
  "html-webpack-plugin": "^5.6.7",
65
- "http-proxy": "^1.18.1",
66
- "humanize-duration": "^3.33.2",
65
+ "humanize-duration": "^3.34.0",
67
66
  "image-minimizer-webpack-plugin": "^5.0.0",
68
67
  "is-text-path": "^3.0.0",
69
68
  "lodash": "^4.18.1",
70
69
  "mini-css-extract-plugin": "^2.10.2",
71
70
  "ora": "^9.4.1",
72
- "postcss": "^8.5.15",
71
+ "postcss": "^8.5.19",
73
72
  "postcss-loader": "^8.2.1",
74
73
  "postcss-scss": "^4.0.9",
75
- "prettier": "^3.8.5",
74
+ "prettier": "^3.9.5",
76
75
  "pretty-hrtime": "^1.0.3",
77
76
  "read-package-up": "^12.0.0",
78
77
  "replacestream": "^4.0.3",
@@ -80,25 +79,27 @@
80
79
  "sass-embedded": "^1.100.0",
81
80
  "sass-loader": "^17.0.0",
82
81
  "semver": "^7.8.5",
83
- "sharp": "^0.35.2",
82
+ "sharp": "^0.35.3",
84
83
  "sort-package-json": "^4.0.0",
85
84
  "string-length": "^7.0.1",
86
85
  "style-loader": "^4.0.0",
87
- "svgo": "^4.0.1",
86
+ "svgo": "^4.0.2",
88
87
  "svgo-loader": "^5.0.0",
89
88
  "version-everything": "^0.12.2",
90
- "webpack": "^5.108.1",
91
- "webpack-bundle-analyzer": "^5.3.0",
92
- "webpack-dev-middleware": "^8.0.3",
93
- "webpack-dev-server": "^5.2.5",
89
+ "webpack": "^5.108.4",
90
+ "webpack-bundle-analyzer": "^5.3.1",
91
+ "webpack-dev-server": "^6.0.0",
94
92
  "webpack-manifest-plugin": "^6.0.1"
95
93
  },
96
94
  "peerDependencies": {
97
95
  "webpack-cli": "^6.0.1"
98
96
  },
97
+ "engines": {
98
+ "node": ">=22.15.0"
99
+ },
99
100
  "devDependencies": {
100
- "@vitest/coverage-v8": "^4.1.9",
101
- "vitest": "^4.1.9"
101
+ "@vitest/coverage-v8": "^4.1.10",
102
+ "vitest": "^4.1.10"
102
103
  },
103
104
  "version-everything": {
104
105
  "files": [
@@ -106,8 +107,8 @@
106
107
  ]
107
108
  },
108
109
  "allowScripts": {
109
- "@parcel/watcher@2.5.1": true,
110
110
  "esbuild@0.28.1": true,
111
- "fsevents@2.3.3": true
111
+ "fsevents@2.3.3": true,
112
+ "@parcel/watcher@2.5.6": true
112
113
  }
113
114
  }
@@ -82,15 +82,15 @@ test("Proxy boolean false", async () => {
82
82
  expect(await devserverProxy({ proxy })).toStrictEqual({ proxy: [] });
83
83
  });
84
84
 
85
- test("test the returned proxy onError handler", async () => {
85
+ test("test the returned proxy on.error handler", async () => {
86
86
  const logSpy = vi.spyOn(console, "log");
87
87
  const actual = await devserverProxy({ proxy: true });
88
88
 
89
89
  const err = { code: "ECONNRESET" };
90
90
 
91
- actual.proxy[0].onError(err, "req", "res");
91
+ actual.proxy[0].on.error(err, "req", "res");
92
92
  expect(logSpy).toHaveBeenLastCalledWith(
93
- expect.stringContaining("ECONNRESET"),
93
+ expect.stringContaining("connection reset"),
94
94
  );
95
95
 
96
96
  err.code = "Unknown Error Code";
@@ -99,10 +99,10 @@ test("test the returned proxy onError handler", async () => {
99
99
  const req = { url: "url" };
100
100
  const res = { writeHead: vi.fn(), end: vi.fn() };
101
101
 
102
- actual.proxy[0].onError(err, req, res);
102
+ actual.proxy[0].on.error(err, req, res);
103
103
 
104
104
  expect(logSpy).toHaveBeenLastCalledWith(
105
- expect.stringContaining("Devserver Proxy Error"),
105
+ expect.stringContaining("Proxy error"),
106
106
  req.url,
107
107
  expect.any(Object),
108
108
  err.stack,
@@ -114,10 +114,10 @@ test("test the returned proxy onError handler", async () => {
114
114
  );
115
115
  });
116
116
 
117
- test("onProxyRes Handler", async () => {
117
+ test("on.proxyRes Handler", async () => {
118
118
  const config = { proxy: "http://localhost:3000" };
119
119
  const result = await devserverProxy(config);
120
- const onProxyRes = result.proxy[0].onProxyRes;
120
+ const onProxyRes = result.proxy[0].on.proxyRes;
121
121
 
122
122
  const mockProxyRes = new EventEmitter();
123
123
  mockProxyRes.statusCode = 200;
@@ -152,10 +152,10 @@ test("onProxyRes Handler", async () => {
152
152
  );
153
153
  });
154
154
 
155
- test("onProxyRes Handler passthrough", async () => {
155
+ test("on.proxyRes Handler passthrough", async () => {
156
156
  const config = { proxy: "http://localhost:3000" };
157
157
  const result = await devserverProxy(config);
158
- const onProxyRes = result.proxy[0].onProxyRes;
158
+ const onProxyRes = result.proxy[0].on.proxyRes;
159
159
 
160
160
  const mockProxyRes = new EventEmitter();
161
161
  mockProxyRes.statusCode = 200;
@@ -190,9 +190,9 @@ test("onProxyRes Handler passthrough", async () => {
190
190
  );
191
191
  });
192
192
 
193
- test("onProxyReqWs handler", async () => {
193
+ test("on.proxyReqWs handler", async () => {
194
194
  const result = await devserverProxy({ proxy: "http://example.com" });
195
- const onProxyReqWs = result.proxy[0].onProxyReqWs;
195
+ const onProxyReqWs = result.proxy[0].on.proxyReqWs;
196
196
 
197
197
  const socket = new EventEmitter();
198
198
  const errSpy = vi.spyOn(console, "error");
@@ -202,7 +202,8 @@ test("onProxyReqWs handler", async () => {
202
202
  expect(errSpy).not.toHaveBeenCalled();
203
203
 
204
204
  socket.emit("error", { code: "OTHER" });
205
- expect(errSpy).toHaveBeenCalledWith("WebSocket proxy error:", {
206
- code: "OTHER",
207
- });
205
+ expect(errSpy).toHaveBeenCalledWith(
206
+ expect.stringContaining("WebSocket proxy error"),
207
+ { code: "OTHER" },
208
+ );
208
209
  });