@loopress/cli 0.3.0 → 0.5.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.
Files changed (33) hide show
  1. package/README.md +88 -334
  2. package/dist/commands/init.d.ts +6 -0
  3. package/dist/commands/init.js +73 -0
  4. package/dist/commands/{styles → plugin}/pull.d.ts +1 -1
  5. package/dist/commands/plugin/pull.js +48 -0
  6. package/dist/commands/{styles → plugin}/push.d.ts +4 -4
  7. package/dist/commands/plugin/push.js +113 -0
  8. package/dist/commands/plugin/require.d.ts +17 -0
  9. package/dist/commands/plugin/require.js +74 -0
  10. package/dist/commands/project/config.js +2 -2
  11. package/dist/commands/{snippets → snippet}/list.d.ts +1 -1
  12. package/dist/commands/{snippets → snippet}/list.js +3 -3
  13. package/dist/commands/{snippets → snippet}/pull.d.ts +4 -1
  14. package/dist/commands/{snippets → snippet}/pull.js +26 -37
  15. package/dist/commands/{snippets → snippet}/push.d.ts +4 -5
  16. package/dist/commands/{snippets → snippet}/push.js +50 -39
  17. package/dist/config/auth.manager.js +2 -2
  18. package/dist/config/project-config.manager.js +2 -2
  19. package/dist/lib/base.d.ts +1 -1
  20. package/dist/lib/base.js +18 -6
  21. package/dist/lib/push-command.d.ts +7 -0
  22. package/dist/lib/push-command.js +32 -0
  23. package/dist/types/plugin.d.ts +15 -0
  24. package/dist/types/plugin.js +1 -0
  25. package/dist/utils/loopress-config.d.ts +5 -2
  26. package/dist/utils/loopress-config.js +8 -3
  27. package/dist/utils/plugins.d.ts +27 -0
  28. package/dist/utils/plugins.js +34 -0
  29. package/dist/utils/snippet-plugin.js +1 -1
  30. package/oclif.manifest.json +217 -131
  31. package/package.json +14 -19
  32. package/dist/commands/styles/pull.js +0 -52
  33. package/dist/commands/styles/push.js +0 -78
