@bootmap/wpep-cli 1.1.1 → 1.1.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/package.json +3 -1
- package/src/commands/deploy.js +64 -24
- package/src/commands/init.js +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bootmap/wpep-cli",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "CLI tool for deploying Next.js static exports to WordPress via WP Elementor Publisher",
|
|
5
5
|
"main": "bin/wpep.js",
|
|
6
6
|
"type": "module",
|
|
@@ -20,8 +20,10 @@
|
|
|
20
20
|
"author": "",
|
|
21
21
|
"license": "ISC",
|
|
22
22
|
"dependencies": {
|
|
23
|
+
"archiver": "^8.0.0",
|
|
23
24
|
"chalk": "^5.3.0",
|
|
24
25
|
"commander": "^11.1.0",
|
|
26
|
+
"form-data": "^4.0.6",
|
|
25
27
|
"inquirer": "^9.2.12",
|
|
26
28
|
"ora": "^7.0.1"
|
|
27
29
|
}
|
package/src/commands/deploy.js
CHANGED
|
@@ -5,6 +5,9 @@ import chalk from 'chalk';
|
|
|
5
5
|
import ora from 'ora';
|
|
6
6
|
import { execSync } from 'child_process';
|
|
7
7
|
import inquirer from 'inquirer';
|
|
8
|
+
import { createRequire } from 'module';
|
|
9
|
+
const require = createRequire(import.meta.url);
|
|
10
|
+
const archiver = require('archiver');
|
|
8
11
|
|
|
9
12
|
function getFiles(dir, files = []) {
|
|
10
13
|
if (!fs.existsSync(dir)) return files;
|
|
@@ -25,15 +28,18 @@ export default async function deployCommand(options) {
|
|
|
25
28
|
let key = options.key;
|
|
26
29
|
|
|
27
30
|
if (!url || !key) {
|
|
28
|
-
const rcPath = path.join(process.cwd(), '.
|
|
29
|
-
|
|
31
|
+
const rcPath = path.join(process.cwd(), '.wpep.config.json');
|
|
32
|
+
const oldRcPath = path.join(process.cwd(), '.wpeprc.json');
|
|
33
|
+
let configPath = fs.existsSync(rcPath) ? rcPath : (fs.existsSync(oldRcPath) ? oldRcPath : null);
|
|
34
|
+
|
|
35
|
+
if (configPath) {
|
|
30
36
|
try {
|
|
31
|
-
const config = JSON.parse(fs.readFileSync(
|
|
37
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
32
38
|
url = url || config.url;
|
|
33
39
|
key = key || config.key;
|
|
34
40
|
options.dir = options.dir || config.dir;
|
|
35
41
|
} catch (e) {
|
|
36
|
-
throw new Error('Could not read .
|
|
42
|
+
throw new Error('Could not read config file. Run "wpep init" first.');
|
|
37
43
|
}
|
|
38
44
|
}
|
|
39
45
|
}
|
|
@@ -76,6 +82,15 @@ export default async function deployCommand(options) {
|
|
|
76
82
|
);
|
|
77
83
|
fs.writeFileSync(nextConfigPath, patched, 'utf8');
|
|
78
84
|
}
|
|
85
|
+
|
|
86
|
+
// Check for next/image unoptimized
|
|
87
|
+
const hasNextImage = getFiles(process.cwd()).some(f => f.endsWith('.js') || f.endsWith('.tsx') || f.endsWith('.jsx'));
|
|
88
|
+
// A quick heuristic: if they have next.config.js but didn't set images: { unoptimized: true }
|
|
89
|
+
if (!originalContent.includes('unoptimized') && !originalContent.includes('unoptimized: true')) {
|
|
90
|
+
console.log(chalk.red.bold('\n⚠️ STATIC EXPORT WARNING'));
|
|
91
|
+
console.log(chalk.yellow('If you use next/image (<Image />), static exports will fail unless you configure unoptimized: true.'));
|
|
92
|
+
console.log(chalk.yellow('Add this to your next.config.js:\n images: { unoptimized: true }\n'));
|
|
93
|
+
}
|
|
79
94
|
}
|
|
80
95
|
|
|
81
96
|
if (options.build !== false) {
|
|
@@ -183,32 +198,57 @@ export default async function deployCommand(options) {
|
|
|
183
198
|
if (skippedCount > 0) {
|
|
184
199
|
console.log(chalk.green(`\n⚡ ${skippedCount} unchanged files will be copied server-side (not re-uploaded).`));
|
|
185
200
|
}
|
|
186
|
-
console.log(chalk.gray(`
|
|
201
|
+
console.log(chalk.gray(`Preparing ZIP archive for ${changedFiles.length} changed files...\n`));
|
|
202
|
+
|
|
203
|
+
const zipPath = path.join(process.cwd(), 'wpep-deploy.zip');
|
|
204
|
+
const outputZip = fs.createWriteStream(zipPath);
|
|
205
|
+
const archive = archiver('zip', { zlib: { level: 9 } });
|
|
206
|
+
|
|
207
|
+
const zipPromise = new Promise((resolve, reject) => {
|
|
208
|
+
outputZip.on('close', resolve);
|
|
209
|
+
archive.on('error', reject);
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
archive.pipe(outputZip);
|
|
187
213
|
|
|
188
|
-
let uploaded = 0;
|
|
189
214
|
for (const file of changedFiles) {
|
|
190
215
|
const relativePath = path.relative(outDir, file);
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
const hash = filesList[relativePath];
|
|
216
|
+
archive.file(file, { name: relativePath });
|
|
217
|
+
}
|
|
194
218
|
|
|
195
|
-
|
|
219
|
+
await archive.finalize();
|
|
220
|
+
await zipPromise;
|
|
196
221
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
222
|
+
const uploadSpinner = ora('Uploading archive to WordPress...').start();
|
|
223
|
+
try {
|
|
224
|
+
const fileBuffer = fs.readFileSync(zipPath);
|
|
225
|
+
const blob = new Blob([fileBuffer], { type: 'application/zip' });
|
|
226
|
+
|
|
227
|
+
// We must use the native FormData (available in Node 18+)
|
|
228
|
+
const formData = new globalThis.FormData();
|
|
229
|
+
formData.append('archive', blob, 'wpep-deploy.zip');
|
|
230
|
+
|
|
231
|
+
const uploadRes = await fetch(`${url}/wp-json/wpep/v1/deployments/${deployId}/upload-archive`, {
|
|
232
|
+
method: 'POST',
|
|
233
|
+
headers: {
|
|
234
|
+
'x-wpep-api-key': key
|
|
235
|
+
},
|
|
236
|
+
body: formData
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
if (!uploadRes.ok) {
|
|
240
|
+
const errorText = await uploadRes.text();
|
|
241
|
+
throw new Error(`Failed to upload archive: ${uploadRes.statusText} - ${errorText}`);
|
|
211
242
|
}
|
|
243
|
+
uploadSpinner.succeed('Archive uploaded and extracted successfully.');
|
|
244
|
+
|
|
245
|
+
// Clean up zip
|
|
246
|
+
if (fs.existsSync(zipPath)) {
|
|
247
|
+
fs.unlinkSync(zipPath);
|
|
248
|
+
}
|
|
249
|
+
} catch (e) {
|
|
250
|
+
uploadSpinner.fail('Failed to upload archive.');
|
|
251
|
+
throw e;
|
|
212
252
|
}
|
|
213
253
|
|
|
214
254
|
const activateSpinner = ora('Activating deployment...').start();
|
package/src/commands/init.js
CHANGED
|
@@ -6,7 +6,7 @@ import path from 'path';
|
|
|
6
6
|
export default async function initCommand() {
|
|
7
7
|
console.log(chalk.blue.bold('\nWelcome to WP Elementor Publisher (WPEP) CLI\n'));
|
|
8
8
|
|
|
9
|
-
const rcPath = path.join(process.cwd(), '.
|
|
9
|
+
const rcPath = path.join(process.cwd(), '.wpep.config.json');
|
|
10
10
|
|
|
11
11
|
let existingConfig = {};
|
|
12
12
|
if (fs.existsSync(rcPath)) {
|
|
@@ -67,6 +67,6 @@ export default async function initCommand() {
|
|
|
67
67
|
|
|
68
68
|
fs.writeFileSync(rcPath, JSON.stringify(config, null, 2));
|
|
69
69
|
|
|
70
|
-
console.log(chalk.green(`\
|
|
70
|
+
console.log(chalk.green(`\n✅ Successfully initialized WPEP configuration in .wpep.config.json`));
|
|
71
71
|
console.log(`You can now run ${chalk.cyan('wpep deploy')} to deploy your site.\n`);
|
|
72
72
|
}
|