@ideasonpurpose/build-tools-wordpress 2.8.2 → 2.8.4

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/CHANGELOG.md CHANGED
@@ -4,6 +4,19 @@ 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.8.3
8
+
9
+ > 5 June 2026
10
+
11
+ - make formatting conditionals work with npx again
12
+ - add WP_ENVIRONMENT_TYPE to docker-compose environment
13
+
14
+ #### v2.8.2
15
+
16
+ > 3 June 2026
17
+
18
+ - update zip script to use ESM archiver
19
+
7
20
  #### v2.8.1
8
21
 
9
22
  > 3 June 2026
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @ideasonpurpose/build-tools-wordpress
2
2
 
3
- #### Version 2.8.2
3
+ #### Version 2.8.4
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)
@@ -37,7 +37,8 @@ Webpack handles SVG files differently based on import context:
37
37
 
38
38
  - **In JS/TSX files**:
39
39
  - With `?url` query (e.g., `import svg from 'file.svg?url'`): Treated as assets, inlined as data URIs if under 4KB, else files.
40
- - Without `?url`: Converted to React components using `@svgr/webpack` for direct JSX usage.
40
+ - With `?react` query (e.g., `import Icon from 'file.svg?react'`): Explicitly converted to a React component using `@svgr/webpack`.
41
+ - Without `?url` or `?react`: Converted to React components using `@svgr/webpack` for direct JSX usage (default behavior when imported from `.jsx`/`.tsx`).
41
42
 
42
43
  Data URIs are generated as `data:image/svg+xml,<url-encoded-content>` using more efficient URL-encoding, not base64.
43
44
 