@@ -1,5 +1,28 @@
1
1
  {
2
2
  "commands": {
3
+ "init": {
4
+ "aliases": [],
5
+ "args": {},
6
+ "description": "Initialize a loopress.json config file in the current directory",
7
+ "examples": [
8
+ "$ lps init"
9
+ ],
10
+ "flags": {},
11
+ "hasDynamicHelp": false,
12
+ "hiddenAliases": [],
13
+ "id": "init",
14
+ "pluginAlias": "@loopress/cli",
15
+ "pluginName": "@loopress/cli",
16
+ "pluginType": "core",
17
+ "strict": true,
18
+ "enableJsonFlag": false,
19
+ "isESM": true,
20
+ "relativePath": [
21
+ "dist",
22
+ "commands",
23
+ "init.js"
24
+ ]
25
+ },
3
26
  "login": {
4
27
  "aliases": [],
5
28
  "args": {},
@@ -46,6 +69,187 @@
46
69
  "logout.js"
47
70
  ]
48
71
  },
72
+ "plugin:pull": {
73
+ "aliases": [],
74
+ "args": {},
75
+ "description": "Pull installed plugins from WordPress into loopress.json",
76
+ "examples": [
77
+ "$ lps plugins pull",
78
+ "$ lps plugins pull --dry-run"
79
+ ],
80
+ "flags": {
81
+ "password": {
82
+ "description": "WordPress application password (fallback; prefer `lps project config`)",
83
+ "helpGroup": "GLOBAL",
84
+ "name": "password",
85
+ "hasDynamicHelp": false,
86
+ "multiple": false,
87
+ "type": "option"
88
+ },
89
+ "url": {
90
+ "description": "WordPress URL (fallback; prefer `lps project config`)",
91
+ "helpGroup": "GLOBAL",
92
+ "name": "url",
93
+ "hasDynamicHelp": false,
94
+ "multiple": false,
95
+ "type": "option"
96
+ },
97
+ "user": {
98
+ "description": "WordPress username (fallback; prefer `lps project config`)",
99
+ "helpGroup": "GLOBAL",
100
+ "name": "user",
101
+ "hasDynamicHelp": false,
102
+ "multiple": false,
103
+ "type": "option"
104
+ },
105
+ "dry-run": {
106
+ "char": "d",
107
+ "description": "Show what would be written without making changes",
108
+ "name": "dry-run",
109
+ "allowNo": false,
110
+ "type": "boolean"
111
+ }
112
+ },
113
+ "hasDynamicHelp": false,
114
+ "hiddenAliases": [],
115
+ "id": "plugin:pull",
116
+ "pluginAlias": "@loopress/cli",
117
+ "pluginName": "@loopress/cli",
118
+ "pluginType": "core",
119
+ "strict": true,
120
+ "enableJsonFlag": false,
121
+ "isESM": true,
122
+ "relativePath": [
123
+ "dist",
124
+ "commands",
125
+ "plugin",
126
+ "pull.js"
127
+ ]
128
+ },
129
+ "plugin:push": {
130
+ "aliases": [],
131
+ "args": {},
132
+ "description": "Sync plugins on WordPress to match loopress.json",
133
+ "examples": [
134
+ "$ lps plugins push",
135
+ "$ lps plugins push --dry-run"
136
+ ],
137
+ "flags": {
138
+ "password": {
139
+ "description": "WordPress application password (fallback; prefer `lps project config`)",
140
+ "helpGroup": "GLOBAL",
141
+ "name": "password",
142
+ "hasDynamicHelp": false,
143
+ "multiple": false,
144
+ "type": "option"
145
+ },
146
+ "url": {
147
+ "description": "WordPress URL (fallback; prefer `lps project config`)",
148
+ "helpGroup": "GLOBAL",
149
+ "name": "url",
150
+ "hasDynamicHelp": false,
151
+ "multiple": false,
152
+ "type": "option"
153
+ },
154
+ "user": {
155
+ "description": "WordPress username (fallback; prefer `lps project config`)",
156
+ "helpGroup": "GLOBAL",
157
+ "name": "user",
158
+ "hasDynamicHelp": false,
159
+ "multiple": false,
160
+ "type": "option"
161
+ },
162
+ "dry-run": {
163
+ "char": "d",
164
+ "description": "Show what would change without making changes",
165
+ "name": "dry-run",
166
+ "allowNo": false,
167
+ "type": "boolean"
168
+ }
169
+ },
170
+ "hasDynamicHelp": false,
171
+ "hiddenAliases": [],
172
+ "id": "plugin:push",
173
+ "pluginAlias": "@loopress/cli",
174
+ "pluginName": "@loopress/cli",
175
+ "pluginType": "core",
176
+ "strict": true,
177
+ "isESM": true,
178
+ "relativePath": [
179
+ "dist",
180
+ "commands",
181
+ "plugin",
182
+ "push.js"
183
+ ]
184
+ },
185
+ "plugin:require": {
186
+ "aliases": [],
187
+ "args": {
188
+ "slug": {
189
+ "description": "Plugin slug (WordPress.org)",
190
+ "name": "slug",
191
+ "required": true
192
+ },
193
+ "version": {
194
+ "description": "Version to pin (default: latest)",
195
+ "name": "version"
196
+ }
197
+ },
198
+ "description": "Add a plugin to loopress.json, resolving its latest version from WordPress.org",
199
+ "examples": [
200
+ "$ lps plugins require woocommerce",
201
+ "$ lps plugins require woocommerce 8.9.1",
202
+ "$ lps plugins require contact-form-7 --dry-run"
203
+ ],
204
+ "flags": {
205
+ "password": {
206
+ "description": "WordPress application password (fallback; prefer `lps project config`)",
207
+ "helpGroup": "GLOBAL",
208
+ "name": "password",
209
+ "hasDynamicHelp": false,
210
+ "multiple": false,
211
+ "type": "option"
212
+ },
213
+ "url": {
214
+ "description": "WordPress URL (fallback; prefer `lps project config`)",
215
+ "helpGroup": "GLOBAL",
216
+ "name": "url",
217
+ "hasDynamicHelp": false,
218
+ "multiple": false,
219
+ "type": "option"
220
+ },
221
+ "user": {
222
+ "description": "WordPress username (fallback; prefer `lps project config`)",
223
+ "helpGroup": "GLOBAL",
224
+ "name": "user",
225
+ "hasDynamicHelp": false,
226
+ "multiple": false,
227
+ "type": "option"
228
+ },
229
+ "dry-run": {
230
+ "char": "d",
231
+ "description": "Show what would be written without making changes",
232
+ "name": "dry-run",
233
+ "allowNo": false,
234
+ "type": "boolean"
235
+ }
236
+ },
237
+ "hasDynamicHelp": false,
238
+ "hiddenAliases": [],
239
+ "id": "plugin:require",
240
+ "pluginAlias": "@loopress/cli",
241
+ "pluginName": "@loopress/cli",
242
+ "pluginType": "core",
243
+ "strict": true,
244
+ "enableJsonFlag": false,
245
+ "isESM": true,
246
+ "relativePath": [
247
+ "dist",
248
+ "commands",
249
+ "plugin",
250
+ "require.js"
251
+ ]
252
+ },
49
253
  "project:config": {
50
254
  "aliases": [],
51
255
  "args": {},
@@ -190,7 +394,7 @@
190
394
  "switch.js"
191
395
  ]
192
396
  },
