sdc-build-wp 5.5.2 → 5.6.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/lib/components/blocks.js +34 -10
- package/lib/page-script.js +16 -17
- package/lib/project.js +4 -0
- package/lib/tui.js +320 -242
- package/package.json +4 -3
- package/webpack.config.js +8 -1
package/lib/components/blocks.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { fileURLToPath } from 'url';
|
|
2
1
|
import BaseComponent from './base.js';
|
|
3
|
-
import { stat, readFile } from 'fs/promises';
|
|
4
|
-
import {
|
|
2
|
+
import { access, stat, readFile } from 'fs/promises';
|
|
3
|
+
import { execFile } from 'child_process';
|
|
5
4
|
import { promisify } from 'util';
|
|
6
5
|
import { createHash } from 'crypto';
|
|
7
6
|
|
|
@@ -10,6 +9,31 @@ export default class BlocksComponent extends BaseComponent {
|
|
|
10
9
|
constructor() {
|
|
11
10
|
super();
|
|
12
11
|
this.description = `Process the theme's WordPress blocks`;
|
|
12
|
+
this._didLogWpScriptsFallback = false;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async getWpScriptsRunner() {
|
|
16
|
+
const localWpScripts = `${this.project.path}/node_modules/@wordpress/scripts/bin/wp-scripts.js`;
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
await access(localWpScripts);
|
|
20
|
+
return {
|
|
21
|
+
command: process.execPath,
|
|
22
|
+
baseArgs: [localWpScripts]
|
|
23
|
+
};
|
|
24
|
+
} catch {
|
|
25
|
+
if (!this._didLogWpScriptsFallback) {
|
|
26
|
+
this.log('info', 'Using temporary @wordpress/scripts via npx for block builds');
|
|
27
|
+
this._didLogWpScriptsFallback = true;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const npxCommand = process.platform === 'win32' ? 'npx.cmd' : 'npx';
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
command: npxCommand,
|
|
34
|
+
baseArgs: ['--yes', '--package', '@wordpress/scripts@31', 'wp-scripts']
|
|
35
|
+
};
|
|
36
|
+
}
|
|
13
37
|
}
|
|
14
38
|
|
|
15
39
|
async init() {
|
|
@@ -132,17 +156,17 @@ export default class BlocksComponent extends BaseComponent {
|
|
|
132
156
|
this.clearHashCache([workingBlockJson, ...dependencies]);
|
|
133
157
|
|
|
134
158
|
try {
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
159
|
+
const runner = await this.getWpScriptsRunner();
|
|
160
|
+
const args = [
|
|
161
|
+
...runner.baseArgs,
|
|
162
|
+
'build',
|
|
138
163
|
`--source-path=.${entry.replace(this.project.path, '')}/src`,
|
|
139
164
|
`--output-path=.${entry.replace(this.project.path, '')}/build`,
|
|
140
|
-
|
|
141
|
-
`--config=${this.path.resolve(this.path.dirname(fileURLToPath(import.meta.url)), '../../webpack.config.js')}`,
|
|
165
|
+
'--webpack-copy-php'
|
|
142
166
|
];
|
|
143
|
-
const
|
|
167
|
+
const execFilePromise = promisify(execFile);
|
|
144
168
|
const timeoutMS = 40000;
|
|
145
|
-
const buildPromise =
|
|
169
|
+
const buildPromise = execFilePromise(runner.command, args, {
|
|
146
170
|
maxBuffer: 1024 * 1024 * 10,
|
|
147
171
|
cwd: this.project.path
|
|
148
172
|
});
|
package/lib/page-script.js
CHANGED
|
@@ -5,23 +5,22 @@ let socket = window.___browserSync___?.socket;
|
|
|
5
5
|
let checkedForPort = false;
|
|
6
6
|
|
|
7
7
|
function redirectAdminFromPort() {
|
|
8
|
-
if (!checkedForPort && window.location.port) {
|
|
9
|
-
const url = new URL(window.location.href);
|
|
10
|
-
const urlParams = new URLSearchParams(window.location.search);
|
|
11
|
-
if (urlParams.has('keepPort')) {
|
|
12
|
-
checkedForPort = true;
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
url.port = '';
|
|
16
|
-
socket.emit('sdc:redirectAdminFromPort', {
|
|
17
|
-
timestamp: Date.now(),
|
|
18
|
-
port: window.location.port,
|
|
19
|
-
from: window.location.href,
|
|
20
|
-
to: url.toString()
|
|
21
|
-
});
|
|
22
|
-
window.location.replace(url.toString());
|
|
23
|
-
}
|
|
24
8
|
checkedForPort = true;
|
|
9
|
+
if (!window.location.port) { return; }
|
|
10
|
+
const url = new URL(window.location.href);
|
|
11
|
+
const isAdmin = /^\/wp-admin(?:\/|$)/.test(url.pathname);
|
|
12
|
+
const urlParams = new URLSearchParams(url.search);
|
|
13
|
+
if (!isAdmin || urlParams.has('keepPort')) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
url.port = '';
|
|
17
|
+
socket.emit('sdc:redirectAdminFromPort', {
|
|
18
|
+
timestamp: Date.now(),
|
|
19
|
+
port: window.location.port,
|
|
20
|
+
from: window.location.href,
|
|
21
|
+
to: url.toString()
|
|
22
|
+
});
|
|
23
|
+
window.location.replace(url.toString());
|
|
25
24
|
}
|
|
26
25
|
|
|
27
26
|
function getScriptsOnPage() {
|
|
@@ -36,7 +35,7 @@ function getScriptsOnPage() {
|
|
|
36
35
|
const scriptsOnPageInterval = setInterval(() => {
|
|
37
36
|
socket = window.___browserSync___?.socket;
|
|
38
37
|
if (socket) {
|
|
39
|
-
redirectAdminFromPort();
|
|
38
|
+
if (!checkedForPort) { redirectAdminFromPort(); }
|
|
40
39
|
getScriptsOnPage();
|
|
41
40
|
clearInterval(scriptsOnPageInterval);
|
|
42
41
|
}
|
package/lib/project.js
CHANGED
|
@@ -252,6 +252,10 @@ export function keypressListen() {
|
|
|
252
252
|
if (isPrompting) { return; }
|
|
253
253
|
switch (key) {
|
|
254
254
|
case '\r': // [Enter]/[Return]
|
|
255
|
+
if (tui.isInitialized && !tui.isMouseEnabled) {
|
|
256
|
+
tui.enableMouseCapture();
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
255
259
|
log(null, '');
|
|
256
260
|
break;
|
|
257
261
|
case '\u0003': // [Ctrl]+C
|
package/lib/tui.js
CHANGED
|
@@ -1,12 +1,95 @@
|
|
|
1
|
-
import
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Box, Text, render as renderInk, useInput, useStdout } from 'ink';
|
|
2
3
|
import { styleText } from 'node:util';
|
|
3
4
|
import log from './logging.js';
|
|
4
5
|
|
|
6
|
+
const sgrMouseRegex = /\x1b\[<(\d+);(\d+);(\d+)([mM])/g;
|
|
7
|
+
|
|
8
|
+
function TUIRoot({ tui }) {
|
|
9
|
+
const { stdout } = useStdout();
|
|
10
|
+
const terminalRows = stdout?.rows || 24;
|
|
11
|
+
const headerLines = tui.getHeaderLines();
|
|
12
|
+
const promptLines = tui.getPromptRenderLines();
|
|
13
|
+
const availableLogRows = Math.max(3, terminalRows - headerLines.length - promptLines.length - 6);
|
|
14
|
+
const visibleLogs = tui.getVisibleLogLines(availableLogRows);
|
|
15
|
+
|
|
16
|
+
useInput((input, key) => {
|
|
17
|
+
if (!tui.isInitialized) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (tui.isMouseEscapeSequence(input)) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (tui.hasPrompt()) {
|
|
26
|
+
tui.handlePromptInput(input, key);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (key.upArrow) {
|
|
31
|
+
tui.scrollLogs(1);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (key.downArrow) {
|
|
36
|
+
tui.scrollLogs(-1);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (key.pageUp) {
|
|
41
|
+
tui.scrollLogs(availableLogRows);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (key.pageDown) {
|
|
46
|
+
tui.scrollLogs(-availableLogRows);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
return React.createElement(
|
|
51
|
+
Box,
|
|
52
|
+
{ flexDirection: 'column' },
|
|
53
|
+
React.createElement(
|
|
54
|
+
Box,
|
|
55
|
+
{
|
|
56
|
+
borderStyle: 'round',
|
|
57
|
+
borderColor: 'blue',
|
|
58
|
+
paddingX: 1,
|
|
59
|
+
flexDirection: 'column'
|
|
60
|
+
},
|
|
61
|
+
headerLines.map((line, index) => React.createElement(Text, { key: `header-${index}` }, line))
|
|
62
|
+
),
|
|
63
|
+
React.createElement(
|
|
64
|
+
Box,
|
|
65
|
+
{
|
|
66
|
+
borderStyle: 'single',
|
|
67
|
+
borderColor: 'blue',
|
|
68
|
+
paddingX: 1,
|
|
69
|
+
flexDirection: 'column',
|
|
70
|
+
height: availableLogRows + 2
|
|
71
|
+
},
|
|
72
|
+
visibleLogs.map((line, index) => React.createElement(Text, { key: `log-${index}` }, line))
|
|
73
|
+
),
|
|
74
|
+
tui.hasPrompt()
|
|
75
|
+
? React.createElement(
|
|
76
|
+
Box,
|
|
77
|
+
{
|
|
78
|
+
borderStyle: 'round',
|
|
79
|
+
borderColor: 'cyan',
|
|
80
|
+
paddingX: 1,
|
|
81
|
+
marginTop: 1,
|
|
82
|
+
flexDirection: 'column'
|
|
83
|
+
},
|
|
84
|
+
tui.getPromptRenderLines().map((line, index) => React.createElement(Text, { key: `prompt-${index}` }, line))
|
|
85
|
+
)
|
|
86
|
+
: null
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
5
90
|
class TUI {
|
|
6
91
|
constructor() {
|
|
7
|
-
this.
|
|
8
|
-
this.headerBox = null;
|
|
9
|
-
this.logBox = null;
|
|
92
|
+
this.app = null;
|
|
10
93
|
this.isInitialized = false;
|
|
11
94
|
this.urls = {
|
|
12
95
|
local: '',
|
|
@@ -18,141 +101,95 @@ class TUI {
|
|
|
18
101
|
this.isPaused = false;
|
|
19
102
|
this.isMouseEnabled = true;
|
|
20
103
|
this._logHistory = [];
|
|
104
|
+
this._logScrollOffset = 0;
|
|
105
|
+
this._activePrompt = null;
|
|
106
|
+
this._mouseDataHandler = null;
|
|
21
107
|
}
|
|
22
108
|
|
|
23
109
|
init() {
|
|
24
110
|
if (this.isInitialized) {
|
|
25
|
-
// If already initialized, redraw the header to reflect current state
|
|
26
|
-
this.updateHeader();
|
|
27
111
|
this.render();
|
|
28
112
|
return;
|
|
29
113
|
}
|
|
30
114
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
smartCSR: true,
|
|
38
|
-
fullUnicode: true,
|
|
39
|
-
title: 'SDC Build WP',
|
|
40
|
-
input: process.stdin,
|
|
41
|
-
output: process.stdout
|
|
115
|
+
this.isInitialized = true;
|
|
116
|
+
this.app = renderInk(React.createElement(TUIRoot, { tui: this }), {
|
|
117
|
+
exitOnCtrlC: false,
|
|
118
|
+
stdin: process.stdin,
|
|
119
|
+
stdout: process.stdout,
|
|
120
|
+
patchConsole: false
|
|
42
121
|
});
|
|
43
122
|
|
|
44
|
-
this.
|
|
45
|
-
|
|
46
|
-
left: 0,
|
|
47
|
-
width: '100%',
|
|
48
|
-
height: 5,
|
|
49
|
-
content: '',
|
|
50
|
-
tags: true,
|
|
51
|
-
style: {
|
|
52
|
-
fg: 'white',
|
|
53
|
-
bg: 'black',
|
|
54
|
-
border: {
|
|
55
|
-
fg: 'blue'
|
|
56
|
-
}
|
|
57
|
-
},
|
|
58
|
-
border: {
|
|
59
|
-
type: 'line',
|
|
60
|
-
bottom: true
|
|
61
|
-
},
|
|
62
|
-
shrink: false,
|
|
63
|
-
scrollable: false
|
|
64
|
-
});
|
|
123
|
+
this.setMouseCaptureEnabled(this.isMouseEnabled);
|
|
124
|
+
this.attachMouseHandler();
|
|
65
125
|
|
|
66
|
-
this.
|
|
67
|
-
|
|
68
|
-
left: 0,
|
|
69
|
-
width: '100%',
|
|
70
|
-
height: '100%-5',
|
|
71
|
-
tags: true,
|
|
72
|
-
scrollable: true,
|
|
73
|
-
alwaysScroll: true,
|
|
74
|
-
scrollbar: {
|
|
75
|
-
ch: ' ',
|
|
76
|
-
track: {
|
|
77
|
-
bg: 'blue'
|
|
78
|
-
},
|
|
79
|
-
style: {
|
|
80
|
-
inverse: true
|
|
81
|
-
}
|
|
82
|
-
},
|
|
83
|
-
mouse: true,
|
|
84
|
-
keys: true,
|
|
85
|
-
vi: true,
|
|
86
|
-
style: {
|
|
87
|
-
fg: 'white',
|
|
88
|
-
bg: 'black'
|
|
89
|
-
}
|
|
90
|
-
});
|
|
126
|
+
this.render();
|
|
127
|
+
}
|
|
91
128
|
|
|
92
|
-
|
|
93
|
-
|
|
129
|
+
isMouseEscapeSequence(input) {
|
|
130
|
+
if (!input || typeof input !== 'string') {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
94
133
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
});
|
|
134
|
+
sgrMouseRegex.lastIndex = 0;
|
|
135
|
+
return sgrMouseRegex.test(input);
|
|
136
|
+
}
|
|
99
137
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
138
|
+
attachMouseHandler() {
|
|
139
|
+
if (!process.stdin?.isTTY || this._mouseDataHandler) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
103
142
|
|
|
104
|
-
this.
|
|
105
|
-
if (!this.isMouseEnabled) {
|
|
106
|
-
this.enableMouseCapture();
|
|
107
|
-
this.updateHeader();
|
|
108
|
-
this.render();
|
|
143
|
+
this._mouseDataHandler = (chunk) => {
|
|
144
|
+
if (!this.isInitialized || !this.isMouseEnabled || this.hasPrompt()) {
|
|
109
145
|
return;
|
|
110
146
|
}
|
|
111
|
-
this.logBox.log('');
|
|
112
|
-
this.screen.render();
|
|
113
|
-
});
|
|
114
147
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
this.disableMouseCapture();
|
|
118
|
-
this.updateHeader();
|
|
119
|
-
this.render();
|
|
120
|
-
}
|
|
148
|
+
const data = String(chunk);
|
|
149
|
+
this.handleMouseData(data);
|
|
121
150
|
};
|
|
122
|
-
this.logBox.on('click', handleMouseDisable);
|
|
123
|
-
this.headerBox.on('click', handleMouseDisable);
|
|
124
151
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
this.screen.render();
|
|
128
|
-
});
|
|
152
|
+
process.stdin.on('data', this._mouseDataHandler);
|
|
153
|
+
}
|
|
129
154
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
this.screen.render();
|
|
133
|
-
});
|
|
155
|
+
handleMouseData(data) {
|
|
156
|
+
sgrMouseRegex.lastIndex = 0;
|
|
134
157
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
158
|
+
let match;
|
|
159
|
+
while ((match = sgrMouseRegex.exec(data)) !== null) {
|
|
160
|
+
const code = Number(match[1]);
|
|
161
|
+
const action = match[4];
|
|
139
162
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
163
|
+
if ((code & 64) === 64) {
|
|
164
|
+
const isScrollDown = (code & 1) === 1;
|
|
165
|
+
this.scrollLogs(isScrollDown ? -3 : 3);
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
144
168
|
|
|
145
|
-
|
|
146
|
-
|
|
169
|
+
const isButtonPress = action === 'M';
|
|
170
|
+
const isDragEvent = (code & 32) === 32;
|
|
147
171
|
|
|
148
|
-
|
|
172
|
+
if (isButtonPress && !isDragEvent) {
|
|
173
|
+
this.disableMouseCapture();
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
149
177
|
}
|
|
150
178
|
|
|
151
|
-
|
|
152
|
-
if (!
|
|
179
|
+
setMouseCaptureEnabled(isEnabled) {
|
|
180
|
+
if (!process.stdout?.isTTY) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (isEnabled) {
|
|
185
|
+
process.stdout.write('\x1b[?1000h\x1b[?1002h\x1b[?1006h');
|
|
153
186
|
return;
|
|
154
187
|
}
|
|
155
188
|
|
|
189
|
+
process.stdout.write('\x1b[?1000l\x1b[?1002l\x1b[?1006l');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
getHeaderLines() {
|
|
156
193
|
const lines = [];
|
|
157
194
|
|
|
158
195
|
let titleLine = ' ' + styleText(['bold', 'blue'], 'SDC Build WP');
|
|
@@ -173,7 +210,9 @@ class TUI {
|
|
|
173
210
|
urlLine += `Local: ${styleText('green', this.urls.local)}`;
|
|
174
211
|
}
|
|
175
212
|
if (this.urls.external) {
|
|
176
|
-
if (urlLine.length > 1)
|
|
213
|
+
if (urlLine.length > 1) {
|
|
214
|
+
urlLine += ' ';
|
|
215
|
+
}
|
|
177
216
|
urlLine += `External: ${styleText('green', this.urls.external)}`;
|
|
178
217
|
}
|
|
179
218
|
lines.push(urlLine);
|
|
@@ -193,32 +232,28 @@ class TUI {
|
|
|
193
232
|
lines.push(' ');
|
|
194
233
|
}
|
|
195
234
|
|
|
196
|
-
|
|
235
|
+
return lines;
|
|
197
236
|
}
|
|
198
237
|
|
|
199
238
|
setURLs(local, external) {
|
|
200
239
|
this.urls.local = local;
|
|
201
240
|
this.urls.external = external;
|
|
202
|
-
this.updateHeader();
|
|
203
241
|
this.render();
|
|
204
242
|
}
|
|
205
243
|
|
|
206
244
|
setCommands(commands) {
|
|
207
245
|
this.commands = commands;
|
|
208
|
-
this.updateHeader();
|
|
209
246
|
this.render();
|
|
210
247
|
}
|
|
211
248
|
|
|
212
249
|
setPaused(isPaused) {
|
|
213
250
|
this.isPaused = isPaused;
|
|
214
|
-
this.updateHeader();
|
|
215
251
|
this.render();
|
|
216
252
|
}
|
|
217
253
|
|
|
218
254
|
setComponents(components, watchMode = false) {
|
|
219
255
|
this.components = components;
|
|
220
256
|
this.watchMode = watchMode;
|
|
221
|
-
this.updateHeader();
|
|
222
257
|
this.render();
|
|
223
258
|
}
|
|
224
259
|
|
|
@@ -228,7 +263,10 @@ class TUI {
|
|
|
228
263
|
log(null, message);
|
|
229
264
|
return;
|
|
230
265
|
}
|
|
231
|
-
|
|
266
|
+
|
|
267
|
+
if (this._logScrollOffset === 0) {
|
|
268
|
+
this._logScrollOffset = 0;
|
|
269
|
+
}
|
|
232
270
|
this.render();
|
|
233
271
|
}
|
|
234
272
|
|
|
@@ -236,104 +274,156 @@ class TUI {
|
|
|
236
274
|
return this._logHistory.join('\n');
|
|
237
275
|
}
|
|
238
276
|
|
|
277
|
+
getVisibleLogLines(maxRows) {
|
|
278
|
+
if (this._logHistory.length === 0) {
|
|
279
|
+
return [''];
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const maxOffset = Math.max(0, this._logHistory.length - maxRows);
|
|
283
|
+
this._logScrollOffset = Math.max(0, Math.min(this._logScrollOffset, maxOffset));
|
|
284
|
+
|
|
285
|
+
const endIndex = this._logHistory.length - this._logScrollOffset;
|
|
286
|
+
const startIndex = Math.max(0, endIndex - maxRows);
|
|
287
|
+
return this._logHistory.slice(startIndex, endIndex);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
scrollLogs(delta) {
|
|
291
|
+
const nextOffset = this._logScrollOffset + delta;
|
|
292
|
+
const maxOffset = Math.max(0, this._logHistory.length - 1);
|
|
293
|
+
this._logScrollOffset = Math.max(0, Math.min(nextOffset, maxOffset));
|
|
294
|
+
this.render();
|
|
295
|
+
}
|
|
296
|
+
|
|
239
297
|
render() {
|
|
240
|
-
if (this.isInitialized && this.
|
|
241
|
-
this.
|
|
298
|
+
if (this.isInitialized && this.app) {
|
|
299
|
+
this.app.rerender(React.createElement(TUIRoot, { tui: this }));
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
hasPrompt() {
|
|
304
|
+
return Boolean(this._activePrompt);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
getPromptRenderLines() {
|
|
308
|
+
if (!this._activePrompt) {
|
|
309
|
+
return [];
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (this._activePrompt.type === 'menu') {
|
|
313
|
+
const promptLines = [this._activePrompt.prompt];
|
|
314
|
+
for (let i = 0; i < this._activePrompt.options.length; i++) {
|
|
315
|
+
const isSelected = i === this._activePrompt.selectedIndex;
|
|
316
|
+
const prefix = isSelected ? styleText(['bold', 'green'], '>') : ' ';
|
|
317
|
+
promptLines.push(`${prefix} ${this._activePrompt.options[i]}`);
|
|
318
|
+
}
|
|
319
|
+
promptLines.push(styleText('gray', 'Use arrows to choose. Enter to confirm. Esc/q to cancel.'));
|
|
320
|
+
return promptLines;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
if (this._activePrompt.type === 'input') {
|
|
324
|
+
const cursor = styleText(['bold', 'cyan'], '_');
|
|
325
|
+
return [
|
|
326
|
+
this._activePrompt.prompt,
|
|
327
|
+
`${styleText('gray', '>')} ${this._activePrompt.value}${cursor}`,
|
|
328
|
+
styleText('gray', 'Type your value, Enter to submit, Esc/q to cancel.')
|
|
329
|
+
];
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
return [];
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
handlePromptInput(input, key) {
|
|
336
|
+
if (!this._activePrompt) {
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
if (this._activePrompt.type === 'menu') {
|
|
341
|
+
if (key.upArrow) {
|
|
342
|
+
this._activePrompt.selectedIndex = (this._activePrompt.selectedIndex - 1 + this._activePrompt.options.length) % this._activePrompt.options.length;
|
|
343
|
+
this.render();
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
if (key.downArrow) {
|
|
347
|
+
this._activePrompt.selectedIndex = (this._activePrompt.selectedIndex + 1) % this._activePrompt.options.length;
|
|
348
|
+
this.render();
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
if (key.return) {
|
|
352
|
+
const selectedIndex = this._activePrompt.selectedIndex;
|
|
353
|
+
const selectedValue = this._activePrompt.options[selectedIndex];
|
|
354
|
+
const resolve = this._activePrompt.resolve;
|
|
355
|
+
this._activePrompt = null;
|
|
356
|
+
this.render();
|
|
357
|
+
resolve({ value: selectedValue, index: selectedIndex });
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
if (key.escape || input === 'q') {
|
|
361
|
+
const resolve = this._activePrompt.resolve;
|
|
362
|
+
this._activePrompt = null;
|
|
363
|
+
this.render();
|
|
364
|
+
resolve(null);
|
|
365
|
+
}
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
if (this._activePrompt.type === 'input') {
|
|
370
|
+
if (key.return) {
|
|
371
|
+
const resolve = this._activePrompt.resolve;
|
|
372
|
+
const value = this._activePrompt.value;
|
|
373
|
+
this._activePrompt = null;
|
|
374
|
+
this.render();
|
|
375
|
+
resolve(value);
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
if (key.escape || input === 'q') {
|
|
379
|
+
const resolve = this._activePrompt.resolve;
|
|
380
|
+
this._activePrompt = null;
|
|
381
|
+
this.render();
|
|
382
|
+
resolve(null);
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
if (key.backspace || key.delete) {
|
|
386
|
+
this._activePrompt.value = this._activePrompt.value.slice(0, -1);
|
|
387
|
+
this.render();
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
if (!key.ctrl && !key.meta && input) {
|
|
391
|
+
this._activePrompt.value += input;
|
|
392
|
+
this.render();
|
|
393
|
+
}
|
|
242
394
|
}
|
|
243
395
|
}
|
|
244
396
|
|
|
245
397
|
async showMenu(options, prompt = 'Choose an option:') {
|
|
398
|
+
if (!this.isInitialized) {
|
|
399
|
+
return null;
|
|
400
|
+
}
|
|
401
|
+
|
|
246
402
|
return new Promise((resolve) => {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
label: ` ${prompt} `,
|
|
254
|
-
items: options,
|
|
255
|
-
keys: true,
|
|
256
|
-
mouse: true,
|
|
257
|
-
border: 'line',
|
|
258
|
-
style: {
|
|
259
|
-
fg: 'white',
|
|
260
|
-
bg: 'black',
|
|
261
|
-
border: { fg: 'blue' },
|
|
262
|
-
selected: { bg: 'blue', fg: 'white' }
|
|
263
|
-
}
|
|
264
|
-
});
|
|
265
|
-
menu.focus();
|
|
266
|
-
const stopLogScroll = (ch, key) => {
|
|
267
|
-
if (['up', 'down', 'pagedown', 'pageup'].includes(key.name)) {
|
|
268
|
-
return false;
|
|
269
|
-
}
|
|
403
|
+
this._activePrompt = {
|
|
404
|
+
type: 'menu',
|
|
405
|
+
options,
|
|
406
|
+
prompt,
|
|
407
|
+
selectedIndex: 0,
|
|
408
|
+
resolve
|
|
270
409
|
};
|
|
271
|
-
this.
|
|
272
|
-
menu.on('detach', () => {
|
|
273
|
-
this.logBox.ignoreKeys = false;
|
|
274
|
-
});
|
|
275
|
-
menu.on('keypress', stopLogScroll);
|
|
276
|
-
this.screen.render();
|
|
277
|
-
menu.on('select', (item, idx) => {
|
|
278
|
-
menu.destroy();
|
|
279
|
-
this.screen.render();
|
|
280
|
-
resolve({ value: item.getText(), index: idx });
|
|
281
|
-
});
|
|
282
|
-
menu.on('cancel', () => {
|
|
283
|
-
menu.destroy();
|
|
284
|
-
this.screen.render();
|
|
285
|
-
resolve(null);
|
|
286
|
-
});
|
|
287
|
-
menu.key(['escape', 'q'], () => {
|
|
288
|
-
menu.emit('cancel');
|
|
289
|
-
});
|
|
410
|
+
this.render();
|
|
290
411
|
});
|
|
291
412
|
}
|
|
292
413
|
|
|
293
414
|
async showInput(prompt = 'Enter value:') {
|
|
415
|
+
if (!this.isInitialized) {
|
|
416
|
+
return null;
|
|
417
|
+
}
|
|
418
|
+
|
|
294
419
|
return new Promise((resolve) => {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
border: 'line',
|
|
303
|
-
style: {
|
|
304
|
-
fg: 'white',
|
|
305
|
-
bg: 'black',
|
|
306
|
-
border: { fg: 'blue' }
|
|
307
|
-
}
|
|
308
|
-
});
|
|
309
|
-
const input = blessed.textbox({
|
|
310
|
-
parent: box,
|
|
311
|
-
top: 2,
|
|
312
|
-
left: 2,
|
|
313
|
-
width: '90%',
|
|
314
|
-
height: 1,
|
|
315
|
-
inputOnFocus: true,
|
|
316
|
-
style: {
|
|
317
|
-
fg: 'white',
|
|
318
|
-
bg: 'black',
|
|
319
|
-
focus: { bg: 'blue' }
|
|
320
|
-
}
|
|
321
|
-
});
|
|
322
|
-
input.focus();
|
|
323
|
-
this.screen.render();
|
|
324
|
-
input.on('submit', (value) => {
|
|
325
|
-
box.destroy();
|
|
326
|
-
this.screen.render();
|
|
327
|
-
resolve(value);
|
|
328
|
-
});
|
|
329
|
-
input.on('cancel', () => {
|
|
330
|
-
box.destroy();
|
|
331
|
-
this.screen.render();
|
|
332
|
-
resolve(null);
|
|
333
|
-
});
|
|
334
|
-
input.key(['escape', 'q'], () => {
|
|
335
|
-
input.emit('cancel');
|
|
336
|
-
});
|
|
420
|
+
this._activePrompt = {
|
|
421
|
+
type: 'input',
|
|
422
|
+
prompt,
|
|
423
|
+
value: '',
|
|
424
|
+
resolve
|
|
425
|
+
};
|
|
426
|
+
this.render();
|
|
337
427
|
});
|
|
338
428
|
}
|
|
339
429
|
|
|
@@ -356,65 +446,53 @@ class TUI {
|
|
|
356
446
|
this.watchMode = state.watchMode;
|
|
357
447
|
this.isPaused = state.isPaused;
|
|
358
448
|
this.isMouseEnabled = state.isMouseEnabled ?? true;
|
|
359
|
-
if (this.isMouseEnabled) {
|
|
360
|
-
this.enableMouseCapture();
|
|
361
|
-
} else {
|
|
362
|
-
this.disableMouseCapture();
|
|
363
|
-
}
|
|
364
|
-
this.updateHeader();
|
|
365
449
|
this.render();
|
|
366
450
|
}
|
|
367
451
|
}
|
|
368
452
|
|
|
369
453
|
enableMouseCapture() {
|
|
370
|
-
if (
|
|
454
|
+
if (this.isMouseEnabled) {
|
|
371
455
|
return;
|
|
372
456
|
}
|
|
373
457
|
this.isMouseEnabled = true;
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
return;
|
|
377
|
-
}
|
|
378
|
-
if (this.screen.program && this.screen.program.enableMouse) {
|
|
379
|
-
this.screen.program.enableMouse();
|
|
380
|
-
}
|
|
458
|
+
this.setMouseCaptureEnabled(true);
|
|
459
|
+
this.render();
|
|
381
460
|
}
|
|
382
461
|
|
|
383
462
|
disableMouseCapture() {
|
|
384
|
-
if (!this.
|
|
463
|
+
if (!this.isMouseEnabled) {
|
|
385
464
|
return;
|
|
386
465
|
}
|
|
387
466
|
this.isMouseEnabled = false;
|
|
388
|
-
|
|
389
|
-
|
|
467
|
+
this.setMouseCaptureEnabled(false);
|
|
468
|
+
this.render();
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
destroy() {
|
|
472
|
+
if (!this.isInitialized) {
|
|
390
473
|
return;
|
|
391
474
|
}
|
|
392
|
-
|
|
393
|
-
|
|
475
|
+
|
|
476
|
+
if (this.app) {
|
|
477
|
+
this.app.unmount();
|
|
478
|
+
this.app = null;
|
|
394
479
|
}
|
|
395
|
-
}
|
|
396
480
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
this.screen.program.normalBuffer();
|
|
402
|
-
this.screen.program.reset();
|
|
403
|
-
}
|
|
481
|
+
if (this._mouseDataHandler && process.stdin) {
|
|
482
|
+
process.stdin.off('data', this._mouseDataHandler);
|
|
483
|
+
this._mouseDataHandler = null;
|
|
484
|
+
}
|
|
404
485
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
process.stdout.write('\x1b[2J');
|
|
416
|
-
process.stdout.write('\x1b[H');
|
|
417
|
-
}
|
|
486
|
+
this.setMouseCaptureEnabled(false);
|
|
487
|
+
|
|
488
|
+
this.isInitialized = false;
|
|
489
|
+
this.isMouseEnabled = true;
|
|
490
|
+
this._activePrompt = null;
|
|
491
|
+
this._logScrollOffset = 0;
|
|
492
|
+
|
|
493
|
+
if (process.stdout.isTTY) {
|
|
494
|
+
process.stdout.write('\x1b[?25h');
|
|
495
|
+
process.stdout.write('\x1b[0m');
|
|
418
496
|
}
|
|
419
497
|
}
|
|
420
498
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sdc-build-wp",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.6.0",
|
|
4
4
|
"description": "Custom WordPress build process.",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=22"
|
|
@@ -26,17 +26,18 @@
|
|
|
26
26
|
"@stylistic/stylelint-plugin": "^4.0.0",
|
|
27
27
|
"@typescript-eslint/eslint-plugin": "^8.48.1",
|
|
28
28
|
"@typescript-eslint/parser": "^8.48.1",
|
|
29
|
-
"@wordpress/scripts": "^31.4.0",
|
|
30
29
|
"autoprefixer": "^10.4.24",
|
|
31
|
-
"blessed": "^0.1.81",
|
|
32
30
|
"browser-sync": "^3.0.4",
|
|
33
31
|
"chokidar": "^5.0.0",
|
|
34
32
|
"esbuild": "^0.27.3",
|
|
35
33
|
"eslint": "^9.39.1",
|
|
34
|
+
"ink": "^6.8.0",
|
|
36
35
|
"postcss": "^8.5.6",
|
|
37
36
|
"postcss-scss": "^4.0.9",
|
|
38
37
|
"postcss-sort-media-queries": "^5.2.0",
|
|
39
38
|
"prettier": "^3.8.1",
|
|
39
|
+
"react": "^19.2.4",
|
|
40
|
+
"react-dom": "^19.2.4",
|
|
40
41
|
"sass": "^1.97.3",
|
|
41
42
|
"sharp": "^0.34.5",
|
|
42
43
|
"stylelint": "^16.26.1",
|
package/webpack.config.js
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
let defaultConfig = {};
|
|
2
|
+
|
|
3
|
+
try {
|
|
4
|
+
const wpConfig = await import('@wordpress/scripts/config/webpack.config.js');
|
|
5
|
+
defaultConfig = wpConfig.default || {};
|
|
6
|
+
} catch {
|
|
7
|
+
defaultConfig = {};
|
|
8
|
+
}
|
|
2
9
|
|
|
3
10
|
export default {
|
|
4
11
|
...defaultConfig,
|