@loopress/cli 0.13.0 → 0.15.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 (43) hide show
  1. package/README.md +96 -44
  2. package/dist/commands/init.js +5 -5
  3. package/dist/commands/plugin/add.d.ts +0 -2
  4. package/dist/commands/plugin/add.js +6 -47
  5. package/dist/commands/plugin/pull.js +4 -6
  6. package/dist/commands/plugin/push.d.ts +1 -2
  7. package/dist/commands/plugin/push.js +18 -50
  8. package/dist/commands/project/pull.d.ts +8 -0
  9. package/dist/commands/project/pull.js +69 -0
  10. package/dist/commands/project/{sync.d.ts → push.d.ts} +1 -2
  11. package/dist/commands/project/{sync.js → push.js} +8 -44
  12. package/dist/commands/snippet/publish.js +1 -1
  13. package/dist/commands/status.js +6 -2
  14. package/dist/commands/telemetry/disable.d.ts +6 -0
  15. package/dist/commands/telemetry/disable.js +14 -0
  16. package/dist/commands/telemetry/enable.d.ts +6 -0
  17. package/dist/commands/telemetry/enable.js +14 -0
  18. package/dist/config/auth.manager.d.ts +4 -2
  19. package/dist/config/auth.manager.js +15 -5
  20. package/dist/config/project-config.manager.d.ts +7 -2
  21. package/dist/config/project-config.manager.js +39 -10
  22. package/dist/hooks/finally.js +17 -3
  23. package/dist/hooks/init.js +8 -16
  24. package/dist/lib/local-callback-server.d.ts +3 -3
  25. package/dist/lib/local-callback-server.js +14 -4
  26. package/dist/lib/open-browser.d.ts +1 -1
  27. package/dist/lib/open-browser.js +3 -10
  28. package/dist/lib/sentry.d.ts +1 -1
  29. package/dist/lib/sentry.js +17 -8
  30. package/dist/lib/wp-authorize-flow.d.ts +15 -3
  31. package/dist/lib/wp-authorize-flow.js +31 -24
  32. package/dist/lib/wp-client.d.ts +1 -1
  33. package/dist/lib/wp-client.js +1 -1
  34. package/dist/types/config.d.ts +1 -1
  35. package/dist/types/global-config.generated.d.ts +13 -3
  36. package/dist/types/plugin.d.ts +4 -5
  37. package/dist/types/project-config.generated.d.ts +1 -4
  38. package/dist/utils/plugins.d.ts +3 -7
  39. package/dist/utils/plugins.js +27 -13
  40. package/oclif.manifest.json +236 -169
  41. package/package.json +6 -2
  42. package/schemas/global-config.schema.json +19 -3
  43. package/schemas/project-config.schema.json +3 -4
package/README.md CHANGED
@@ -21,7 +21,7 @@ $ npm install -g @loopress/cli
21
21
  $ lps COMMAND
22
22
  running command...
23
23
  $ lps (--version)
24
- @loopress/cli/0.13.0 linux-x64 node-v24.18.0
24
+ @loopress/cli/0.15.0 linux-x64 node-v24.18.0
25
25
  $ lps --help [COMMAND]
26
26
  USAGE
27
27
  $ lps COMMAND
@@ -35,8 +35,9 @@ Loopress sends crash reports to our Sentry project so we can find and fix bugs.
35
35
 
36
36
  To opt out, either:
37
37
 
38
- - set `LOOPRESS_TELEMETRY_DISABLED=1`, or
39
- - pass `--no-error-reporting` on the command.
38
+ - run `lps telemetry disable` (persists across all future commands), or
39
+ - set `LOOPRESS_TELEMETRY_DISABLED=1` (overrides the persisted preference for a single run,
40
+ useful in CI).
40
41
 
41
42
  A crash report includes the command name, its flags/args as typed, your Node.js
42
43
  version, and OS. WordPress credentials are configured via `lps project config`