@@ -58,7 +58,7 @@ const isInTag = (html, offset) => {
58
58
  */
59
59
  export function tokenizeHTML(htmlContent) {
60
60
  let tokenizedHTML = "";
61
- const phpCodeBlocks = new Map(); // Changed to Map for better performance and type safety
61
+ const phpCodeBlocks = new Map(); // Changed to Map for better performance and type safety
62
62
  let tokenCount = 0;
63
63
 
64
64
  /**
@@ -182,4 +182,5 @@ export async function main(filepath = process.argv[2]) {
182
182
  }
183
183
  await formatHTMLThenPHP(resolve(filepath));
184
184
  }
185
- if (import.meta.url === `file://${process.argv[1]}`) main();
185
+
186
+ if (process.argv[2]) main();
@@ -111,9 +111,9 @@ export function normalizeCommentTagSpacing(content) {
111
111
 
112
112
  if (block === "wp:paragraph") {
113
113
  newContent = newContent
114
- .replace(/\n\s*<p>\s*/g, "\n<p>")
114
+ .replace(/\n\s*(<p[^>]*>)\s*/g, "\n$1")
115
115
  .replace(/\s*<\/p>/g, "</p>")
116
- .replace(/<p>[\s\S]*?<\/p>/g, (match) =>
116
+ .replace(/<p[^>]*>[\s\S]*?<\/p>/g, (match) =>
117
117
  match.replace(/\s+/g, " ").trim(),
118
118
  );
119
119
  newContent = newContent.replace(/\n{3,}/g, "\n\n").replace(/\s+$/, "\n");
@@ -211,4 +211,4 @@ export async function main(filepath = process.argv[2]) {
211
211
  }
212
212
  await formatWPBlockPattern(resolve(filepath));
213
213
  }
214
- if (import.meta.url === `file://${process.argv[1]}`) main();
214
+ if (process.argv[2]) main();
@@ -4,7 +4,6 @@
4
4
  *
5
5
  * This config allows for immediate optimization of SVGs in the editor
6
6
  *
7
- *
8
7
  * @links
9
8
  * - SVGO: https://github.com/svg/svgo
10
9
  * - SVGO preset-default docs: https://svgo.dev/docs/preset-default
@@ -14,19 +13,62 @@
14
13
 
15
14
  export default {
16
15
  js2svg: {
17
- indent: 4, // number
18
- pretty: true, // boolean
16
+ indent: 4,
17
+ pretty: true,
19
18
  },
20
19
 
21
20
  plugins: [
21
+ {
22
+ name: "addDimensionsFromViewBox",
23
+ type: "visitor",
24
+ fn: () => {
25
+ return {
26
+ element: {
27
+ enter: (node) => {
28
+ if (node.name !== "svg") return;
29
+ if (!node.attributes.viewBox) return;
30
+ if (node.attributes.width && node.attributes.height) return;
31
+
32
+ const parts = node.attributes.viewBox.trim().split(/[\s,]+/);
33
+ if (parts.length !== 4) return;
34
+
35
+ if (!node.attributes.width) {
36
+ node.attributes.width = parts[2];
37
+ }
38
+ if (!node.attributes.height) {
39
+ node.attributes.height = parts[3];
40
+ }
41
+ },
42
+ },
43
+ };
44
+ },
45
+ },
46
+ {
47
+ name: "removeTopLevelFillNone",
48
+ type: "visitor",
49
+ fn: () => {
50
+ return {
51
+ element: {
52
+ enter: (node) => {
53
+ if (node.name !== "svg") return;
54
+ if (node.attributes.fill !== "none") return;
55
+
56
+ delete node.attributes.fill;
57
+ },
58
+ },
59
+ };
60
+ },
61
+ },
22
62
  {
23
63
  name: "preset-default",
24
64
  params: {
25
65
  overrides: {
26
66
  cleanupIds: false,
67
+ removeUselessStrokeAndFill: {
68
+ removeNone: true,
69
+ },
27
70
  },
28
71
  },
29
72
  },
30
- "removeDimensions",
31
73
  ],
32
74
  };
@@ -219,6 +219,9 @@ export default async (env) => {
219
219
  * To import an SVG file as a src url, append ?url to the filename:
220
220
  * import svg from './assets/file.svg?url'
221
221
  *
222
+ * To force an SVG as a React component, append ?react:
223
+ * import Icon from './assets/file.svg?react'
224
+ *
222
225
  * @link https://react-svgr.com/docs/webpack/#use-svgr-and-asset-svg-in-the-same-project
223
226
  */
224
227
  {
@@ -243,10 +246,15 @@ export default async (env) => {
243
246
  dataUrl: svgDataUrlHelper,
244
247
  },
245
248
  },
249
+ {
250
+ test: /\.svg$/i,
251
+ resourceQuery: /react/, // *.svg?react forces React component via SVGR
252
+ use: ["@svgr/webpack"],
253
+ },
246
254
  {
247
255
  test: /\.svg$/i,
248
256
  issuer: /\.[jt]sx?$/,
249
- resourceQuery: { not: [/url/] }, // exclude react component if *.svg?url
257
+ resourceQuery: { not: [/url/, /react/] }, // exclude react component if *.svg?url or *.svg?react
250
258
  use: ["@svgr/webpack"],
251
259
  },
252
260
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ideasonpurpose/build-tools-wordpress",
3
- "version": "2.8.2",
3
+ "version": "2.8.4",
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": {
@@ -34,30 +34,30 @@
34
34
  },
35
35
  "prettier": "@ideasonpurpose/prettier-config",
36
36
  "dependencies": {
37
- "@ideasonpurpose/prettier-config": "^1.0.1",
37
+ "@ideasonpurpose/prettier-config": "^1.1.0",
38
38
  "@ideasonpurpose/stylelint-config": "^1.1.6",
39
39
  "@prettier/plugin-php": "^0.25.0",
40
40
  "@rollup/plugin-commonjs": "^29.0.3",
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.47.0",
44
+ "@wordpress/dependency-extraction-webpack-plugin": "^6.48.1",
45
45
  "ansi-html": "^0.0.9",
46
46
  "archiver": "^8.0.0",
47
- "autoprefixer": "^10.5.0",
47
+ "autoprefixer": "^10.5.1",
48
48
  "babel-loader": "^10.1.1",
49
- "caniuse-lite": "^1.0.30001793",
49
+ "caniuse-lite": "^1.0.30001799",
50
50
  "chalk": "^5.6.2",
51
51
  "chalk-cli": "^6.0.0",
52
52
  "classnames": "^2.5.1",
53
- "cli-truncate": "^6.0.0",
53
+ "cli-truncate": "^6.0.1",
54
54
  "copy-webpack-plugin": "^14.0.0",
55
- "cosmiconfig": "^9.0.1",
55
+ "cosmiconfig": "^9.0.2",
56
56
  "css-loader": "^7.1.4",
57
- "cssnano": "^8.0.1",
57
+ "cssnano": "^8.0.2",
58
58
  "dotenv": "^17.4.2",
59
- "esbuild-loader": "^4.4.3",
60
- "eslint": "^10.4.1",
59
+ "esbuild-loader": "^4.5.0",
60
+ "eslint": "^10.5.0",
61
61
  "filesize": "^11.0.17",
62
62
  "fs-extra": "^11.3.5",
63
63
  "globby": "^16.2.0",
@@ -68,20 +68,20 @@
68
68
  "is-text-path": "^3.0.0",
69
69
  "lodash": "^4.18.1",
70
70
  "mini-css-extract-plugin": "^2.10.2",
71
- "ora": "^9.4.0",
71
+ "ora": "^9.4.1",
72
72
  "postcss": "^8.5.15",
73
73
  "postcss-loader": "^8.2.1",
74
74
  "postcss-scss": "^4.0.9",
75
- "prettier": "^3.8.3",
75
+ "prettier": "^3.8.4",
76
76
  "pretty-hrtime": "^1.0.3",
77
77
  "read-package-up": "^12.0.0",
78
78
  "replacestream": "^4.0.3",
79
79
  "rimraf": "^6.1.3",
80
80
  "sass-embedded": "^1.100.0",
81
81
  "sass-loader": "^17.0.0",
82
- "semver": "^7.8.1",
83
- "sharp": "^0.34.5",
84
- "sort-package-json": "^3.7.0",
82
+ "semver": "^7.8.5",
83
+ "sharp": "^0.35.2",
84
+ "sort-package-json": "^4.0.0",
85
85
  "string-length": "^7.0.1",
86
86
  "style-loader": "^4.0.0",
87
87
  "svgo": "^4.0.1",
@@ -90,19 +90,24 @@
90
90
  "webpack": "^5.107.2",
91
91
  "webpack-bundle-analyzer": "^5.3.0",
92
92
  "webpack-dev-middleware": "^8.0.3",
93
- "webpack-dev-server": "^5.2.4",
93
+ "webpack-dev-server": "^5.2.5",
94
94
  "webpack-manifest-plugin": "^6.0.1"
95
95
  },
96
96
  "peerDependencies": {
97
97
  "webpack-cli": "^6.0.1"
98
98
  },
99
99
  "devDependencies": {
100
- "@vitest/coverage-v8": "^4.1.8",
101
- "vitest": "^4.1.8"
100
+ "@vitest/coverage-v8": "^4.1.9",
101
+ "vitest": "^4.1.9"
102
102
  },
103
103
  "version-everything": {
104
104
  "files": [
105
105
  "README.md"
106
106
  ]
107
+ },
108
+ "allowScripts": {
109
+ "@parcel/watcher@2.5.1": true,
110
+ "esbuild@0.28.1": true,
111
+ "fsevents@2.3.3": true
107
112
  }
108
113
  }