193
- "snippets:list": {
397
+ "snippet:list": {
194
398
  "aliases": [],
195
399
  "args": {},
196
400
  "description": "List snippets from WordPress",
@@ -233,9 +437,8 @@
233
437
  },
234
438
  "plugin": {
235
439
  "char": "p",
236
- "description": "WordPress snippet plugin to target",
440
+ "description": "WordPress snippet plugin to target (overrides loopress.json)",
237
441
  "name": "plugin",
238
- "default": "code-snippets",
239
442
  "hasDynamicHelp": false,
240
443
  "multiple": false,
241
444
  "options": [
@@ -247,7 +450,7 @@
247
450
  },
248
451
  "hasDynamicHelp": false,
249
452
  "hiddenAliases": [],
250
- "id": "snippets:list",
453
+ "id": "snippet:list",
251
454
  "pluginAlias": "@loopress/cli",
252
455
  "pluginName": "@loopress/cli",
253
456
  "pluginType": "core",
@@ -257,11 +460,11 @@
257
460
  "relativePath": [
258
461
  "dist",
259
462
  "commands",
260
- "snippets",
463
+ "snippet",
261
464
  "list.js"
262
465
  ]
263
466
  },
264
- "snippets:pull": {
467
+ "snippet:pull": {
265
468
  "aliases": [],
266
469
  "args": {
267
470
  "path": {
@@ -310,9 +513,8 @@
310
513
  },
311
514
  "plugin": {
312
515
  "char": "p",
313
- "description": "WordPress snippet plugin to target",
516
+ "description": "WordPress snippet plugin to target (overrides loopress.json)",
314
517
  "name": "plugin",
315
- "default": "code-snippets",
316
518
  "hasDynamicHelp": false,
317
519
  "multiple": false,
318
520
  "options": [
@@ -324,7 +526,7 @@
324
526
  },
325
527
  "hasDynamicHelp": false,
326
528
  "hiddenAliases": [],
327
- "id": "snippets:pull",
529
+ "id": "snippet:pull",
328
530
  "pluginAlias": "@loopress/cli",
329
531
  "pluginName": "@loopress/cli",
330
532
  "pluginType": "core",
@@ -334,11 +536,11 @@
334
536
  "relativePath": [
335
537
  "dist",
336
538
  "commands",
337
- "snippets",
539
+ "snippet",
338
540
  "pull.js"
339
541
  ]
340
542
  },
341
- "snippets:push": {
543
+ "snippet:push": {
342
544
  "aliases": [],
343
545
  "args": {
344
546
  "path": {
@@ -387,9 +589,8 @@
387
589
  },
388
590
  "plugin": {
389
591
  "char": "p",
390
- "description": "WordPress snippet plugin to target",
592
+ "description": "WordPress snippet plugin to target (overrides loopress.json)",
391
593
  "name": "plugin",
392
- "default": "code-snippets",
393
594
  "hasDynamicHelp": false,
394
595
  "multiple": false,
395
596
  "options": [
@@ -401,134 +602,19 @@
401
602
  },
402
603
  "hasDynamicHelp": false,
403
604
  "hiddenAliases": [],
404
- "id": "snippets:push",
605
+ "id": "snippet:push",
405
606
  "pluginAlias": "@loopress/cli",
406
607
  "pluginName": "@loopress/cli",
407
608
  "pluginType": "core",
408
609
  "strict": true,
409
- "enableJsonFlag": false,
410
- "isESM": true,
411
- "relativePath": [
412
- "dist",
413
- "commands",
414
- "snippets",
415
- "push.js"
416
- ]
417
- },
418
- "styles:pull": {
419
- "aliases": [],
420
- "args": {},
421
- "description": "Pull Global Styles from WordPress",
422
- "examples": [
423
- "$ lps styles pull",
424
- "$ lps styles pull --url http://example.com"
425
- ],
426
- "flags": {
427
- "password": {
428
- "description": "WordPress application password (fallback; prefer `lps project config`)",
429
- "helpGroup": "GLOBAL",
430
- "name": "password",
431
- "hasDynamicHelp": false,
432
- "multiple": false,
433
- "type": "option"
434
- },
435
- "url": {
436
- "description": "WordPress URL (fallback; prefer `lps project config`)",
437
- "helpGroup": "GLOBAL",
438
- "name": "url",
439
- "hasDynamicHelp": false,
440
- "multiple": false,
441
- "type": "option"
442
- },
443
- "user": {
444
- "description": "WordPress username (fallback; prefer `lps project config`)",
445
- "helpGroup": "GLOBAL",
446
- "name": "user",
447
- "hasDynamicHelp": false,
448
- "multiple": false,
449
- "type": "option"
450
- },
451
- "dryRun": {
452
- "char": "d",
453
- "description": "Dry run - show what would happen without making changes",
454
- "name": "dryRun",
455
- "allowNo": false,
456
- "type": "boolean"
457
- }
458
- },
459
- "hasDynamicHelp": false,
460
- "hiddenAliases": [],
461
- "id": "styles:pull",
462
- "pluginAlias": "@loopress/cli",
463
- "pluginName": "@loopress/cli",
464
- "pluginType": "core",
465
- "strict": true,
466
- "enableJsonFlag": false,
467
- "isESM": true,
468
- "relativePath": [
469
- "dist",
470
- "commands",
471
- "styles",
472
- "pull.js"
473
- ]
474
- },
475
- "styles:push": {
476
- "aliases": [],
477
- "args": {},
478
- "description": "Push Global Styles to WordPress",
479
- "examples": [
480
- "$ lps styles push",
481
- "$ lps styles push --url http://example.com"
482
- ],
483
- "flags": {
484
- "password": {
485
- "description": "WordPress application password (fallback; prefer `lps project config`)",
486
- "helpGroup": "GLOBAL",
487
- "name": "password",
488
- "hasDynamicHelp": false,
489
- "multiple": false,
490
- "type": "option"
491
- },
492
- "url": {
493
- "description": "WordPress URL (fallback; prefer `lps project config`)",
494
- "helpGroup": "GLOBAL",
495
- "name": "url",
496
- "hasDynamicHelp": false,
497
- "multiple": false,
498
- "type": "option"
499
- },
500
- "user": {
501
- "description": "WordPress username (fallback; prefer `lps project config`)",
502
- "helpGroup": "GLOBAL",
503
- "name": "user",
504
- "hasDynamicHelp": false,
505
- "multiple": false,
506
- "type": "option"
507
- },
508
- "dryRun": {
509
- "char": "d",
510
- "description": "Dry run - show what would happen without making changes",
511
- "name": "dryRun",
512
- "allowNo": false,
513
- "type": "boolean"
514
- }
515
- },
516
- "hasDynamicHelp": false,
517
- "hiddenAliases": [],
518
- "id": "styles:push",
519
- "pluginAlias": "@loopress/cli",
520
- "pluginName": "@loopress/cli",
521
- "pluginType": "core",
522
- "strict": true,
523
- "enableJsonFlag": false,
524
610
  "isESM": true,
525
611
  "relativePath": [
526
612
  "dist",
527
613
  "commands",
528
- "styles",
614
+ "snippet",
529
615
  "push.js"
530
616
  ]
531
617
  }
532
618
  },
533
- "version": "0.3.0"
619
+ "version": "0.5.0"
534
620
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@loopress/cli",
3
3
  "description": "CLI tool for syncing WordPress CodeSnippets, styles, and menus via the REST API",
4
- "version": "0.3.0",
4
+ "version": "0.5.0",
5
5
  "author": "jean-smaug",
6
6
  "bin": {
7
7
  "loopress": "bin/run.js",
@@ -12,31 +12,27 @@
12
12
  },
13
13
  "dependencies": {
14
14
  "@inquirer/prompts": "^8.5.2",
15
- "@oclif/core": "^4.11.7",
16
- "@oclif/plugin-help": "^6.2.50",
17
- "@oclif/plugin-plugins": "^5.4.72",
15
+ "@oclif/core": "^4.11.11",
16
+ "@oclif/plugin-help": "^6.2.52",
17
+ "@oclif/plugin-plugins": "^5.4.80",
18
18
  "glob": "13.0.6",
19
- "got": "^15.0.5",
19
+ "got": "^15.0.7",
20
20
  "slugify": "^1.6.9"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@eslint/compat": "2.1.0",
24
24
  "@oclif/prettier-config": "^0.2.1",
25
- "@oclif/test": "^4",
26
- "@types/chai": "^5.2.3",
27
- "@types/mocha": "^10",
28
- "@types/node": "25.9.3",
29
- "chai": "^6.2.2",
25
+ "@oclif/test": "^4.1.20",
26
+ "@types/node": "26.0.1",
30
27
  "eslint": "^9",
31
- "eslint-config-oclif": "^6",
28
+ "eslint-config-oclif": "^6.0.174",
32
29
  "eslint-config-prettier": "^10",
33
- "mocha": "^11.7.6",
34
- "oclif": "^4",
35
- "prettier": "3.8.4",
30
+ "oclif": "^4.23.22",
31
+ "prettier": "3.9.1",
36
32
  "shx": "^0.4.0",
37
- "ts-node": "^10",
38
33
  "tsx": "4.22.4",
39
- "typescript": "^6.0.3"
34
+ "typescript": "^6.0.3",
35
+ "vitest": "^3.2.4"
40
36
  },
41
37
  "engines": {
42
38
  "node": ">=18.0.0"
@@ -63,8 +59,7 @@
63
59
  "commands": "./dist/commands",
64
60
  "helpClass": "./dist/help.js",
65
61
  "plugins": [
66
- "@oclif/plugin-help",
67
- "@oclif/plugin-plugins"
62
+ "@oclif/plugin-help"
68
63
  ],
69
64
  "topicSeparator": " "
70
65
  },
@@ -81,7 +76,7 @@
81
76
  "build": "shx rm -rf dist && tsc -b",
82
77
  "lint": "eslint",
83
78
  "posttest": "pnpm run lint",
84
- "test": "mocha --forbid-only \"test/**/*.test.ts\" --reporter spec --full-trace --verbose",
79
+ "test": "vitest run",
85
80
  "version": "oclif readme && git add README.md",
86
81
  "format": "prettier . --write"
87
82
  }
@@ -1,52 +0,0 @@
1
- import { Flags } from '@oclif/core';
2
- import got from 'got';
3
- import { LoopressCommand } from '../../lib/base.js';
4
- export default class Pull extends LoopressCommand {
5
- static description = 'Pull Global Styles from WordPress';
6
- static examples = ['$ lps styles pull', '$ lps styles pull --url http://example.com'];
7
- static flags = {
8
- ...LoopressCommand.baseFlags,
9
- dryRun: Flags.boolean({ char: 'd', description: 'Dry run - show what would happen without making changes' }),
10
- };
11
- async run() {
12
- const { flags } = await this.parse(Pull);
13
- const { dryRun } = flags;
14
- const { url } = this.siteConfig;
15
- const stylesDir = await this.resolveStylesPath();
16
- const outputPath = `${stylesDir}/global-styles.json`;
17
- this.log(`📥 Pulling Global Styles from ${url}`);
18
- this.log(`📂 Target file: ${outputPath}`);
19
- this.log(`🔄 Dry run: ${dryRun ? 'yes' : 'no'}`);
20
- try {
21
- const headers = await this.buildAuthHeaders();
22
- this.log('🔍 Finding active theme...');
23
- const themes = await got.get(`${url}/wp-json/wp/v2/themes?status=active`, { headers }).json();
24
- if (!themes || themes.length === 0) {
25
- this.error('❌ No active theme found.');
26
- }
27
- const activeTheme = themes[0];
28
- const globalStylesEndpoint = activeTheme._links['wp:user-global-styles'][0].href;
29
- if (!globalStylesEndpoint) {
30
- this.error(`❌ Active theme "${activeTheme.name}" does not have global styles endpoint.`);
31
- }
32
- const globalStyles = await got.get(globalStylesEndpoint, { headers }).json();
33
- const dataToSave = {
34
- id: globalStyles.id,
35
- settings: globalStyles.settings,
36
- styles: globalStyles.styles,
37
- };
38
- if (dryRun) {
39
- this.log(`📝 [DRY RUN] Would pull styles and settings for ID: ${globalStyles.id}`);
40
- this.log(`📄 Data preview: ${JSON.stringify(dataToSave).slice(0, 100)}...`);
41
- return;
42
- }
43
- const fs = await import('node:fs/promises');
44
- await fs.mkdir(stylesDir, { recursive: true });
45
- await fs.writeFile(outputPath, JSON.stringify(dataToSave, null, 2));
46
- this.log(`✅ Successfully pulled global styles to ${outputPath}`);
47
- }
48
- catch (error) {
49
- this.error(`❌ Error pulling global styles: ${error.message}`);
50
- }
51
- }
52
- }
@@ -1,78 +0,0 @@
1
- import { Flags } from '@oclif/core';
2
- import { glob } from 'glob';
3
- import got from 'got';
4
- import { LoopressCommand } from '../../lib/base.js';
5
- export default class Push extends LoopressCommand {
6
- static description = 'Push Global Styles to WordPress';
7
- static examples = ['$ lps styles push', '$ lps styles push --url http://example.com'];
8
- static flags = {
9
- ...LoopressCommand.baseFlags,
10
- dryRun: Flags.boolean({ char: 'd', description: 'Dry run - show what would happen without making changes' }),
11
- };
12
- async run() {
13
- const { flags } = await this.parse(Push);
14
- const { dryRun } = flags;
15
- const { url } = this.siteConfig;
16
- const stylesDir = await this.resolveStylesPath();
17
- const jsonPath = `${stylesDir}/global-styles.json`;
18
- this.log(`📤 Pushing Global Styles to ${url}`);
19
- this.log(`📂 From directory: ${stylesDir}`);
20
- this.log(`🔄 Dry run: ${dryRun ? 'yes' : 'no'}`);
21
- try {
22
- const fs = await import('node:fs/promises');
23
- const headers = await this.buildAuthHeaders();
24
- const data = await this.readOrFetchGlobalStyles(jsonPath, url, headers, fs);
25
- this.log('🎨 Bundling CSS files in memory...');
26
- const cssFiles = await glob(`${stylesDir}/**/*.css`);
27
- let bundledCss = '';
28
- if (cssFiles.length > 0) {
29
- const cssContents = await Promise.all(cssFiles.map((file) => fs.readFile(file, 'utf8')));
30
- bundledCss = cssContents.join('\n').trim();
31
- this.log(`✨ Bundled ${cssFiles.length} CSS files`);
32
- }
33
- else {
34
- this.log(`⚠️ No CSS files found in ${stylesDir}/**/*.css`);
35
- }
36
- const endpoint = `${url}/wp-json/wp/v2/global-styles/${data.id}`;
37
- const payload = {
38
- settings: data.settings,
39
- styles: {
40
- ...data.styles,
41
- ...(bundledCss ? { css: bundledCss } : {}),
42
- },
43
- };
44
- if (dryRun) {
45
- this.log(`📝 [DRY RUN] Would push to ${endpoint}`);
46
- this.log(`📄 Payload preview: ${JSON.stringify(payload).slice(0, 100)}...`);
47
- return;
48
- }
49
- await got.post(endpoint, { headers, json: payload });
50
- this.log(`✅ Successfully pushed global styles to ID: ${data.id}`);
51
- }
52
- catch (error) {
53
- this.error(`❌ Error pushing global styles: ${error.message}`);
54
- }
55
- }
56
- async readOrFetchGlobalStyles(jsonPath, url, headers, fs) {
57
- try {
58
- const content = await fs.readFile(jsonPath, 'utf8');
59
- return JSON.parse(content);
60
- }
61
- catch (error) {
62
- if (error.code !== 'ENOENT')
63
- throw error;
64
- }
65
- this.log('ℹ️ No local cache found — fetching global styles from WordPress...');
66
- const themes = await got.get(`${url}/wp-json/wp/v2/themes?status=active`, { headers }).json();
67
- if (!themes || themes.length === 0) {
68
- this.error('❌ No active theme found.');
69
- }
70
- const globalStylesEndpoint = themes[0]._links['wp:user-global-styles'][0].href;
71
- const globalStyles = await got.get(globalStylesEndpoint, { headers }).json();
72
- const data = { id: globalStyles.id, settings: globalStyles.settings, styles: globalStyles.styles };
73
- await fs.mkdir(jsonPath.replace(/\/[^/]+$/, ''), { recursive: true });
74
- await fs.writeFile(jsonPath, JSON.stringify(data, null, 2));
75
- this.log(`💾 Cached to ${jsonPath}`);
76
- return data;
77
- }
78
- }