@loopress/cli 0.17.0 → 0.18.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/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # Loopress
2
2
 
3
- A new CLI generated with oclif
3
+ CLI to interact with the Loopress ecosystem
4
4
 
5
5
  [![oclif](https://img.shields.io/badge/cli-oclif-brightgreen.svg)](https://oclif.io)
6
- [![Version](https://img.shields.io/npm/v/mynewcli.svg)](https://npmjs.org/package/mynewcli)
7
- [![Downloads/week](https://img.shields.io/npm/dw/mynewcli.svg)](https://npmjs.org/package/mynewcli)
6
+ [![Version](https://img.shields.io/npm/v/@loopress/cli.svg)](https://www.npmjs.com/package/@loopress/cli)
7
+ [![Downloads/week](https://img.shields.io/npm/dw/@loopress/cli.svg)](https://npmjs.org/package/@loopress/cli)
8
8
 
9
9
  <!-- toc -->
10
10
  * [Loopress](#loopress)
@@ -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.17.0 linux-x64 node-v24.18.0
24
+ @loopress/cli/0.18.0 linux-x64 node-v24.18.0
25
25
  $ lps --help [COMMAND]
26
26
  USAGE
27
27
  $ lps COMMAND
@@ -50,9 +50,15 @@ report.
50
50
  * [`lps acf list`](#lps-acf-list)
51
51
  * [`lps acf pull [PATH]`](#lps-acf-pull-path)
52
52
  * [`lps acf push [PATH]`](#lps-acf-push-path)
53
+ * [`lps api list`](#lps-api-list)
54
+ * [`lps api pull [PATH]`](#lps-api-pull-path)
55
+ * [`lps api push [PATH]`](#lps-api-push-path)
53
56
  * [`lps composer init`](#lps-composer-init)
54
57
  * [`lps composer pull`](#lps-composer-pull)
55
58
  * [`lps composer push`](#lps-composer-push)
59
+ * [`lps form list`](#lps-form-list)
60
+ * [`lps form pull [PATH]`](#lps-form-pull-path)
61
+ * [`lps form push [PATH]`](#lps-form-push-path)
56
62
  * [`lps help [COMMAND]`](#lps-help-command)
57
63
  * [`lps init`](#lps-init)
58
64
  * [`lps login`](#lps-login)
@@ -99,7 +105,7 @@ EXAMPLES
99
105
  $ lps acf list --type field-groups
100
106
  ```
101
107
 
102
- _See code: [src/commands/acf/list.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/acf/list.ts)_
108
+ _See code: [src/commands/acf/list.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/acf/list.ts)_
103
109
 
104
110
  ## `lps acf pull [PATH]`
105
111
 
@@ -126,7 +132,7 @@ EXAMPLES
126
132
  $ lps acf pull --type field-groups
127
133
  ```
128
134
 
129
- _See code: [src/commands/acf/pull.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/acf/pull.ts)_
135
+ _See code: [src/commands/acf/pull.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/acf/pull.ts)_
130
136
 
131
137
  ## `lps acf push [PATH]`
132
138
 
@@ -153,7 +159,77 @@ EXAMPLES
153
159
  $ lps acf push --type field-groups
154
160
  ```
155
161
 
156
- _See code: [src/commands/acf/push.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/acf/push.ts)_
162
+ _See code: [src/commands/acf/push.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/acf/push.ts)_
163
+
164
+ ## `lps api list`
165
+
166
+ List custom API route files from WordPress
167
+
168
+ ```
169
+ USAGE
170
+ $ lps api list [-j]
171
+
172
+ FLAGS
173
+ -j, --json Output in JSON format
174
+
175
+ DESCRIPTION
176
+ List custom API route files from WordPress
177
+
178
+ EXAMPLES
179
+ $ lps api list
180
+ ```
181
+
182
+ _See code: [src/commands/api/list.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/api/list.ts)_
183
+
184
+ ## `lps api pull [PATH]`
185
+
186
+ Pull custom API route files from WordPress
187
+
188
+ ```
189
+ USAGE
190
+ $ lps api pull [PATH] [-d]
191
+
192
+ ARGUMENTS
193
+ [PATH] Path to api directory (overrides project config)
194
+
195
+ FLAGS
196
+ -d, --dry-run Show what would change without making changes
197
+
198
+ DESCRIPTION
199
+ Pull custom API route files from WordPress
200
+
201
+ EXAMPLES
202
+ $ lps api pull
203
+
204
+ $ lps api pull --path ./api
205
+ ```
206
+
207
+ _See code: [src/commands/api/pull.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/api/pull.ts)_
208
+
209
+ ## `lps api push [PATH]`
210
+
211
+ Push custom API route files to WordPress
212
+
213
+ ```
214
+ USAGE
215
+ $ lps api push [PATH] [-d]
216
+
217
+ ARGUMENTS
218
+ [PATH] Path to api directory (overrides project config)
219
+
220
+ FLAGS
221
+ -d, --dry-run Show what would change without making changes
222
+
223
+ DESCRIPTION
224
+ Push custom API route files to WordPress
225
+
226
+ EXAMPLES
227
+ $ lps api push
228
+
229
+ $ lps api push --path ./api
230
+ ```
231
+
232
+ _See code: [src/commands/api/push.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/api/push.ts)_
157
233
 
158
234
  ## `lps composer init`
159
235
 
@@ -175,7 +251,7 @@ EXAMPLES
175
251
  $ lps composer init --dry-run
176
252
  ```
177
253
 
178
- _See code: [src/commands/composer/init.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/composer/init.ts)_
254
+ _See code: [src/commands/composer/init.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/composer/init.ts)_
179
255
 
180
256
  ## `lps composer pull`
181
257
 
@@ -197,7 +273,7 @@ EXAMPLES
197
273
  $ lps composer pull --dry-run
198
274
  ```
199
275
 
200
- _See code: [src/commands/composer/pull.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/composer/pull.ts)_
276
+ _See code: [src/commands/composer/pull.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/composer/pull.ts)_
201
277
 
202
278
  ## `lps composer push`
203
279
 
@@ -219,7 +295,74 @@ EXAMPLES
219
295
  $ lps composer push --dry-run
220
296
  ```
221
297
 
222
- _See code: [src/commands/composer/push.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/composer/push.ts)_
298
+ _See code: [src/commands/composer/push.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/composer/push.ts)_
299
+
300
+ ## `lps form list`
301
+
302
+ List forms from WordPress
303
+
304
+ ```
305
+ USAGE
306
+ $ lps form list [-j]
307
+
308
+ FLAGS
309
+ -j, --json Output in JSON format
310
+
311
+ DESCRIPTION
312
+ List forms from WordPress
313
+
314
+ EXAMPLES
315
+ $ lps form list
316
+ ```
317
+
318
+ _See code: [src/commands/form/list.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/form/list.ts)_
319
+
320
+ ## `lps form pull [PATH]`
321
+
322
+ Pull forms from WordPress
323
+
324
+ ```
325
+ USAGE
326
+ $ lps form pull [PATH] [-d]
327
+
328
+ ARGUMENTS
329
+ [PATH] Path to forms directory (overrides project config)
330
+
331
+ FLAGS
332
+ -d, --dry-run Show what would change without making changes
333
+
334
+ DESCRIPTION
335
+ Pull forms from WordPress
336
+
337
+ EXAMPLES
338
+ $ lps form pull
339
+ ```
340
+
341
+ _See code: [src/commands/form/pull.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/form/pull.ts)_
342
+
343
+ ## `lps form push [PATH]`
344
+
345
+ Push forms to WordPress. Local files created or updated remotely are renamed on disk to the `<id>-<slug>.json` convention.
346
+
347
+ ```
348
+ USAGE
349
+ $ lps form push [PATH] [-d]
350
+
351
+ ARGUMENTS
352
+ [PATH] Path to forms directory (overrides project config)
353
+
354
+ FLAGS
355
+ -d, --dry-run Show what would change without making changes
356
+
357
+ DESCRIPTION
358
+ Push forms to WordPress. Local files created or updated remotely are renamed on disk to the `<id>-<slug>.json`
359
+ convention.
360
+
361
+ EXAMPLES
362
+ $ lps form push
363
+ ```
364
+
365
+ _See code: [src/commands/form/push.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/form/push.ts)_
223
366
 
224
367
  ## `lps help [COMMAND]`
225
368
 
@@ -256,7 +399,7 @@ EXAMPLES
256
399
  $ lps init
257
400
  ```
258
401
 
259
- _See code: [src/commands/init.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/init.ts)_
402
+ _See code: [src/commands/init.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/init.ts)_
260
403
 
261
404
  ## `lps login`
262
405
 
@@ -273,7 +416,7 @@ EXAMPLES
273
416
  $ lps login
274
417
  ```
275
418
 
276
- _See code: [src/commands/login.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/login.ts)_
419
+ _See code: [src/commands/login.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/login.ts)_
277
420
 
278
421
  ## `lps logout`
279
422
 
@@ -290,7 +433,7 @@ EXAMPLES
290
433
  $ lps logout
291
434
  ```
292
435
 
293
- _See code: [src/commands/logout.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/logout.ts)_
436
+ _See code: [src/commands/logout.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/logout.ts)_
294
437
 
295
438
  ## `lps plugin add SLUG`
296
439
 
@@ -315,7 +458,7 @@ EXAMPLES
315
458
  $ lps plugin add contact-form-7 --dry-run
316
459
  ```
317
460
 
318
- _See code: [src/commands/plugin/add.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/plugin/add.ts)_
461
+ _See code: [src/commands/plugin/add.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/plugin/add.ts)_
319
462
 
320
463
  ## `lps plugin pull`
321
464
 
@@ -337,7 +480,7 @@ EXAMPLES
337
480
  $ lps plugin pull --dry-run
338
481
  ```
339
482
 
340
- _See code: [src/commands/plugin/pull.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/plugin/pull.ts)_
483
+ _See code: [src/commands/plugin/pull.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/plugin/pull.ts)_
341
484
 
342
485
  ## `lps plugin push`
343
486
 
@@ -359,7 +502,7 @@ EXAMPLES
359
502
  $ lps plugin push --dry-run
360
503
  ```
361
504
 
362
- _See code: [src/commands/plugin/push.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/plugin/push.ts)_
505
+ _See code: [src/commands/plugin/push.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/plugin/push.ts)_
363
506
 
364
507
  ## `lps project config`
365
508
 
@@ -377,7 +520,7 @@ EXAMPLES
377
520
  $ lps project config
378
521
  ```
379
522
 
380
- _See code: [src/commands/project/config.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/project/config.ts)_
523
+ _See code: [src/commands/project/config.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/project/config.ts)_
381
524
 
382
525
  ## `lps project list`
383
526
 
@@ -394,7 +537,7 @@ EXAMPLES
394
537
  $ lps project list
395
538
  ```
396
539
 
397
- _See code: [src/commands/project/list.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/project/list.ts)_
540
+ _See code: [src/commands/project/list.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/project/list.ts)_
398
541
 
399
542
  ## `lps project pull`
400
543
 
@@ -411,7 +554,7 @@ EXAMPLES
411
554
  $ lps project pull
412
555
  ```
413
556
 
414
- _See code: [src/commands/project/pull.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/project/pull.ts)_
557
+ _See code: [src/commands/project/pull.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/project/pull.ts)_
415
558
 
416
559
  ## `lps project push`
417
560
 
@@ -428,7 +571,7 @@ EXAMPLES
428
571
  $ lps project push
429
572
  ```
430
573
 
431
- _See code: [src/commands/project/push.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/project/push.ts)_
574
+ _See code: [src/commands/project/push.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/project/push.ts)_
432
575
 
433
576
  ## `lps project remove`
434
577
 
@@ -445,7 +588,7 @@ EXAMPLES
445
588
  $ lps project remove
446
589
  ```
447
590
 
448
- _See code: [src/commands/project/remove.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/project/remove.ts)_
591
+ _See code: [src/commands/project/remove.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/project/remove.ts)_
449
592
 
450
593
  ## `lps project switch`
451
594
 
@@ -462,7 +605,7 @@ EXAMPLES
462
605
  $ lps project switch
463
606
  ```
464
607
 
465
- _See code: [src/commands/project/switch.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/project/switch.ts)_
608
+ _See code: [src/commands/project/switch.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/project/switch.ts)_
466
609
 
467
610
  ## `lps seo list`
468
611
 
@@ -485,7 +628,7 @@ EXAMPLES
485
628
  $ lps seo list --post-type post
486
629
  ```
487
630
 
488
- _See code: [src/commands/seo/list.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/seo/list.ts)_
631
+ _See code: [src/commands/seo/list.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/seo/list.ts)_
489
632
 
490
633
  ## `lps seo pull [PATH]`
491
634
 
@@ -511,7 +654,7 @@ EXAMPLES
511
654
  $ lps seo pull --post-type post --post-type page
512
655
  ```
513
656
 
514
- _See code: [src/commands/seo/pull.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/seo/pull.ts)_
657
+ _See code: [src/commands/seo/pull.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/seo/pull.ts)_
515
658
 
516
659
  ## `lps seo push [PATH]`
517
660
 
@@ -535,7 +678,7 @@ EXAMPLES
535
678
  $ lps seo push
536
679
  ```
537
680
 
538
- _See code: [src/commands/seo/push.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/seo/push.ts)_
681
+ _See code: [src/commands/seo/push.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/seo/push.ts)_
539
682
 
540
683
  ## `lps snippet list`
541
684
 
@@ -555,7 +698,7 @@ EXAMPLES
555
698
  $ lps snippet list
556
699
  ```
557
700
 
558
- _See code: [src/commands/snippet/list.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/snippet/list.ts)_
701
+ _See code: [src/commands/snippet/list.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/snippet/list.ts)_
559
702
 
560
703
  ## `lps snippet publish [PATH]`
561
704
 
@@ -578,7 +721,7 @@ EXAMPLES
578
721
  $ lps snippet publish --path ./snippets
579
722
  ```
580
723
 
581
- _See code: [src/commands/snippet/publish.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/snippet/publish.ts)_
724
+ _See code: [src/commands/snippet/publish.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/snippet/publish.ts)_
582
725
 
583
726
  ## `lps snippet pull [PATH]`
584
727
 
@@ -603,7 +746,7 @@ EXAMPLES
603
746
  $ lps snippet pull --path ./snippets
604
747
  ```
605
748
 
606
- _See code: [src/commands/snippet/pull.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/snippet/pull.ts)_
749
+ _See code: [src/commands/snippet/pull.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/snippet/pull.ts)_
607
750
 
608
751
  ## `lps snippet push [PATH]`
609
752
 
@@ -629,7 +772,7 @@ EXAMPLES
629
772
  $ lps snippet push --path ./snippets
630
773
  ```
631
774
 
632
- _See code: [src/commands/snippet/push.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/snippet/push.ts)_
775
+ _See code: [src/commands/snippet/push.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/snippet/push.ts)_
633
776
 
634
777
  ## `lps status`
635
778
 
@@ -646,7 +789,7 @@ EXAMPLES
646
789
  $ lps status
647
790
  ```
648
791
 
649
- _See code: [src/commands/status.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/status.ts)_
792
+ _See code: [src/commands/status.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/status.ts)_
650
793
 
651
794
  ## `lps telemetry disable`
652
795
 
@@ -663,7 +806,7 @@ EXAMPLES
663
806
  $ lps telemetry disable
664
807
  ```
665
808
 
666
- _See code: [src/commands/telemetry/disable.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/telemetry/disable.ts)_
809
+ _See code: [src/commands/telemetry/disable.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/telemetry/disable.ts)_
667
810
 
668
811
  ## `lps telemetry enable`
669
812
 
@@ -680,5 +823,5 @@ EXAMPLES
680
823
  $ lps telemetry enable
681
824
  ```
682
825
 
683
- _See code: [src/commands/telemetry/enable.ts](https://github.com/loopress/loopress/blob/v0.17.0/src/commands/telemetry/enable.ts)_
826
+ _See code: [src/commands/telemetry/enable.ts](https://github.com/loopress/loopress/blob/v0.18.0/src/commands/telemetry/enable.ts)_
684
827
  <!-- commandsstop -->
@@ -0,0 +1,9 @@
1
+ import { LoopressCommand } from '../../lib/base.js';
2
+ export default class List extends LoopressCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ };
8
+ run(): Promise<void>;
9
+ }
@@ -0,0 +1,26 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { LoopressCommand } from '../../lib/base.js';
3
+ export default class List extends LoopressCommand {
4
+ static description = 'List custom API route files from WordPress';
5
+ static examples = ['$ lps api list'];
6
+ static flags = {
7
+ json: Flags.boolean({ char: 'j', description: 'Output in JSON format' }),
8
+ };
9
+ async run() {
10
+ const { flags } = await this.parse(List);
11
+ const files = await this.wp.get('loopress/v1/api-files');
12
+ if (flags.json) {
13
+ this.log(JSON.stringify(files, null, 2));
14
+ return;
15
+ }
16
+ if (files.length === 0) {
17
+ this.log('No API route files found');
18
+ return;
19
+ }
20
+ this.log(`Found ${files.length} route file${files.length === 1 ? '' : 's'}:`);
21
+ this.log('');
22
+ for (const file of files) {
23
+ this.log(` ${file.filename}`);
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,13 @@
1
+ import { LoopressCommand } from '../../lib/base.js';
2
+ export default class Pull extends LoopressCommand {
3
+ static args: {
4
+ path: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: string[];
8
+ static flags: {
9
+ 'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ };
11
+ run(): Promise<void>;
12
+ private findOrphanedFiles;
13
+ }
@@ -0,0 +1,64 @@
1
+ import { Args } from '@oclif/core';
2
+ import { Listr } from 'listr2';
3
+ import { mkdir, readdir, rm, writeFile } from 'node:fs/promises';
4
+ import { join } from 'node:path';
5
+ import { LoopressCommand } from '../../lib/base.js';
6
+ export default class Pull extends LoopressCommand {
7
+ static args = {
8
+ path: Args.string({ description: 'Path to api directory (overrides project config)' }),
9
+ };
10
+ static description = 'Pull custom API route files from WordPress';
11
+ static examples = ['$ lps api pull', '$ lps api pull --path ./api'];
12
+ static flags = {
13
+ ...LoopressCommand.dryRunFlag,
14
+ };
15
+ async run() {
16
+ const { args } = await this.parse(Pull);
17
+ const { url } = this.siteConfig;
18
+ const path = this.resolveApiPath(args.path);
19
+ this.log(`Pulling API routes from ${url}`);
20
+ this.log(`API path: ${path}`);
21
+ const files = await this.wp.get('loopress/v1/api-files');
22
+ // Files following the `<filename>.php` convention no longer present remotely belong to
23
+ // a route deleted on WordPress. Left on disk, they'd silently come back to life the next
24
+ // time `api push` runs (see obsidian/Product/Push Deletion Rules.md: push itself stays
25
+ // additive-only, but pull already cleans up locally, same as `snippet pull`).
26
+ const orphans = await this.findOrphanedFiles(path, new Set(files.map((file) => file.filename)));
27
+ if (this.dryRun) {
28
+ this.log(`[dry-run] Would pull ${files.length} route file${files.length === 1 ? '' : 's'} to ${path}`);
29
+ if (orphans.length > 0) {
30
+ this.log(`[dry-run] Would remove ${orphans.length} local file${orphans.length === 1 ? '' : 's'} whose route no longer exists on WordPress: ${orphans.join(', ')}`);
31
+ }
32
+ return;
33
+ }
34
+ await mkdir(path, { recursive: true });
35
+ await new Listr(files.map((file) => ({
36
+ async task(_ctx, task) {
37
+ await writeFile(join(path, `${file.filename}.php`), file.content);
38
+ task.output = `Pulled: ${file.filename}`;
39
+ },
40
+ title: `Pull ${file.filename}`,
41
+ }))).run();
42
+ for (const file of orphans)
43
+ await rm(join(path, file), { force: true });
44
+ if (orphans.length > 0) {
45
+ this.warn(`Removed ${orphans.length} local file${orphans.length === 1 ? '' : 's'} whose route no longer exists on WordPress: ${orphans.join(', ')}`);
46
+ }
47
+ this.log(`Pulled ${files.length} route file${files.length === 1 ? '' : 's'} to ${path}`);
48
+ }
49
+ // Only ever matches `.php` files already following the flat `<filename>.php` convention
50
+ // that `api pull`/`push` themselves produce, so a hand-created non-.php file is never at
51
+ // risk of being picked up here.
52
+ async findOrphanedFiles(path, keepFilenames) {
53
+ let entries;
54
+ try {
55
+ entries = await readdir(path);
56
+ }
57
+ catch (error) {
58
+ if (error.code === 'ENOENT')
59
+ return [];
60
+ throw error;
61
+ }
62
+ return entries.filter((entry) => entry.endsWith('.php') && !keepFilenames.has(entry.slice(0, -4)));
63
+ }
64
+ }
@@ -0,0 +1,15 @@
1
+ import { PushCommand } from '../../lib/push-command.js';
2
+ export default class Push extends PushCommand {
3
+ static args: {
4
+ path: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: string[];
8
+ static flags: {
9
+ 'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ };
11
+ private failedCount;
12
+ run(): Promise<void>;
13
+ private loadFiles;
14
+ private pushFile;
15
+ }
@@ -0,0 +1,76 @@
1
+ import { Args } from '@oclif/core';
2
+ import { Listr } from 'listr2';
3
+ import { readdir, readFile } from 'node:fs/promises';
4
+ import { extname, join } from 'node:path';
5
+ import { PushCommand } from '../../lib/push-command.js';
6
+ export default class Push extends PushCommand {
7
+ static args = {
8
+ path: Args.string({ description: 'Path to api directory (overrides project config)' }),
9
+ };
10
+ static description = 'Push custom API route files to WordPress';
11
+ static examples = ['$ lps api push', '$ lps api push --path ./api'];
12
+ static flags = {
13
+ ...PushCommand.dryRunFlag,
14
+ };
15
+ failedCount = 0;
16
+ async run() {
17
+ const { args } = await this.parse(Push);
18
+ const { url } = this.siteConfig;
19
+ const path = this.resolveApiPath(args.path);
20
+ this.log(`Pushing API routes to ${url}`);
21
+ this.log(`API path: ${path}`);
22
+ const files = await this.loadFiles(path);
23
+ this.log(`Found ${files.length} route file${files.length === 1 ? '' : 's'} to push`);
24
+ await new Listr(files.map((file) => ({
25
+ task: async (_ctx, task) => this.pushFile(file, task),
26
+ title: `Push ${file.filename}`,
27
+ })), { concurrent: false, exitOnError: false }).run();
28
+ if (this.failedCount > 0) {
29
+ this.error(`${this.failedCount} route file${this.failedCount === 1 ? '' : 's'} failed to push.`);
30
+ }
31
+ if (this.dryRun)
32
+ return;
33
+ await this.recordSuccess();
34
+ this.log('All API routes pushed.');
35
+ }
36
+ async loadFiles(path) {
37
+ let entries;
38
+ try {
39
+ entries = await readdir(path);
40
+ }
41
+ catch (error) {
42
+ if (error.code === 'ENOENT')
43
+ return [];
44
+ throw error;
45
+ }
46
+ const files = [];
47
+ for (const entry of entries) {
48
+ if (extname(entry) !== '.php')
49
+ continue;
50
+ const content = await readFile(join(path, entry), 'utf8');
51
+ files.push({ content, filename: entry.slice(0, -4) });
52
+ }
53
+ return files;
54
+ }
55
+ async pushFile(file, task) {
56
+ if (this.dryRun) {
57
+ if (task)
58
+ task.output = `[dry-run] Would push: ${file.filename}`;
59
+ return;
60
+ }
61
+ try {
62
+ await this.wp.put(`loopress/v1/api-files/${file.filename}`, { content: file.content });
63
+ if (task)
64
+ task.output = `Pushed: ${file.filename}`;
65
+ }
66
+ catch (error) {
67
+ const message = `Failed to push ${file.filename}: ${error.message}`;
68
+ if (task)
69
+ task.output = message;
70
+ else
71
+ this.warn(` ${message}`);
72
+ this.failedCount++;
73
+ throw error;
74
+ }
75
+ }
76
+ }
@@ -0,0 +1,9 @@
1
+ import { LoopressCommand } from '../../lib/base.js';
2
+ export default class List extends LoopressCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
+ };
8
+ run(): Promise<void>;
9
+ }
@@ -0,0 +1,26 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { LoopressCommand } from '../../lib/base.js';
3
+ import { FORM_ENDPOINT, getFormId, getFormTitle } from '../../utils/form-format.js';
4
+ export default class List extends LoopressCommand {
5
+ static description = 'List forms from WordPress';
6
+ static examples = ['$ lps form list'];
7
+ static flags = {
8
+ json: Flags.boolean({ char: 'j', description: 'Output in JSON format' }),
9
+ };
10
+ async run() {
11
+ const { flags } = await this.parse(List);
12
+ const forms = await this.wp.get(FORM_ENDPOINT);
13
+ if (flags.json) {
14
+ this.log(JSON.stringify(forms, null, 2));
15
+ return;
16
+ }
17
+ this.log(`Forms (${forms.length}):`);
18
+ if (forms.length === 0) {
19
+ this.log(' (none)');
20
+ return;
21
+ }
22
+ for (const form of forms) {
23
+ this.log(` ${getFormId(form) ?? '(no id)'}. ${getFormTitle(form)}`);
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,14 @@
1
+ import { LoopressCommand } from '../../lib/base.js';
2
+ export default class Pull extends LoopressCommand {
3
+ static args: {
4
+ path: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: string[];
8
+ static flags: {
9
+ 'dry-run': import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
+ };
11
+ run(): Promise<void>;
12
+ private findOrphanedFiles;
13
+ }
14
+ export declare function slug(title: string): string;