@@ -0,0 +1,15 @@
1
+ <?php
2
+ /**
3
+ * Title: Paragraph Whitespace Attribute Test
4
+ */
5
+ ?>
6
+
7
+ <!-- wp:paragraph -->
8
+ <p class="example classnames" style="color:red">
9
+ Amet dolore laborum tempor mollit ea magna enim minim sunt nostrud.
10
+ Sit ut labore laborum culpa sint aliqua aliqua reprehenderit
11
+ consectetur eiud sit. Ea non laborum duis enim laborum reprehenderit.
12
+ </p>
13
+
14
+
15
+ <!-- /wp:paragraph -->
@@ -0,0 +1,9 @@
1
+ <?php
2
+ /**
3
+ * Title: Paragraph Whitespace Attribute Test
4
+ */
5
+ ?>
6
+
7
+ <!-- wp:paragraph -->
8
+ <p class="example classnames" style="color:red">Amet dolore laborum tempor mollit ea magna enim minim sunt nostrud. Sit ut labore laborum culpa sint aliqua aliqua reprehenderit consectetur eiud sit. Ea non laborum duis enim laborum reprehenderit.</p>
9
+ <!-- /wp:paragraph -->
@@ -147,6 +147,23 @@ describe("Normalize whitespace", () => {
147
147
  expect(actual).toBe(expected);
148
148
  });
149
149
 
150
+ test("Whitespace handling in paragraphs with attributes", async () => {
151
+ const input = (
152
+ await readFile(
153
+ "./test/fixtures/format-wp-block-pattern/paragraph-whitespace-with-attributes.php",
154
+ )
155
+ ).toString();
156
+
157
+ const expected = (
158
+ await readFile(
159
+ "./test/fixtures/format-wp-block-pattern/paragraph-whitespace-with-attributes__formatted.php",
160
+ )
161
+ ).toString();
162
+
163
+ const actual = normalizeCommentTagSpacing(input);
164
+ expect(actual).toBe(expected);
165
+ });
166
+
150
167
  test("normalizeNewlines for coverage", async () => {
151
168
  const input = "Line 1\nLine 2\n \n \n\n\n\nLine 3\nLine 4";
152
169
  const expected = "Line 1\nLine 2\n\nLine 3\nLine 4\n";
@@ -63,6 +63,7 @@ services:
63
63
  - 9003
64
64
 
65
65
  # Link external plugin projects by defining host:container path pairs in .env
66
+ # Set a custom environment by assigning a value to WP_ENVIRONMENT_TYPE
66
67
  environment:
67
68
  IOP_DEV_PLUGIN_1:
68
69
  IOP_DEV_PLUGIN_2:
@@ -72,6 +73,7 @@ services:
72
73
  IOP_DEV_PLUGIN_6:
73
74
  IOP_DEV_PLUGIN_7:
74
75
  IOP_DEV_PLUGIN_8:
76
+ WP_ENVIRONMENT_TYPE:
75
77
 
76
78
  # Required for iptables port-mapping to work inside the Docker image
77
79
  # This is used to fix a PHP/WordPress issue where internal requests