@@ -52,19 +53,22 @@ report.
52
53
  * [`lps init`](#lps-init)
53
54
  * [`lps login`](#lps-login)
54
55
  * [`lps logout`](#lps-logout)
55
- * [`lps plugin add SLUG [VERSION]`](#lps-plugin-add-slug-version)
56
+ * [`lps plugin add SLUG`](#lps-plugin-add-slug)
56
57
  * [`lps plugin pull`](#lps-plugin-pull)
57
58
  * [`lps plugin push`](#lps-plugin-push)
58
59
  * [`lps project config`](#lps-project-config)
59
60
  * [`lps project list`](#lps-project-list)
61
+ * [`lps project pull`](#lps-project-pull)
62
+ * [`lps project push`](#lps-project-push)
60
63
  * [`lps project remove`](#lps-project-remove)
61
64
  * [`lps project switch`](#lps-project-switch)
62
- * [`lps project sync`](#lps-project-sync)
63
65
  * [`lps snippet list`](#lps-snippet-list)
64
66
  * [`lps snippet publish [PATH]`](#lps-snippet-publish-path)
65
67
  * [`lps snippet pull [PATH]`](#lps-snippet-pull-path)
66
68
  * [`lps snippet push [PATH]`](#lps-snippet-push-path)
67
69
  * [`lps status`](#lps-status)
70
+ * [`lps telemetry disable`](#lps-telemetry-disable)
71
+ * [`lps telemetry enable`](#lps-telemetry-enable)
68
72
 
69
73
  ## `lps composer pull`
70
74
 
@@ -86,7 +90,7 @@ EXAMPLES
86
90
  $ lps composer pull --dry-run
87
91
  ```
88
92
 
89
- _See code: [src/commands/composer/pull.ts](https://github.com/loopress/loopress/blob/v0.13.0/src/commands/composer/pull.ts)_
93
+ _See code: [src/commands/composer/pull.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/composer/pull.ts)_
90
94
 
91
95
  ## `lps composer push`
92
96
 
@@ -108,7 +112,7 @@ EXAMPLES
108
112
  $ lps composer push --dry-run
109
113
  ```
110
114
 
111
- _See code: [src/commands/composer/push.ts](https://github.com/loopress/loopress/blob/v0.13.0/src/commands/composer/push.ts)_
115
+ _See code: [src/commands/composer/push.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/composer/push.ts)_
112
116
 
113
117
  ## `lps help [COMMAND]`
114
118
 
@@ -145,7 +149,7 @@ EXAMPLES
145
149
  $ lps init
146
150
  ```
147
151
 
148
- _See code: [src/commands/init.ts](https://github.com/loopress/loopress/blob/v0.13.0/src/commands/init.ts)_
152
+ _See code: [src/commands/init.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/init.ts)_
149
153
 
150
154
  ## `lps login`
151
155
 
@@ -162,7 +166,7 @@ EXAMPLES
162
166
  $ lps login
163
167
  ```
164
168
 
165
- _See code: [src/commands/login.ts](https://github.com/loopress/loopress/blob/v0.13.0/src/commands/login.ts)_
169
+ _See code: [src/commands/login.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/login.ts)_
166
170
 
167
171
  ## `lps logout`
168
172
 
@@ -179,19 +183,18 @@ EXAMPLES
179
183
  $ lps logout
180
184
  ```
181
185
 
182
- _See code: [src/commands/logout.ts](https://github.com/loopress/loopress/blob/v0.13.0/src/commands/logout.ts)_
186
+ _See code: [src/commands/logout.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/logout.ts)_
183
187
 
184
- ## `lps plugin add SLUG [VERSION]`
188
+ ## `lps plugin add SLUG`
185
189
 
186
190
  Add a WordPress.org plugin to loopress.json
187
191
 
188
192
  ```
189
193
  USAGE
190
- $ lps plugin add SLUG [VERSION] [-d]
194
+ $ lps plugin add SLUG [-d]
191
195
 
192
196
  ARGUMENTS
193
- SLUG Plugin slug on WordPress.org
194
- [VERSION] Version to pin (default: latest)
197
+ SLUG Plugin slug on WordPress.org
195
198
 
196
199
  FLAGS
197
200
  -d, --dry-run Show what would change without making changes
@@ -202,12 +205,10 @@ DESCRIPTION
202
205
  EXAMPLES
203
206
  $ lps plugin add woocommerce
204
207
 
205
- $ lps plugin add woocommerce 8.9.1
206
-
207
208
  $ lps plugin add contact-form-7 --dry-run
208
209
  ```
209
210
 
210
- _See code: [src/commands/plugin/add.ts](https://github.com/loopress/loopress/blob/v0.13.0/src/commands/plugin/add.ts)_
211
+ _See code: [src/commands/plugin/add.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/plugin/add.ts)_
211
212
 
212
213
  ## `lps plugin pull`
213
214
 
@@ -229,7 +230,7 @@ EXAMPLES
229
230
  $ lps plugin pull --dry-run
230
231
  ```
231
232
 
232
- _See code: [src/commands/plugin/pull.ts](https://github.com/loopress/loopress/blob/v0.13.0/src/commands/plugin/pull.ts)_
233
+ _See code: [src/commands/plugin/pull.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/plugin/pull.ts)_
233
234
 
234
235
  ## `lps plugin push`
235
236
 
@@ -251,7 +252,7 @@ EXAMPLES
251
252
  $ lps plugin push --dry-run
252
253
  ```
253
254
 
254
- _See code: [src/commands/plugin/push.ts](https://github.com/loopress/loopress/blob/v0.13.0/src/commands/plugin/push.ts)_
255
+ _See code: [src/commands/plugin/push.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/plugin/push.ts)_
255
256
 
256
257
  ## `lps project config`
257
258
 
@@ -269,7 +270,7 @@ EXAMPLES
269
270
  $ lps project config
270
271
  ```
271
272
 
272
- _See code: [src/commands/project/config.ts](https://github.com/loopress/loopress/blob/v0.13.0/src/commands/project/config.ts)_
273
+ _See code: [src/commands/project/config.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/project/config.ts)_
273
274
 
274
275
  ## `lps project list`
275
276
 
@@ -286,58 +287,75 @@ EXAMPLES
286
287
  $ lps project list
287
288
  ```
288
289
 
289
- _See code: [src/commands/project/list.ts](https://github.com/loopress/loopress/blob/v0.13.0/src/commands/project/list.ts)_
290
+ _See code: [src/commands/project/list.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/project/list.ts)_
290
291
 
291
- ## `lps project remove`
292
+ ## `lps project pull`
292
293
 
293
- Remove one or more WordPress projects or environments
294
+ Pull projects and environments from your Loopress account that are not configured locally yet
294
295
 
295
296
  ```
296
297
  USAGE
297
- $ lps project remove
298
+ $ lps project pull
298
299
 
299
300
  DESCRIPTION
300
- Remove one or more WordPress projects or environments
301
+ Pull projects and environments from your Loopress account that are not configured locally yet
301
302
 
302
303
  EXAMPLES
303
- $ lps project remove
304
+ $ lps project pull
304
305
  ```
305
306
 
306
- _See code: [src/commands/project/remove.ts](https://github.com/loopress/loopress/blob/v0.13.0/src/commands/project/remove.ts)_
307
+ _See code: [src/commands/project/pull.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/project/pull.ts)_
307
308
 
308
- ## `lps project switch`
309
+ ## `lps project push`
309
310
 
310
- Switch the active project and environment
311
+ Push locally configured projects, environments and credentials to your Loopress account
311
312
 
312
313
  ```
313
314
  USAGE
314
- $ lps project switch
315
+ $ lps project push
315
316
 
316
317
  DESCRIPTION
317
- Switch the active project and environment
318
+ Push locally configured projects, environments and credentials to your Loopress account
318
319
 
319
320
  EXAMPLES
320
- $ lps project switch
321
+ $ lps project push
322
+ ```
323
+
324
+ _See code: [src/commands/project/push.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/project/push.ts)_
325
+
326
+ ## `lps project remove`
327
+
328
+ Remove one or more WordPress projects or environments
329
+
330
+ ```
331
+ USAGE
332
+ $ lps project remove
333
+
334
+ DESCRIPTION
335
+ Remove one or more WordPress projects or environments
336
+
337
+ EXAMPLES
338
+ $ lps project remove
321
339
  ```
322
340
 
323
- _See code: [src/commands/project/switch.ts](https://github.com/loopress/loopress/blob/v0.13.0/src/commands/project/switch.ts)_
341
+ _See code: [src/commands/project/remove.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/project/remove.ts)_
324
342
 
325
- ## `lps project sync`
343
+ ## `lps project switch`
326
344
 
327
- Sync locally configured projects and environments with your Loopress account
345
+ Switch the active project and environment
328
346
 
329
347
  ```
330
348
  USAGE
331
- $ lps project sync
349
+ $ lps project switch
332
350
 
333
351
  DESCRIPTION
334
- Sync locally configured projects and environments with your Loopress account
352
+ Switch the active project and environment
335
353
 
336
354
  EXAMPLES
337
- $ lps project sync
355
+ $ lps project switch
338
356
  ```
339
357
 
340
- _See code: [src/commands/project/sync.ts](https://github.com/loopress/loopress/blob/v0.13.0/src/commands/project/sync.ts)_
358
+ _See code: [src/commands/project/switch.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/project/switch.ts)_
341
359
 
342
360
  ## `lps snippet list`
343
361
 
@@ -357,7 +375,7 @@ EXAMPLES
357
375
  $ lps snippet list
358
376
  ```
359
377
 
360
- _See code: [src/commands/snippet/list.ts](https://github.com/loopress/loopress/blob/v0.13.0/src/commands/snippet/list.ts)_
378
+ _See code: [src/commands/snippet/list.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/snippet/list.ts)_
361
379
 
362
380
  ## `lps snippet publish [PATH]`
363
381
 
@@ -380,7 +398,7 @@ EXAMPLES
380
398
  $ lps snippet publish --path ./snippets
381
399
  ```
382
400
 
383
- _See code: [src/commands/snippet/publish.ts](https://github.com/loopress/loopress/blob/v0.13.0/src/commands/snippet/publish.ts)_
401
+ _See code: [src/commands/snippet/publish.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/snippet/publish.ts)_
384
402
 
385
403
  ## `lps snippet pull [PATH]`
386
404
 
@@ -405,7 +423,7 @@ EXAMPLES
405
423
  $ lps snippet pull --path ./snippets
406
424
  ```
407
425
 
408
- _See code: [src/commands/snippet/pull.ts](https://github.com/loopress/loopress/blob/v0.13.0/src/commands/snippet/pull.ts)_
426
+ _See code: [src/commands/snippet/pull.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/snippet/pull.ts)_
409
427
 
410
428
  ## `lps snippet push [PATH]`
411
429
 
@@ -431,7 +449,7 @@ EXAMPLES
431
449
  $ lps snippet push --path ./snippets
432
450
  ```
433
451
 
434
- _See code: [src/commands/snippet/push.ts](https://github.com/loopress/loopress/blob/v0.13.0/src/commands/snippet/push.ts)_
452
+ _See code: [src/commands/snippet/push.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/snippet/push.ts)_
435
453
 
436
454
  ## `lps status`
437
455
 
@@ -448,5 +466,39 @@ EXAMPLES
448
466
  $ lps status
449
467
  ```
450
468
 
451
- _See code: [src/commands/status.ts](https://github.com/loopress/loopress/blob/v0.13.0/src/commands/status.ts)_
469
+ _See code: [src/commands/status.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/status.ts)_
470
+
471
+ ## `lps telemetry disable`
472
+
473
+ Disable error reporting to Sentry
474
+
475
+ ```
476
+ USAGE
477
+ $ lps telemetry disable
478
+
479
+ DESCRIPTION
480
+ Disable error reporting to Sentry
481
+
482
+ EXAMPLES
483
+ $ lps telemetry disable
484
+ ```
485
+
486
+ _See code: [src/commands/telemetry/disable.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/telemetry/disable.ts)_
487
+
488
+ ## `lps telemetry enable`
489
+
490
+ Enable error reporting to Sentry
491
+
492
+ ```
493
+ USAGE
494
+ $ lps telemetry enable
495
+
496
+ DESCRIPTION
497
+ Enable error reporting to Sentry
498
+
499
+ EXAMPLES
500
+ $ lps telemetry enable
501
+ ```
502
+
503
+ _See code: [src/commands/telemetry/enable.ts](https://github.com/loopress/loopress/blob/v0.15.0/src/commands/telemetry/enable.ts)_
452
504
  <!-- commandsstop -->
@@ -3,7 +3,7 @@ import { Command } from '@oclif/core';
3
3
  import { existsSync } from 'node:fs';
4
4
  import { join } from 'node:path';
5
5
  import { configManager } from '../config/project-config.manager.js';
6
- import { readLocalConfig, writeLocalConfig } from '../utils/loopress-config.js';
6
+ import { writeLocalConfig } from '../utils/loopress-config.js';
7
7
  // WordPress.org slugs for the two snippet plugins the Loopress WordPress plugin supports
8
8
  // (see SnippetModule.php, which wires up both providers and auto-detects the active one).
9
9
  const SNIPPET_PROVIDERS = [
@@ -76,11 +76,11 @@ export default class Init extends Command {
76
76
  snippetsDir,
77
77
  };
78
78
  await writeLocalConfig(config);
79
- let providerVersion;
79
+ let providerAdded = false;
80
80
  if (providerChoice !== '__none__') {
81
81
  try {
82
82
  await this.config.runCommand('plugin:add', [providerChoice]);
83
- providerVersion = (await readLocalConfig()).plugins?.[providerChoice];
83
+ providerAdded = true;
84
84
  }
85
85
  catch (error) {
86
86
  this.warn(error.message);
@@ -89,8 +89,8 @@ export default class Init extends Command {
89
89
  this.log(`\n✓ loopress.json created`);
90
90
  this.log(` Project: ${projectLabel}`);
91
91
  this.log(` Snippets: ${join(rootDir, snippetsDir)}`);
92
- if (providerChoice !== '__none__' && providerVersion) {
93
- this.log(` Plugin: ${providerChoice}@${providerVersion}`);
92
+ if (providerAdded) {
93
+ this.log(` Plugin: ${providerChoice}`);
94
94
  }
95
95
  }
96
96
  }
@@ -1,9 +1,7 @@
1
1
  import { LoopressCommand } from '../../lib/base.js';
2
- export declare function resolvePluginVersion(slug: string, version: string): Promise<string>;
3
2
  export default class Add extends LoopressCommand {
4
3
  static args: {
5
4
  slug: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
6
- version: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
7
5
  };
8
6
  static description: string;
9
7
  static examples: string[];
@@ -1,73 +1,32 @@
1
1
  import { Args } from '@oclif/core';
2
- import got from 'got';
3
2
  import { LoopressCommand } from '../../lib/base.js';
4
3
  import { writeLocalConfig } from '../../utils/loopress-config.js';
5
- const WP_ORG_API = 'https://api.wordpress.org/plugins/info/1.2/';
6
- const WP_ORG_TIMEOUT_MS = 10_000;
7
- export async function resolvePluginVersion(slug, version) {
8
- if (version !== 'latest')
9
- return version;
10
- let info;
11
- try {
12
- info = await got
13
- .get(WP_ORG_API, {
14
- searchParams: {
15
- action: 'plugin_information',
16
- 'request[slug]': slug,
17
- },
18
- timeout: { request: WP_ORG_TIMEOUT_MS },
19
- })
20
- .json();
21
- }
22
- catch {
23
- throw new Error(`Plugin "${slug}" not found on WordPress.org.`);
24
- }
25
- if (info.error)
26
- throw new Error(`Plugin "${slug}" not found on WordPress.org.`);
27
- return info.version;
28
- }
29
4
  export default class Add extends LoopressCommand {
30
5
  static args = {
31
6
  slug: Args.string({ description: 'Plugin slug on WordPress.org', required: true }),
32
- version: Args.string({ description: 'Version to pin (default: latest)' }),
33
7
  };
34
8
  static description = 'Add a WordPress.org plugin to loopress.json';
35
- static examples = [
36
- '$ lps plugin add woocommerce',
37
- '$ lps plugin add woocommerce 8.9.1',
38
- '$ lps plugin add contact-form-7 --dry-run',
39
- ];
9
+ static examples = ['$ lps plugin add woocommerce', '$ lps plugin add contact-form-7 --dry-run'];
40
10
  static flags = {
41
11
  ...LoopressCommand.dryRunFlag,
42
12
  };
43
13
  async run() {
44
14
  const { args } = await this.parse(Add);
45
15
  const { slug } = args;
46
- const requestedVersion = args.version ?? 'latest';
47
- this.log(`Resolving ${slug}@${requestedVersion}...`);
48
- let resolvedVersion;
49
- try {
50
- resolvedVersion = await resolvePluginVersion(slug, requestedVersion);
51
- }
52
- catch (error) {
53
- this.error(error.message);
54
- }
55
- this.log(`Resolved: ${slug}@${resolvedVersion}`);
56
16
  const existing = this.localConfig.plugins ?? {};
57
- if (existing[slug] === resolvedVersion) {
58
- this.log(`${slug}@${resolvedVersion} is already in loopress.json, nothing to do.`);
17
+ if (existing[slug] === 'latest') {
18
+ this.log(`${slug} is already in loopress.json, nothing to do.`);
59
19
  return;
60
20
  }
61
21
  const updated = existing[slug] !== undefined;
62
- const label = updated ? `${existing[slug]} → ${resolvedVersion}` : resolvedVersion;
63
22
  if (this.dryRun) {
64
- this.log(`[dry-run] Would ${updated ? 'update' : 'add'} ${slug}: ${label}`);
23
+ this.log(`[dry-run] Would ${updated ? 'update' : 'add'} ${slug} in loopress.json`);
65
24
  return;
66
25
  }
67
26
  await writeLocalConfig({
68
27
  ...this.localConfig,
69
- plugins: { ...existing, [slug]: resolvedVersion },
28
+ plugins: { ...existing, [slug]: 'latest' },
70
29
  });
71
- this.log(`${updated ? 'Updated' : 'Added'} ${slug}: ${label}`);
30
+ this.log(`${updated ? 'Updated' : 'Added'} ${slug}`);
72
31
  }
73
32
  }
@@ -1,7 +1,7 @@
1
1
  import { LoopressCommand } from '../../lib/base.js';
2
2
  import { getComposerManagedSlugs, readComposerJson } from '../../utils/composer.js';
3
3
  import { writeLocalConfig } from '../../utils/loopress-config.js';
4
- import { mergePluginManifest } from '../../utils/plugins.js';
4
+ import { mergePluginManifest, parseInstalledPlugins } from '../../utils/plugins.js';
5
5
  export default class Pull extends LoopressCommand {
6
6
  static description = 'Pull installed plugins from WordPress into loopress.json';
7
7
  static examples = ['$ lps plugin pull', '$ lps plugin pull --dry-run'];
@@ -11,10 +11,11 @@ export default class Pull extends LoopressCommand {
11
11
  async run() {
12
12
  const { url } = this.siteConfig;
13
13
  this.log(`Pulling plugins from ${url}`);
14
- const installed = await this.wp.get('loopress/v1/plugins');
14
+ const raw = await this.wp.get('wp/v2/plugins');
15
+ const installed = parseInstalledPlugins(raw);
15
16
  const composerJson = await readComposerJson();
16
17
  const composerSlugs = composerJson ? getComposerManagedSlugs(composerJson) : [];
17
- const incoming = Object.fromEntries(installed.filter((p) => !composerSlugs.includes(p.slug)).map((p) => [p.slug, p.version]));
18
+ const incoming = Object.fromEntries(installed.filter((p) => !composerSlugs.includes(p.slug)).map((p) => [p.slug, 'latest']));
18
19
  if (composerSlugs.length > 0) {
19
20
  const found = installed.filter((p) => composerSlugs.includes(p.slug)).map((p) => p.slug);
20
21
  if (found.length > 0) {
@@ -38,8 +39,5 @@ export default class Pull extends LoopressCommand {
38
39
  this.log(` + Added: ${added.join(', ')}`);
39
40
  for (const u of updated)
40
41
  this.log(` ~ Updated: ${u.slug} ${u.from} → ${u.to}`);
41
- if (Object.keys(merged).length > 0) {
42
- await this.wp.post('loopress/v1/plugins/auto-updates/disable', { slugs: Object.keys(merged) });
43
- }
44
42
  }
45
43
  }
@@ -8,7 +8,6 @@ export default class Push extends PushCommand {
8
8
  private failedCount;
9
9
  run(): Promise<void>;
10
10
  private activatePlugin;
11
- private installAndActivate;
11
+ private installPlugin;
12
12
  private performPluginAction;
13
- private syncDrifted;
14
13
  }
@@ -1,8 +1,7 @@
1
- import { confirm } from '@inquirer/prompts';
2
1
  import { Listr } from 'listr2';
3
2
  import { PushCommand } from '../../lib/push-command.js';
4
3
  import { getComposerManagedSlugs, readComposerJson } from '../../utils/composer.js';
5
- import { diffPlugins } from '../../utils/plugins.js';
4
+ import { diffPlugins, parseInstalledPlugins } from '../../utils/plugins.js';
6
5
  export default class Push extends PushCommand {
7
6
  static description = 'Push plugins to WordPress to match loopress.json';
8
7
  static examples = ['$ lps plugin push', '$ lps plugin push --dry-run'];
@@ -25,45 +24,39 @@ export default class Push extends PushCommand {
25
24
  this.log('Run `lps composer push` to deploy them.');
26
25
  }
27
26
  this.log(`Pushing plugins to ${url}`);
28
- const installed = await this.wp.get('loopress/v1/plugins');
29
- const { drifted, toActivate, toInstall } = diffPlugins(filteredManifest, installed);
30
- if (toInstall.length === 0 && toActivate.length === 0 && drifted.length === 0) {
27
+ const raw = await this.wp.get('wp/v2/plugins');
28
+ const installed = parseInstalledPlugins(raw);
29
+ const { toActivate, toInstall } = diffPlugins(filteredManifest, installed);
30
+ if (toInstall.length === 0 && toActivate.length === 0) {
31
31
  this.log('Everything is already in sync.');
32
32
  return;
33
33
  }
34
34
  if (toInstall.length > 0) {
35
35
  this.log(`\nTo install (${toInstall.length}):`);
36
36
  for (const a of toInstall)
37
- this.log(` + ${a.slug} @ ${a.targetVersion}`);
37
+ this.log(` + ${a.slug}`);
38
38
  }
39
39
  if (toActivate.length > 0) {
40
40
  this.log(`\nTo activate (${toActivate.length}):`);
41
41
  for (const a of toActivate)
42
42
  this.log(` ↑ ${a.slug}`);
43
43
  }
44
- if (drifted.length > 0) {
45
- this.log(`\nVersion mismatch (${drifted.length}):`);
46
- for (const a of drifted) {
47
- this.log(` ~ ${a.slug}: site has ${a.currentVersion}, manifest wants ${a.targetVersion}`);
48
- }
49
- }
50
44
  if (this.dryRun)
51
45
  return;
52
- // Install missing plugins and activate them.
46
+ // Installing with `status: active` activates in the same call, so installs never need a
47
+ // separate activation step the way the old custom endpoint's two-step flow did.
53
48
  if (toInstall.length > 0) {
54
49
  await new Listr(toInstall.map((action) => ({
55
- task: async (_ctx, task) => this.installAndActivate(action.slug, action.targetVersion, task),
56
- title: `Install ${action.slug} @ ${action.targetVersion}`,
50
+ task: async (_ctx, task) => this.installPlugin(action.slug, task),
51
+ title: `Install ${action.slug}`,
57
52
  })), { concurrent: false, exitOnError: false }).run();
58
53
  }
59
- // Activate installed-but-inactive plugins without prompting.
60
54
  if (toActivate.length > 0) {
61
55
  await new Listr(toActivate.map((action) => ({
62
- task: async (_ctx, task) => this.activatePlugin(action.slug, task),
56
+ task: async (_ctx, task) => this.activatePlugin(action.file, action.slug, task),
63
57
  title: `Activate ${action.slug}`,
64
58
  })), { concurrent: false, exitOnError: false }).run();
65
59
  }
66
- await this.syncDrifted(drifted);
67
60
  if (this.failedCount > 0) {
68
61
  this.error(`${this.failedCount} plugin${this.failedCount === 1 ? '' : 's'} failed to install or activate.`);
69
62
  }
@@ -75,18 +68,16 @@ export default class Push extends PushCommand {
75
68
  // it falls back to plain logging. Rethrowing on failure (rather than swallowing) is what lets Listr
76
69
  // mark the task as failed (red cross) instead of completed, even though `exitOnError: false` stops
77
70
  // that failure from aborting sibling tasks in the same list.
78
- async activatePlugin(slug, task) {
79
- await this.performPluginAction('activate', { body: { slug }, endpoint: 'loopress/v1/plugins/activate', slug }, task);
71
+ async activatePlugin(file, slug, task) {
72
+ await this.performPluginAction('activate', slug, () => this.wp.put(`wp/v2/plugins/${file}`, { status: 'active' }), task);
80
73
  }
81
- async installAndActivate(slug, version, task) {
82
- await this.performPluginAction('install', { body: { slug, version }, endpoint: 'loopress/v1/plugins/install', slug }, task);
83
- await this.activatePlugin(slug, task);
74
+ async installPlugin(slug, task) {
75
+ await this.performPluginAction('install', slug, () => this.wp.post('wp/v2/plugins', { slug, status: 'active' }), task);
84
76
  }
85
- async performPluginAction(verb, request, task) {
86
- const { body, endpoint, slug } = request;
77
+ async performPluginAction(verb, slug, request, task) {
87
78
  try {
88
- const result = await this.wp.post(endpoint, body);
89
- const message = `✓ ${result.message}`;
79
+ await request();
80
+ const message = `✓ ${slug} ${verb === 'install' ? 'installed and activated' : 'activated'}`;
90
81
  if (task)
91
82
  task.output = message;
92
83
  else
@@ -102,27 +93,4 @@ export default class Push extends PushCommand {
102
93
  throw error;
103
94
  }
104
95
  }
105
- // Prompt per drifted plugin before syncing. Prompts run sequentially on plain stdout,
106
- // before the Listr renderer takes over the terminal for the confirmed subset.
107
- async syncDrifted(drifted) {
108
- const confirmedDrift = [];
109
- for (const action of drifted) {
110
- const proceed = await confirm({
111
- default: false,
112
- message: `${action.slug} is at ${action.currentVersion} on the site but manifest wants ${action.targetVersion}. Sync to ${action.targetVersion}?`,
113
- });
114
- if (proceed) {
115
- confirmedDrift.push(action);
116
- }
117
- else {
118
- this.log(` Skipped ${action.slug}`);
119
- }
120
- }
121
- if (confirmedDrift.length === 0)
122
- return;
123
- await new Listr(confirmedDrift.map((action) => ({
124
- task: async (_ctx, task) => this.installAndActivate(action.slug, action.targetVersion, task),
125
- title: `Sync ${action.slug} to ${action.targetVersion}`,
126
- })), { concurrent: false, exitOnError: false }).run();
127
- }
128
96
  }
@@ -0,0 +1,8 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Pull extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ run(): Promise<void>;
6
+ private fetchApiProjects;
7
+ private pullProject;
8
+ }