@ideasonpurpose/build-tools-wordpress 2.0.1 → 2.0.3
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 +12 -0
- package/README.md +1 -1
- package/example/docker-compose.yml +299 -0
- package/lib/devserver-proxy.js +10 -6
- package/package.json +28 -28
- package/test/{devserver-proxy.test.ts → devserver-proxy.test.js} +114 -33
- package/test/{find-local-docker-port.test.ts → find-local-docker-port.test.js} +2 -0
- package/example/ideasonpurpose.config.js +0 -29
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,18 @@ 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.0.2
|
|
8
|
+
|
|
9
|
+
> 13 January 2025
|
|
10
|
+
|
|
11
|
+
- bump deps
|
|
12
|
+
|
|
13
|
+
#### v2.0.1
|
|
14
|
+
|
|
15
|
+
> 19 October 2024
|
|
16
|
+
|
|
17
|
+
- another Sass bump
|
|
18
|
+
|
|
7
19
|
#### v2.0.0
|
|
8
20
|
|
|
9
21
|
> 19 October 2024
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @ideasonpurpose/build-tools-wordpress
|
|
2
2
|
|
|
3
|
-
#### Version 2.0.
|
|
3
|
+
#### Version 2.0.3
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@ideasonpurpose/build-tools-wordpress)
|
|
6
6
|
[](https://github.com/ideasonpurpose/build-tools-wordpress#readme)
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
services:
|
|
2
|
+
# Primary database for the local WordPress development environment.
|
|
3
|
+
# Image from: https://hub.docker.com/_/mysql
|
|
4
|
+
db:
|
|
5
|
+
image: &db_img mysql:8.4
|
|
6
|
+
restart: always
|
|
7
|
+
volumes:
|
|
8
|
+
- db_data:/var/lib/mysql
|
|
9
|
+
- ./_db:/docker-entrypoint-initdb.d
|
|
10
|
+
# - ./_log/mysql:/var/log/mysql
|
|
11
|
+
environment:
|
|
12
|
+
MYSQL_ALLOW_EMPTY_PASSWORD: 1
|
|
13
|
+
MYSQL_DATABASE: wordpress
|
|
14
|
+
MYSQL_USER: wordpress
|
|
15
|
+
MYSQL_PASSWORD: wordpress
|
|
16
|
+
# command: >
|
|
17
|
+
# --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
|
|
18
|
+
|
|
19
|
+
# Ideas On Purpose's local WordPress development environment.
|
|
20
|
+
# Update image version with `docker run ideasonpurpose/wordpress init`
|
|
21
|
+
# Project info: https://github.com/ideasonpurpose/docker-wordpress-dev
|
|
22
|
+
wordpress:
|
|
23
|
+
depends_on:
|
|
24
|
+
- db
|
|
25
|
+
# image: &wp_img ideasonpurpose/wordpress:dev
|
|
26
|
+
image: &wp_img ideasonpurpose/wordpress:6.7.2
|
|
27
|
+
restart: always
|
|
28
|
+
volumes:
|
|
29
|
+
- wp_data:/var/www/html
|
|
30
|
+
- ./wp-content/themes/${npm_package_name:-ioptheme}:/var/www/html/wp-content/themes/${npm_package_name:-ioptheme}
|
|
31
|
+
- ./wp-content/plugins:/var/www/html/wp-content/plugins
|
|
32
|
+
- ./wp-content/uploads:/var/www/html/wp-content/uploads
|
|
33
|
+
- ${IOP_DEV_PLUGIN_1:-/tmp/null:/tmp/IOP_DEV_PLUGIN_1}
|
|
34
|
+
- ${IOP_DEV_PLUGIN_2:-/tmp/null:/tmp/IOP_DEV_PLUGIN_2}
|
|
35
|
+
- ${IOP_DEV_PLUGIN_3:-/tmp/null:/tmp/IOP_DEV_PLUGIN_3}
|
|
36
|
+
- ${IOP_DEV_PLUGIN_4:-/tmp/null:/tmp/IOP_DEV_PLUGIN_4}
|
|
37
|
+
- ${IOP_DEV_PLUGIN_5:-/tmp/null:/tmp/IOP_DEV_PLUGIN_5}
|
|
38
|
+
- ${IOP_DEV_PLUGIN_6:-/tmp/null:/tmp/IOP_DEV_PLUGIN_6}
|
|
39
|
+
- ${IOP_DEV_PLUGIN_7:-/tmp/null:/tmp/IOP_DEV_PLUGIN_7}
|
|
40
|
+
- ${IOP_DEV_PLUGIN_8:-/tmp/null:/tmp/IOP_DEV_PLUGIN_8}
|
|
41
|
+
- ./webpack/xdebug:/tmp/xdebug
|
|
42
|
+
|
|
43
|
+
# Publish port 80 to an ephemeral host port to prepare for future local build tools
|
|
44
|
+
ports:
|
|
45
|
+
- "80"
|
|
46
|
+
|
|
47
|
+
# Internally expose port 9003 for XDebug and profiling
|
|
48
|
+
expose:
|
|
49
|
+
- 9003
|
|
50
|
+
|
|
51
|
+
# Link external plugin projects by defining host:container path pairs in .env
|
|
52
|
+
environment:
|
|
53
|
+
IOP_DEV_PLUGIN_1:
|
|
54
|
+
IOP_DEV_PLUGIN_2:
|
|
55
|
+
IOP_DEV_PLUGIN_3:
|
|
56
|
+
IOP_DEV_PLUGIN_4:
|
|
57
|
+
IOP_DEV_PLUGIN_5:
|
|
58
|
+
IOP_DEV_PLUGIN_6:
|
|
59
|
+
IOP_DEV_PLUGIN_7:
|
|
60
|
+
IOP_DEV_PLUGIN_8:
|
|
61
|
+
|
|
62
|
+
# Apache will throw errors for any ulimit value below 8192
|
|
63
|
+
# NOTE THAT THIS MIGHT BE MORE THAN THE SYSTEM OFFERS
|
|
64
|
+
# TODO: Still true?
|
|
65
|
+
# TODO: Testing removal. 2025-03-18
|
|
66
|
+
# ulimits:
|
|
67
|
+
# nofile: 8192
|
|
68
|
+
|
|
69
|
+
# Required for iptables port-mapping to work inside the Docker image
|
|
70
|
+
# This is used to fix a PHP/WordPress issue where internal requests
|
|
71
|
+
# from Site Health tried to load from external ports.
|
|
72
|
+
cap_add:
|
|
73
|
+
- NET_ADMIN
|
|
74
|
+
|
|
75
|
+
# # TODO: Deprecated and likely ready to remove 2025-03-18
|
|
76
|
+
# # Ideas On Purpose's development toolchain
|
|
77
|
+
# # Image from: https://hub.docker.com/r/ideasonpurpose/docker-build
|
|
78
|
+
# tools:
|
|
79
|
+
# # image: ideasonpurpose/docker-build:dev
|
|
80
|
+
# image: ideasonpurpose/docker-build:0.17.2
|
|
81
|
+
# user: "${UID:-1000}:${GID:-1000}"
|
|
82
|
+
# depends_on:
|
|
83
|
+
# - wordpress
|
|
84
|
+
# volumes:
|
|
85
|
+
# - .:/usr/src/site/
|
|
86
|
+
# ports:
|
|
87
|
+
# - "${npm_config_port:-8080}:8080"
|
|
88
|
+
# environment:
|
|
89
|
+
# PORT: ${npm_config_port:-8080}
|
|
90
|
+
# entrypoint: npm run
|
|
91
|
+
# command: start
|
|
92
|
+
|
|
93
|
+
# Utility service for running composer commands
|
|
94
|
+
# Image from: https://hub.docker.com/_/composer
|
|
95
|
+
composer:
|
|
96
|
+
image: composer:2.8
|
|
97
|
+
profiles: ["utility"]
|
|
98
|
+
user: "${UID:-1000}:${GID:-1000}"
|
|
99
|
+
environment:
|
|
100
|
+
COMPOSER_HOME: /.composer
|
|
101
|
+
volumes:
|
|
102
|
+
- ./:/app
|
|
103
|
+
- ~/.composer:/.composer
|
|
104
|
+
command: install
|
|
105
|
+
|
|
106
|
+
# Utility service which exposes wp-cli. Useful for testing pre-releases
|
|
107
|
+
# Update image version with `docker run ideasonpurpose/wordpress init`
|
|
108
|
+
# Project info: https://github.com/ideasonpurpose/docker-wordpress-dev
|
|
109
|
+
wp-cli:
|
|
110
|
+
depends_on:
|
|
111
|
+
- db
|
|
112
|
+
- wordpress
|
|
113
|
+
image: *wp_img
|
|
114
|
+
profiles: ["utility"]
|
|
115
|
+
user: www-data
|
|
116
|
+
volumes:
|
|
117
|
+
- wp_data:/var/www/html
|
|
118
|
+
- ./wp-content/themes/${npm_package_name:-ioptheme}:/var/www/html/wp-content/themes/${npm_package_name:-ioptheme}
|
|
119
|
+
- ./wp-content/plugins:/var/www/html/wp-content/plugins
|
|
120
|
+
- ./wp-content/uploads:/var/www/html/wp-content/uploads
|
|
121
|
+
environment:
|
|
122
|
+
- WP_CLI_CACHE_DIR=/tmp/wp-cli
|
|
123
|
+
- WP_CLI_DISABLE_AUTO_CHECK_UPDATE=true
|
|
124
|
+
command: wp theme activate ${npm_package_name:-ioptheme}
|
|
125
|
+
|
|
126
|
+
# Runs phpMyAdmin on port 8002
|
|
127
|
+
# Image from: https://hub.docker.com/_/phpmyadmin
|
|
128
|
+
phpmyadmin:
|
|
129
|
+
image: phpmyadmin:5.2-apache
|
|
130
|
+
profiles: ["utility"]
|
|
131
|
+
ports:
|
|
132
|
+
- "${npm_config_port:-8002}:80"
|
|
133
|
+
depends_on:
|
|
134
|
+
- db
|
|
135
|
+
environment:
|
|
136
|
+
PMA_USER: root
|
|
137
|
+
PMA_PASSWORD: ~
|
|
138
|
+
UPLOAD_LIMIT: 1G
|
|
139
|
+
command: |
|
|
140
|
+
bash -c 'echo &&
|
|
141
|
+
echo -e "🛠 \033[33mStarting phpMyAdmin at\033[0m \033[36mhttp://localhost:${npm_config_port:-8002}\033[0m" &&
|
|
142
|
+
echo &&
|
|
143
|
+
/docker-entrypoint.sh apache2-foreground'
|
|
144
|
+
|
|
145
|
+
# XDebug profile viewer at http://localhost:9001 (change port with --port=xxxx)
|
|
146
|
+
# Enable profiling by appending `?XDEBUG_PROFILE=1` to any request
|
|
147
|
+
# https://hub.docker.com/r/wodby/webgrind
|
|
148
|
+
webgrind:
|
|
149
|
+
image: wodby/webgrind:1.9
|
|
150
|
+
profiles: ["utility"]
|
|
151
|
+
user: "${UID:-1000}:${GID:-1000}"
|
|
152
|
+
ports:
|
|
153
|
+
- "${npm_config_port:-9004}:8080"
|
|
154
|
+
depends_on:
|
|
155
|
+
- wordpress
|
|
156
|
+
volumes:
|
|
157
|
+
- ./webpack/xdebug:/tmp
|
|
158
|
+
environment:
|
|
159
|
+
WEBGRIND_DEFAULT_TIMEZONE: America/New_York
|
|
160
|
+
command: |
|
|
161
|
+
bash -c 'echo &&
|
|
162
|
+
echo -e "🔍 \033[33mStarting WebGrind server at\033[0m \033[36mhttp://localhost:${npm_config_port:-9004}\033[0m" &&
|
|
163
|
+
echo -e "⏱️ Profile any request by adding \033[1;35m?XDEBUG_PROFILE=1\033[0m to the url" &&
|
|
164
|
+
echo &&
|
|
165
|
+
php -S 0.0.0.0:8080 index.php
|
|
166
|
+
'
|
|
167
|
+
|
|
168
|
+
# Dumps the current database to _db/theme-YYYY-MM-DDTHHMMSS.sql.gz
|
|
169
|
+
db-dump:
|
|
170
|
+
image: *db_img
|
|
171
|
+
profiles: ["utility"]
|
|
172
|
+
depends_on:
|
|
173
|
+
- db
|
|
174
|
+
volumes:
|
|
175
|
+
- ./_db:/usr/src
|
|
176
|
+
environment:
|
|
177
|
+
MYSQL_DATABASE: wordpress
|
|
178
|
+
OWNER_GROUP: "${UID:-1000}:${GID:-1000}"
|
|
179
|
+
|
|
180
|
+
# NOTE: The datbase dumpfile will include these CREATE/USE commands:
|
|
181
|
+
# CREATE DATABASE `wordpress`;
|
|
182
|
+
# USE `wordpress`;
|
|
183
|
+
# to drop those lines, remove "--databases" from the mysqldump command
|
|
184
|
+
command: |
|
|
185
|
+
bash -c 'for i in {1..10}
|
|
186
|
+
do echo -e "⏳ \033[33mWaiting for DB server...\033[0m" &&
|
|
187
|
+
mysql --ssl-mode=DISABLED -s -h db -e "exit" && break || sleep 3
|
|
188
|
+
done &&
|
|
189
|
+
sleep 2 &&
|
|
190
|
+
echo -e "✔️ \033[32mConnected to DB\033[0m" &&
|
|
191
|
+
export DUMPFILE="/usr/src/'${npm_package_name:-dumpfile}'-$$(date +%FT%H%M%S).sql" &&
|
|
192
|
+
echo $${DUMPFILE} &&
|
|
193
|
+
mysqldump --ssl-mode=DISABLED -hdb --databases $${MYSQL_DATABASE} > "$${DUMPFILE}" &&
|
|
194
|
+
gzip "$${DUMPFILE}" &&
|
|
195
|
+
chown -R $${OWNER_GROUP} /usr/src &&
|
|
196
|
+
echo "Successfully dumped database to \"$${DUMPFILE}.gz\""'
|
|
197
|
+
|
|
198
|
+
# Reloads the database from the first found *.sql dumpfile in _db
|
|
199
|
+
db-reload:
|
|
200
|
+
image: *db_img
|
|
201
|
+
profiles: ["utility"]
|
|
202
|
+
depends_on:
|
|
203
|
+
- db
|
|
204
|
+
volumes:
|
|
205
|
+
- ./_db:/usr/src/dumpfiles
|
|
206
|
+
environment:
|
|
207
|
+
MYSQL_DATABASE: wordpress
|
|
208
|
+
command: |
|
|
209
|
+
bash -c 'for i in {1..10}
|
|
210
|
+
do echo -e "⏳ \033[33mWaiting for DB server...\033[0m" &&
|
|
211
|
+
mysql --ssl-mode=DISABLED -s -h db -e "exit" && break || sleep 3
|
|
212
|
+
done &&
|
|
213
|
+
sleep 2 &&
|
|
214
|
+
echo -e "✔️ \033[32mConnected to DB\033[0m" &&
|
|
215
|
+
mysqladmin --ssl-mode=DISABLED -hdb -v -f drop $${MYSQL_DATABASE} &&
|
|
216
|
+
mysqladmin --ssl-mode=DISABLED -hdb -v -f create $${MYSQL_DATABASE} &&
|
|
217
|
+
echo Database \"$${MYSQL_DATABASE}\" created &&
|
|
218
|
+
echo Reloading database from dumpfile &&
|
|
219
|
+
mysql --ssl-mode=DISABLED -hdb $${MYSQL_DATABASE} < $$(ls /usr/src/dumpfiles/*.sql | tail -n1)'
|
|
220
|
+
|
|
221
|
+
# Activates the theme directly in the database
|
|
222
|
+
theme-activate:
|
|
223
|
+
image: *db_img
|
|
224
|
+
profiles: ["utility"]
|
|
225
|
+
depends_on:
|
|
226
|
+
- db
|
|
227
|
+
volumes:
|
|
228
|
+
- ./_db:/usr/src/dumpfiles
|
|
229
|
+
environment:
|
|
230
|
+
MYSQL_DATABASE: wordpress
|
|
231
|
+
command: |
|
|
232
|
+
bash -c 'for i in {1..10}
|
|
233
|
+
do echo -e "⏳ \033[33mWaiting for DB server...\033[0m" &&
|
|
234
|
+
mysql --ssl-mode=DISABLED -s -h db -e "exit" && break || sleep 3
|
|
235
|
+
done &&
|
|
236
|
+
sleep 2 &&
|
|
237
|
+
echo -e "✔️ \033[32mConnected to DB\033[0m" &&
|
|
238
|
+
if [[ $$(mysql --ssl-mode=DISABLED -s -h db $${MYSQL_DATABASE} -e "SHOW TABLES LIKE \"wp_options\"") ]]
|
|
239
|
+
then
|
|
240
|
+
echo -e "🎨 \033[36mActivating theme \033[0m\033[1m${npm_package_name:-ioptheme}\033[0m"
|
|
241
|
+
mysql --ssl-mode=DISABLED -h db $${MYSQL_DATABASE} \
|
|
242
|
+
-e "UPDATE wp_options \
|
|
243
|
+
SET option_value = \"'${npm_package_name:-ioptheme}'\" \
|
|
244
|
+
WHERE option_name in (\"template\",\"stylesheet\")"
|
|
245
|
+
else
|
|
246
|
+
echo -e "Unable to activate theme: \033[31m'\'wp_options\'' table does not exist.\033[0m"
|
|
247
|
+
echo "To recreate an existing site, copy the site'\''s DB dumpfile into _db"
|
|
248
|
+
echo If this project is starting from an empty database, you can ignore this message.
|
|
249
|
+
fi'
|
|
250
|
+
|
|
251
|
+
# Repairs permissions for known project files and directories
|
|
252
|
+
repair-permissions:
|
|
253
|
+
image: *wp_img
|
|
254
|
+
profiles: ["utility"]
|
|
255
|
+
volumes:
|
|
256
|
+
- .:/usr/src/site
|
|
257
|
+
environment:
|
|
258
|
+
OWNER_GROUP: "${UID:-1000}:${GID:-1000}"
|
|
259
|
+
entrypoint: /usr/local/bin/permissions.sh
|
|
260
|
+
|
|
261
|
+
# Locally mirror remote sites by pulling the database, plugins and uploads
|
|
262
|
+
# Remote connections are configured in the project's .env file
|
|
263
|
+
pull:
|
|
264
|
+
image: *wp_img
|
|
265
|
+
profiles: ["utility"]
|
|
266
|
+
volumes:
|
|
267
|
+
- .:/usr/src/site
|
|
268
|
+
entrypoint: |
|
|
269
|
+
/usr/local/bin/pull.sh
|
|
270
|
+
environment:
|
|
271
|
+
OWNER_GROUP: "${UID:-1000}:${GID:-1000}"
|
|
272
|
+
SSH_KEY_PATH:
|
|
273
|
+
SSH_LOGIN:
|
|
274
|
+
SSH_USER:
|
|
275
|
+
SSH_PORT:
|
|
276
|
+
SSH_WP_CONTENT_DIR:
|
|
277
|
+
secrets:
|
|
278
|
+
- SSH_KEY
|
|
279
|
+
|
|
280
|
+
# Run the init script from ideasonpurpose/wordpress:latest (intentionally "latest")
|
|
281
|
+
# to refresh tooling and bring the project inline with our boilerplate
|
|
282
|
+
# Project info: https://github.com/ideasonpurpose/docker-wordpress-dev
|
|
283
|
+
refresh:
|
|
284
|
+
# image: ideasonpurpose/wordpress:dev
|
|
285
|
+
image: ideasonpurpose/wordpress:latest
|
|
286
|
+
profiles: ["utility"]
|
|
287
|
+
volumes:
|
|
288
|
+
- .:/usr/src/site
|
|
289
|
+
command: init
|
|
290
|
+
|
|
291
|
+
secrets:
|
|
292
|
+
SSH_KEY:
|
|
293
|
+
file: ${SSH_KEY_PATH:-~/.ssh/your_ssh_private_key}
|
|
294
|
+
|
|
295
|
+
volumes:
|
|
296
|
+
db_data:
|
|
297
|
+
name: ${npm_package_name:-ioptheme}_db
|
|
298
|
+
wp_data:
|
|
299
|
+
name: ${npm_package_name:-ioptheme}_wp
|
package/lib/devserver-proxy.js
CHANGED
|
@@ -10,6 +10,8 @@ import { findLocalPort } from "./find-local-docker-port.js";
|
|
|
10
10
|
/**
|
|
11
11
|
* If config.proxy is explicitly not false, return a {proxy} object
|
|
12
12
|
* otherwise return an empty object.
|
|
13
|
+
*
|
|
14
|
+
* @returns {Promise<{ proxy: Object[] }>}
|
|
13
15
|
*/
|
|
14
16
|
export async function devserverProxy(config) {
|
|
15
17
|
let target = config.proxy;
|
|
@@ -44,17 +46,17 @@ export async function devserverProxy(config) {
|
|
|
44
46
|
if (localPort && localPort.hostname && localPort.port) {
|
|
45
47
|
target = new URL(`http://${localPort.hostname}:${localPort.port}`);
|
|
46
48
|
console.log(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
"PORT FROM DEVSERVER-PROXY:",
|
|
50
|
+
chalk.cyan(config.proxy),
|
|
51
|
+
chalk.bold(localPort.port),
|
|
52
|
+
target,
|
|
51
53
|
);
|
|
52
54
|
}
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
57
|
|
|
56
58
|
if (!target) {
|
|
57
|
-
return {};
|
|
59
|
+
return { proxy: [] };
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
const proxy = [
|
|
@@ -114,7 +116,9 @@ export async function devserverProxy(config) {
|
|
|
114
116
|
|
|
115
117
|
originalBody = Buffer.concat(originalBody);
|
|
116
118
|
let newBody;
|
|
117
|
-
|
|
119
|
+
// TODO: Is there ever a case where content-type is missing?
|
|
120
|
+
const type = proxyRes.headers["content-type"].split(";")[0];
|
|
121
|
+
// const type = (proxyRes.headers["content-type"] || "").split(";")[0];
|
|
118
122
|
const wpRegexp = new RegExp(
|
|
119
123
|
"^/wp-(?:admin|includes|content/plugins).*(?:css|js|map)$",
|
|
120
124
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ideasonpurpose/build-tools-wordpress",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.3",
|
|
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": {
|
|
@@ -33,66 +33,66 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@ideasonpurpose/prettier-config": "^1.0.0",
|
|
35
35
|
"@ideasonpurpose/stylelint-config": "^1.1.0",
|
|
36
|
-
"@rollup/plugin-commonjs": "^28.0.
|
|
36
|
+
"@rollup/plugin-commonjs": "^28.0.3",
|
|
37
37
|
"@rollup/plugin-json": "^6.1.0",
|
|
38
|
-
"@rollup/plugin-node-resolve": "^
|
|
38
|
+
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
39
39
|
"@svgr/webpack": "^8.1.0",
|
|
40
|
-
"@wordpress/dependency-extraction-webpack-plugin": "^6.
|
|
40
|
+
"@wordpress/dependency-extraction-webpack-plugin": "^6.20.0",
|
|
41
41
|
"ansi-html": "^0.0.9",
|
|
42
42
|
"archiver": "^7.0.1",
|
|
43
43
|
"auto-changelog": "^2.5.0",
|
|
44
|
-
"autoprefixer": "^10.4.
|
|
45
|
-
"babel-loader": "^
|
|
44
|
+
"autoprefixer": "^10.4.21",
|
|
45
|
+
"babel-loader": "^10.0.0",
|
|
46
46
|
"body-parser": "^1.20.3",
|
|
47
|
-
"caniuse-lite": "^1.0.
|
|
48
|
-
"chalk": "^5.
|
|
47
|
+
"caniuse-lite": "^1.0.30001706",
|
|
48
|
+
"chalk": "^5.4.1",
|
|
49
49
|
"chalk-cli": "^5.0.1",
|
|
50
50
|
"classnames": "^2.5.1",
|
|
51
51
|
"cli-truncate": "^4.0.0",
|
|
52
|
-
"copy-webpack-plugin": "^
|
|
52
|
+
"copy-webpack-plugin": "^13.0.0",
|
|
53
53
|
"cosmiconfig": "^9.0.0",
|
|
54
54
|
"cross-env": "^7.0.3",
|
|
55
55
|
"css-loader": "^7.1.2",
|
|
56
56
|
"cssnano": "^7.0.6",
|
|
57
|
-
"dotenv": "^16.4.
|
|
58
|
-
"esbuild-loader": "^4.
|
|
59
|
-
"eslint": "^9.
|
|
57
|
+
"dotenv": "^16.4.7",
|
|
58
|
+
"esbuild-loader": "^4.3.0",
|
|
59
|
+
"eslint": "^9.22.0",
|
|
60
60
|
"filesize": "^10.1.6",
|
|
61
|
-
"fs-extra": "^11.
|
|
62
|
-
"globby": "^14.0
|
|
61
|
+
"fs-extra": "^11.3.0",
|
|
62
|
+
"globby": "^14.1.0",
|
|
63
63
|
"http-proxy": "^1.18.1",
|
|
64
64
|
"humanize-duration": "^3.32.1",
|
|
65
|
-
"image-minimizer-webpack-plugin": "^4.1.
|
|
65
|
+
"image-minimizer-webpack-plugin": "^4.1.3",
|
|
66
66
|
"is-text-path": "^3.0.0",
|
|
67
67
|
"lodash": "^4.17.21",
|
|
68
|
-
"mini-css-extract-plugin": "^2.9.
|
|
69
|
-
"ora": "^8.
|
|
70
|
-
"postcss": "^8.
|
|
68
|
+
"mini-css-extract-plugin": "^2.9.2",
|
|
69
|
+
"ora": "^8.2.0",
|
|
70
|
+
"postcss": "^8.5.3",
|
|
71
71
|
"postcss-loader": "^8.1.1",
|
|
72
72
|
"postcss-scss": "^4.0.9",
|
|
73
73
|
"pretty-hrtime": "^1.0.3",
|
|
74
74
|
"read-package-up": "^11.0.0",
|
|
75
75
|
"replacestream": "^4.0.3",
|
|
76
|
-
"sass": "^1.
|
|
77
|
-
"sass-embedded": "^1.
|
|
78
|
-
"sass-loader": "^16.0.
|
|
79
|
-
"semver": "^7.
|
|
76
|
+
"sass": "^1.86.0",
|
|
77
|
+
"sass-embedded": "^1.86.0",
|
|
78
|
+
"sass-loader": "^16.0.5",
|
|
79
|
+
"semver": "^7.7.1",
|
|
80
80
|
"sharp": "^0.33.5",
|
|
81
|
-
"sort-package-json": "^
|
|
81
|
+
"sort-package-json": "^3.0.0",
|
|
82
82
|
"string-length": "^6.0.0",
|
|
83
83
|
"style-loader": "^4.0.0",
|
|
84
84
|
"svgo": "^3.3.2",
|
|
85
85
|
"svgo-loader": "^4.0.0",
|
|
86
86
|
"version-everything": "^0.11.4",
|
|
87
|
-
"webpack": "^5.
|
|
87
|
+
"webpack": "^5.98.0",
|
|
88
88
|
"webpack-bundle-analyzer": "^4.10.2",
|
|
89
|
-
"webpack-cli": "^
|
|
89
|
+
"webpack-cli": "^6.0.1",
|
|
90
90
|
"webpack-dev-middleware": "^7.4.2",
|
|
91
|
-
"webpack-dev-server": "^5.
|
|
91
|
+
"webpack-dev-server": "^5.2.0"
|
|
92
92
|
},
|
|
93
93
|
"devDependencies": {
|
|
94
|
-
"@vitest/coverage-v8": "^
|
|
95
|
-
"vitest": "^
|
|
94
|
+
"@vitest/coverage-v8": "^3.0.9",
|
|
95
|
+
"vitest": "^3.0.9"
|
|
96
96
|
},
|
|
97
97
|
"version-everything": {
|
|
98
98
|
"files": [
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
//@ts-check
|
|
2
|
+
|
|
1
3
|
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
|
|
2
4
|
|
|
3
5
|
import fs from "fs";
|
|
4
6
|
import dns from "dns";
|
|
5
7
|
|
|
8
|
+
import { EventEmitter } from "events";
|
|
9
|
+
|
|
6
10
|
import { devserverProxy } from "../lib/devserver-proxy.js";
|
|
7
11
|
import { findLocalPort } from "../lib/find-local-docker-port.js";
|
|
8
12
|
|
|
@@ -59,7 +63,6 @@ afterEach(() => {
|
|
|
59
63
|
// expect(actual).toBe(expected);
|
|
60
64
|
// });
|
|
61
65
|
|
|
62
|
-
|
|
63
66
|
// test("Send legacy token where there's no wordpress service", async () => {
|
|
64
67
|
// jest.spyOn(dns, "promises", "get").mockImplementation(() => {
|
|
65
68
|
// // console.log("ONLY ONCE");
|
|
@@ -107,75 +110,153 @@ afterEach(() => {
|
|
|
107
110
|
|
|
108
111
|
test("Test proxy settings", async () => {
|
|
109
112
|
let proxy = true;
|
|
110
|
-
const actual = await devserverProxy({ proxy });
|
|
111
|
-
|
|
112
|
-
expect(actual).
|
|
113
|
-
expect(actual.proxy["**"].target).toMatch("stella");
|
|
113
|
+
const actual = (await devserverProxy({ proxy })).proxy[0];
|
|
114
|
+
expect(actual).toHaveProperty("target");
|
|
115
|
+
expect(actual.context).toContain("**");
|
|
114
116
|
});
|
|
115
117
|
|
|
116
118
|
test("proxy is bare IP address", async () => {
|
|
117
119
|
let proxy = "4.3.2.1";
|
|
118
|
-
const actual = await devserverProxy({ proxy });
|
|
119
|
-
expect(actual).toHaveProperty("
|
|
120
|
+
const actual = (await devserverProxy({ proxy })).proxy[0];
|
|
121
|
+
expect(actual).toHaveProperty("target", "http://4.3.2.1");
|
|
120
122
|
});
|
|
121
123
|
|
|
122
124
|
test("proxy is a url", async () => {
|
|
123
|
-
let proxy = "https://example.com
|
|
124
|
-
const actual = await devserverProxy({ proxy });
|
|
125
|
-
expect(actual).toHaveProperty("
|
|
125
|
+
let proxy = "https://example.com";
|
|
126
|
+
const actual = (await devserverProxy({ proxy })).proxy[0];
|
|
127
|
+
expect(actual).toHaveProperty("target", proxy);
|
|
126
128
|
});
|
|
127
129
|
|
|
128
130
|
test("proxy is a plain string", async () => {
|
|
129
131
|
let proxy = "sandwich";
|
|
130
|
-
const actual = await devserverProxy({ proxy });
|
|
131
|
-
expect(actual).toHaveProperty("
|
|
132
|
+
const actual = (await devserverProxy({ proxy })).proxy[0];
|
|
133
|
+
expect(actual).toHaveProperty("target", expectedTarget);
|
|
132
134
|
expect(findLocalPort).toHaveBeenCalledWith(proxy);
|
|
133
135
|
});
|
|
134
136
|
|
|
135
137
|
test("Proxy boolean true", async () => {
|
|
136
138
|
vi.mocked(findLocalPort).mockReturnValue(localPort);
|
|
137
139
|
const proxy = true;
|
|
138
|
-
const actual = await devserverProxy({ proxy });
|
|
139
|
-
expect(actual).toHaveProperty("
|
|
140
|
+
const actual = (await devserverProxy({ proxy })).proxy[0];
|
|
141
|
+
expect(actual).toHaveProperty("target", expectedTarget);
|
|
140
142
|
});
|
|
141
143
|
|
|
142
144
|
test("Proxy boolean false", async () => {
|
|
143
145
|
const proxy = false;
|
|
144
|
-
expect(await devserverProxy({ proxy })).toStrictEqual({});
|
|
146
|
+
expect(await devserverProxy({ proxy })).toStrictEqual({ proxy: [] });
|
|
145
147
|
});
|
|
146
148
|
|
|
147
149
|
test("test the returned proxy onError handler", async () => {
|
|
148
|
-
let proxy = "wordpress";
|
|
149
150
|
const logSpy = vi.spyOn(console, "log");
|
|
150
151
|
const actual = await devserverProxy({ proxy: true });
|
|
151
152
|
|
|
152
|
-
|
|
153
|
-
expect(actual).toHaveProperty("proxy.**");
|
|
153
|
+
const err = { code: "ECONNRESET" };
|
|
154
154
|
|
|
155
|
-
|
|
156
|
-
let err = new Error("boom");
|
|
157
|
-
err.code = "ECONNRESET";
|
|
158
|
-
route.onError(err);
|
|
159
|
-
|
|
160
|
-
expect(route).toHaveProperty("onError");
|
|
155
|
+
actual.proxy[0].onError(err, "req", "res");
|
|
161
156
|
expect(logSpy).toHaveBeenLastCalledWith(
|
|
162
157
|
expect.stringContaining("ECONNRESET"),
|
|
163
158
|
);
|
|
164
159
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
160
|
+
err.code = "Unknown Error Code";
|
|
161
|
+
err.stack = "STACK";
|
|
162
|
+
|
|
168
163
|
const req = { url: "url" };
|
|
164
|
+
const res = { writeHead: vi.fn(), end: vi.fn() };
|
|
169
165
|
|
|
170
|
-
err
|
|
171
|
-
|
|
172
|
-
|
|
166
|
+
actual.proxy[0].onError(err, req, res);
|
|
167
|
+
|
|
168
|
+
expect(logSpy).toHaveBeenLastCalledWith(
|
|
169
|
+
expect.stringContaining("Devserver Proxy Error"),
|
|
170
|
+
req.url,
|
|
171
|
+
expect.any(Object),
|
|
172
|
+
err.stack,
|
|
173
|
+
);
|
|
173
174
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
175
|
+
expect(res.writeHead).toHaveBeenCalledWith(500, expect.any(Object));
|
|
176
|
+
expect(res.end).toHaveBeenCalledWith(
|
|
177
|
+
expect.stringContaining("Webpack DevServer Proxy Error: "),
|
|
178
|
+
);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
test("onProxyRes Handler", async () => {
|
|
182
|
+
const config = { proxy: "http://localhost:3000" };
|
|
183
|
+
const result = await devserverProxy(config);
|
|
184
|
+
const onProxyRes = result.proxy[0].onProxyRes;
|
|
185
|
+
|
|
186
|
+
const mockProxyRes = new EventEmitter();
|
|
187
|
+
mockProxyRes.statusCode = 200;
|
|
188
|
+
mockProxyRes.statusMessage = "OK";
|
|
189
|
+
mockProxyRes.headers = {
|
|
190
|
+
"content-type": "text/css",
|
|
191
|
+
};
|
|
192
|
+
const mockReq = {
|
|
193
|
+
headers: { host: "example.com" },
|
|
194
|
+
path: "/style.css",
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
const mockRes = {
|
|
198
|
+
statusCode: 0,
|
|
199
|
+
setHeader: vi.fn(),
|
|
200
|
+
end: vi.fn(),
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
onProxyRes(mockProxyRes, mockReq, mockRes);
|
|
204
|
+
|
|
205
|
+
const bodySrc = "body { color: red; }";
|
|
206
|
+
let originalBody = Buffer.from(bodySrc);
|
|
207
|
+
mockProxyRes.emit("data", originalBody);
|
|
208
|
+
mockProxyRes.emit("end");
|
|
209
|
+
|
|
210
|
+
// Assert
|
|
211
|
+
expect(mockRes.statusCode).toBe(200);
|
|
212
|
+
expect(mockRes.end).toHaveBeenCalledWith(bodySrc);
|
|
213
|
+
expect(mockRes.setHeader).toHaveBeenCalledWith(
|
|
214
|
+
"content-type",
|
|
215
|
+
expect.anything(),
|
|
216
|
+
);
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
test("onProxyRes Handler passthrough", async () => {
|
|
221
|
+
const config = { proxy: "http://localhost:3000" };
|
|
222
|
+
const result = await devserverProxy(config);
|
|
223
|
+
const onProxyRes = result.proxy[0].onProxyRes;
|
|
224
|
+
|
|
225
|
+
const mockProxyRes = new EventEmitter();
|
|
226
|
+
mockProxyRes.statusCode = 200;
|
|
227
|
+
mockProxyRes.statusMessage = "OK";
|
|
228
|
+
mockProxyRes.headers = {
|
|
229
|
+
"content-type": "nope/nope",
|
|
230
|
+
};
|
|
231
|
+
const mockReq = {
|
|
232
|
+
headers: { host: "example.com" },
|
|
233
|
+
path: "/style.css",
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
const mockRes = {
|
|
237
|
+
statusCode: 0,
|
|
238
|
+
setHeader: vi.fn(),
|
|
239
|
+
end: vi.fn(),
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
onProxyRes(mockProxyRes, mockReq, mockRes);
|
|
243
|
+
|
|
244
|
+
const bodySrc = "body { color: red; }";
|
|
245
|
+
let originalBody = Buffer.from(bodySrc);
|
|
246
|
+
mockProxyRes.emit("data", originalBody);
|
|
247
|
+
mockProxyRes.emit("end");
|
|
248
|
+
|
|
249
|
+
// Assert
|
|
250
|
+
expect(mockRes.statusCode).toBe(200);
|
|
251
|
+
expect(mockRes.end).toHaveBeenCalledWith(Buffer.from(bodySrc));
|
|
252
|
+
expect(mockRes.setHeader).toHaveBeenCalledWith(
|
|
253
|
+
"content-type",
|
|
254
|
+
expect.anything(),
|
|
255
|
+
);
|
|
177
256
|
});
|
|
178
257
|
|
|
258
|
+
|
|
259
|
+
|
|
179
260
|
// test("test proxy's onProxyRes handler", async () => {
|
|
180
261
|
// let proxy = "https://example.com";
|
|
181
262
|
// const logSpy = jest.spyOn(console, "log");
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Future node versions should import package.json directly:
|
|
3
|
-
* import packageJson from "./package.json" with { type: "json" };
|
|
4
|
-
*
|
|
5
|
-
* In the current node.js LTS v20, importing JSON throws the following warnings:
|
|
6
|
-
* (node:14509) ExperimentalWarning: Importing JSON modules is an experimental feature and might change at any time
|
|
7
|
-
* (Use `node --trace-warnings ...` to show where the warning was created)
|
|
8
|
-
*
|
|
9
|
-
* NOTE: This file does not work if the build runs from Docker. Inside a Docker volume, the
|
|
10
|
-
* theme name pulls instead from the docker image's package.json file, which will probably
|
|
11
|
-
* create a theme named 'iop-build-tools'.
|
|
12
|
-
*/
|
|
13
|
-
import { readFileSync } from "fs";
|
|
14
|
-
const packageJson = JSON.parse(readFileSync("./package.json"));
|
|
15
|
-
// import packageJson from "./package.json" with { type: "json" };
|
|
16
|
-
|
|
17
|
-
const { name: themeName } = packageJson;
|
|
18
|
-
|
|
19
|
-
export default {
|
|
20
|
-
src: `./wp-content/themes/${themeName}/src`,
|
|
21
|
-
dist: `./wp-content/themes/${themeName}/dist`,
|
|
22
|
-
entry: ["./js/main.js", "./js/admin.js", "./js/editor.js"],
|
|
23
|
-
publicPath: `/wp-content/themes/${themeName}/dist/`,
|
|
24
|
-
|
|
25
|
-
sass: "sass-embedded",
|
|
26
|
-
esTarget: "es2020",
|
|
27
|
-
|
|
28
|
-
devtool: "source-map",
|
|
29
|
-
};
|