@loopress/cli 0.1.1 → 0.2.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
@@ -20,7 +20,7 @@ $ npm install -g @loopress/cli
20
20
  $ lps COMMAND
21
21
  running command...
22
22
  $ lps (--version)
23
- @loopress/cli/0.1.1 linux-x64 node-v24.16.0
23
+ @loopress/cli/0.2.0 linux-x64 node-v24.16.0
24
24
  $ lps --help [COMMAND]
25
25
  USAGE
26
26
  $ lps COMMAND
@@ -89,7 +89,7 @@ EXAMPLES
89
89
  $ lps login
90
90
  ```
91
91
 
92
- _See code: [src/commands/login.ts](https://github.com/loopress/loopress/blob/v0.1.1/src/commands/login.ts)_
92
+ _See code: [src/commands/login.ts](https://github.com/loopress/loopress/blob/v0.2.0/src/commands/login.ts)_
93
93
 
94
94
  ## `lps logout`
95
95
 
@@ -106,7 +106,7 @@ EXAMPLES
106
106
  $ lps logout
107
107
  ```
108
108
 
109
- _See code: [src/commands/logout.ts](https://github.com/loopress/loopress/blob/v0.1.1/src/commands/logout.ts)_
109
+ _See code: [src/commands/logout.ts](https://github.com/loopress/loopress/blob/v0.2.0/src/commands/logout.ts)_
110
110
 
111
111
  ## `lps plugins`
112
112
 
@@ -413,7 +413,7 @@ EXAMPLES
413
413
  $ lps project config
414
414
  ```
415
415
 
416
- _See code: [src/commands/project/config.ts](https://github.com/loopress/loopress/blob/v0.1.1/src/commands/project/config.ts)_
416
+ _See code: [src/commands/project/config.ts](https://github.com/loopress/loopress/blob/v0.2.0/src/commands/project/config.ts)_
417
417
 
418
418
  ## `lps project list`
419
419
 
@@ -430,7 +430,7 @@ EXAMPLES
430
430
  $ lps project list
431
431
  ```
432
432
 
433
- _See code: [src/commands/project/list.ts](https://github.com/loopress/loopress/blob/v0.1.1/src/commands/project/list.ts)_
433
+ _See code: [src/commands/project/list.ts](https://github.com/loopress/loopress/blob/v0.2.0/src/commands/project/list.ts)_
434
434
 
435
435
  ## `lps project remove`
436
436
 
@@ -447,7 +447,7 @@ EXAMPLES
447
447
  $ lps project remove
448
448
  ```
449
449
 
450
- _See code: [src/commands/project/remove.ts](https://github.com/loopress/loopress/blob/v0.1.1/src/commands/project/remove.ts)_
450
+ _See code: [src/commands/project/remove.ts](https://github.com/loopress/loopress/blob/v0.2.0/src/commands/project/remove.ts)_
451
451
 
452
452
  ## `lps project remove-env`
453
453
 
@@ -464,7 +464,7 @@ EXAMPLES
464
464
  $ lps project remove-env
465
465
  ```
466
466
 
467
- _See code: [src/commands/project/remove-env.ts](https://github.com/loopress/loopress/blob/v0.1.1/src/commands/project/remove-env.ts)_
467
+ _See code: [src/commands/project/remove-env.ts](https://github.com/loopress/loopress/blob/v0.2.0/src/commands/project/remove-env.ts)_
468
468
 
469
469
  ## `lps project switch`
470
470
 
@@ -481,7 +481,7 @@ EXAMPLES
481
481
  $ lps project switch
482
482
  ```
483
483
 
484
- _See code: [src/commands/project/switch.ts](https://github.com/loopress/loopress/blob/v0.1.1/src/commands/project/switch.ts)_
484
+ _See code: [src/commands/project/switch.ts](https://github.com/loopress/loopress/blob/v0.2.0/src/commands/project/switch.ts)_
485
485
 
486
486
  ## `lps project switch-env`
487
487
 
@@ -498,7 +498,7 @@ EXAMPLES
498
498
  $ lps project switch-env
499
499
  ```
500
500
 
501
- _See code: [src/commands/project/switch-env.ts](https://github.com/loopress/loopress/blob/v0.1.1/src/commands/project/switch-env.ts)_
501
+ _See code: [src/commands/project/switch-env.ts](https://github.com/loopress/loopress/blob/v0.2.0/src/commands/project/switch-env.ts)_
502
502
 
503
503
  ## `lps snippets list`
504
504
 
@@ -529,7 +529,7 @@ EXAMPLES
529
529
  $ lps snippets list --plugin wpcode
530
530
  ```
531
531
 
532
- _See code: [src/commands/snippets/list.ts](https://github.com/loopress/loopress/blob/v0.1.1/src/commands/snippets/list.ts)_
532
+ _See code: [src/commands/snippets/list.ts](https://github.com/loopress/loopress/blob/v0.2.0/src/commands/snippets/list.ts)_
533
533
 
534
534
  ## `lps snippets pull [PATH]`
535
535
 
@@ -565,7 +565,7 @@ EXAMPLES
565
565
  $ lps snippets pull --plugin wpcode
566
566
  ```
567
567
 
568
- _See code: [src/commands/snippets/pull.ts](https://github.com/loopress/loopress/blob/v0.1.1/src/commands/snippets/pull.ts)_
568
+ _See code: [src/commands/snippets/pull.ts](https://github.com/loopress/loopress/blob/v0.2.0/src/commands/snippets/pull.ts)_
569
569
 
570
570
  ## `lps snippets push [PATH]`
571
571
 
@@ -601,7 +601,7 @@ EXAMPLES
601
601
  $ lps snippets push --plugin wpcode
602
602
  ```
603
603
 
604
- _See code: [src/commands/snippets/push.ts](https://github.com/loopress/loopress/blob/v0.1.1/src/commands/snippets/push.ts)_
604
+ _See code: [src/commands/snippets/push.ts](https://github.com/loopress/loopress/blob/v0.2.0/src/commands/snippets/push.ts)_
605
605
 
606
606
  ## `lps styles pull`
607
607
 
@@ -628,7 +628,7 @@ EXAMPLES
628
628
  $ lps styles pull --url http://example.com
629
629
  ```
630
630
 
631
- _See code: [src/commands/styles/pull.ts](https://github.com/loopress/loopress/blob/v0.1.1/src/commands/styles/pull.ts)_
631
+ _See code: [src/commands/styles/pull.ts](https://github.com/loopress/loopress/blob/v0.2.0/src/commands/styles/pull.ts)_
632
632
 
633
633
  ## `lps styles push`
634
634
 
@@ -655,5 +655,5 @@ EXAMPLES
655
655
  $ lps styles push --url http://example.com
656
656
  ```
657
657
 
658
- _See code: [src/commands/styles/push.ts](https://github.com/loopress/loopress/blob/v0.1.1/src/commands/styles/push.ts)_
658
+ _See code: [src/commands/styles/push.ts](https://github.com/loopress/loopress/blob/v0.2.0/src/commands/styles/push.ts)_
659
659
  <!-- commandsstop -->
@@ -1,7 +1,7 @@
1
1
  import { Flags } from '@oclif/core';
2
2
  import got from 'got';
3
- import { getSnippetPlugin } from '../../utils/snippet-plugin.js';
4
3
  import { LoopressCommand } from '../../lib/base.js';
4
+ import { getSnippetPlugin } from '../../utils/snippet-plugin.js';
5
5
  export default class List extends LoopressCommand {
6
6
  static description = 'List snippets from WordPress';
7
7
  static examples = [
@@ -1,7 +1,48 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
2
  import got from 'got';
3
- import { getSnippetPlugin } from '../../utils/snippet-plugin.js';
3
+ import slugify from 'slugify';
4
4
  import { LoopressCommand } from '../../lib/base.js';
5
+ import { getSnippetPlugin } from '../../utils/snippet-plugin.js';
6
+ const EXTENSIONS = {
7
+ css: 'css',
8
+ html: 'html',
9
+ js: 'js',
10
+ php: 'php',
11
+ text: 'txt',
12
+ };
13
+ const sanitize = (value) => value.replaceAll(/\s*\n\s*/g, ' ').trim();
14
+ function buildMetaLines(snippet) {
15
+ return [
16
+ `name: ${sanitize(snippet.name)}`,
17
+ ...(snippet.description ? [`description: ${sanitize(snippet.description)}`] : []),
18
+ `type: ${snippet.type}`,
19
+ ...(snippet.tags.length > 0 ? [`tags: ${snippet.tags.map((t) => sanitize(t)).join(', ')}`] : []),
20
+ `active: ${snippet.active}`,
21
+ ];
22
+ }
23
+ function buildSnippetFile(snippet) {
24
+ const meta = buildMetaLines(snippet);
25
+ switch (snippet.type) {
26
+ case 'css':
27
+ case 'js': {
28
+ const header = ['/**', ...meta.map((l) => ` * ${l}`), ' */'].join('\n');
29
+ return `${header}\n\n${snippet.code}`;
30
+ }
31
+ case 'html': {
32
+ const header = ['<!--', ...meta.map((l) => ` ${l}`), '-->'].join('\n');
33
+ return `${header}\n\n${snippet.code}`;
34
+ }
35
+ case 'text': {
36
+ return snippet.code;
37
+ }
38
+ case 'php':
39
+ default: {
40
+ const header = ['<?php', '/**', ...meta.map((l) => ` * ${l}`), ' */'].join('\n');
41
+ const body = snippet.code.replace(/^<\?php\s*/i, '');
42
+ return `${header}\n\n${body}`;
43
+ }
44
+ }
45
+ }
5
46
  export default class Pull extends LoopressCommand {
6
47
  static args = {
7
48
  path: Args.string({ description: 'Path to snippets directory (overrides project config)' }),
@@ -38,18 +79,29 @@ export default class Pull extends LoopressCommand {
38
79
  const remoteList = await got.get(endpoint, { headers }).json();
39
80
  const snippets = remoteList.map((r) => adapter.fromRemote(r));
40
81
  const fs = await import('node:fs/promises');
82
+ await fs.mkdir(path, { recursive: true });
41
83
  if (dryRun) {
42
84
  this.log(`📝 [DRY RUN] Would pull ${snippets.length} snippets`);
85
+ this.log(`🔍 Raw API sample:\n${JSON.stringify(remoteList[0], null, 2)}`);
43
86
  return;
44
87
  }
45
88
  let count = 0;
89
+ let skipped = 0;
46
90
  for (const snippet of snippets) {
47
- const filePath = `${path}/${snippet.name}.php`;
48
- await fs.writeFile(filePath, snippet.code);
91
+ if (!snippet.name.trim()) {
92
+ skipped++;
93
+ continue;
94
+ }
95
+ const ext = EXTENSIONS[snippet.type];
96
+ const filePath = `${path}/${slugify(snippet.name, { lower: true, strict: true })}.${ext}`;
97
+ await fs.writeFile(filePath, buildSnippetFile(snippet));
49
98
  count++;
50
99
  this.log(`✅ Pulled: ${snippet.name}`);
51
100
  }
52
101
  this.log(`🎉 Successfully pulled ${count} snippet${count === 1 ? '' : 's'} to ${path}`);
102
+ if (skipped > 0) {
103
+ this.warn(`${skipped} snippet${skipped === 1 ? '' : 's'} skipped because they have no name`);
104
+ }
53
105
  }
54
106
  catch (error) {
55
107
  this.error(`❌ Error pulling snippets: ${error.message}`);
@@ -1,7 +1,7 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
2
  import got from 'got';
3
- import { getSnippetPlugin } from '../../utils/snippet-plugin.js';
4
3
  import { LoopressCommand } from '../../lib/base.js';
4
+ import { getSnippetPlugin } from '../../utils/snippet-plugin.js';
5
5
  export default class Push extends LoopressCommand {
6
6
  static args = {
7
7
  path: Args.string({ description: 'Path to snippets directory (overrides project config)' }),
package/dist/help.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import { Help } from '@oclif/core';
2
+ export default class CustomHelp extends Help {
3
+ showRootHelp(): Promise<void>;
4
+ }
package/dist/help.js ADDED
@@ -0,0 +1,22 @@
1
+ import { Help } from '@oclif/core';
2
+ const BANNER = `
3
+
4
+ @@@@@@@@@@@*
5
+ @@@@@@@@@@@*++
6
+ @@@@ ++++
7
+ @@@@ ++++ ▗▖ ▗▄▖ ▗▄▖ ▗▄▄▖ ▗▄▄▖ ▗▄▄▄▖ ▗▄▄▖ ▗▄▄▖
8
+ @@@@ ++++ ▐▌ ▐▌ ▐▌▐▌ ▐▌▐▌ ▐▌▐▌ ▐▌▐▌ ▐▌ ▐▌
9
+ @@@@ ++++ ▐▌ ▐▌ ▐▌▐▌ ▐▌▐▛▀▘ ▐▛▀▚▖▐▛▀▀▘ ▝▀▚▖ ▝▀▚▖
10
+ @@@@ ++++ ▐▙▄▄▖▝▚▄▞▘▝▚▄▞▘▐▌ ▐▌ ▐▌▐▙▄▄▖▗▄▄▞▘▗▄▄▞▘
11
+ @@@@ ++++
12
+ @@@@ ++++
13
+ @@@@@@@@@@@*++
14
+ @@@@@@@@@@@*
15
+
16
+ `;
17
+ export default class CustomHelp extends Help {
18
+ async showRootHelp() {
19
+ this.log(BANNER);
20
+ await super.showRootHelp();
21
+ }
22
+ }
@@ -1,4 +1,5 @@
1
1
  export type PluginName = 'code-snippets' | 'wpcode';
2
+ export type SnippetType = 'css' | 'html' | 'js' | 'php' | 'text';
2
3
  export interface NormalizedSnippet {
3
4
  active: boolean;
4
5
  code: string;
@@ -6,6 +7,7 @@ export interface NormalizedSnippet {
6
7
  id: number;
7
8
  name: string;
8
9
  tags: string[];
10
+ type: SnippetType;
9
11
  }
10
12
  export interface SnippetPlugin {
11
13
  endpoint(siteUrl: string): string;
@@ -1,3 +1,19 @@
1
+ function parseType(raw) {
2
+ const valid = ['css', 'html', 'js', 'php', 'text'];
3
+ const value = String(raw ?? '').toLowerCase();
4
+ return valid.includes(value) ? value : null;
5
+ }
6
+ function inferTypeFromCode(code) {
7
+ const firstLine = code.trimStart().split('\n')[0].trimStart();
8
+ if (firstLine.startsWith('<?'))
9
+ return 'php';
10
+ if (firstLine.startsWith('<'))
11
+ return 'html';
12
+ return 'php';
13
+ }
14
+ function resolveType(raw, code) {
15
+ return parseType(raw) ?? inferTypeFromCode(code);
16
+ }
1
17
  class CodeSnippetsPlugin {
2
18
  endpoint(siteUrl) {
3
19
  return `${siteUrl}/wp-json/code-snippets/v1/snippets`;
@@ -10,6 +26,7 @@ class CodeSnippetsPlugin {
10
26
  id: Number(data.id),
11
27
  name: String(data.name ?? ''),
12
28
  tags: Array.isArray(data.tags) ? data.tags : [],
29
+ type: resolveType(data.type, String(data.code ?? '')),
13
30
  };
14
31
  }
15
32
  toPayload(name, code, path) {
@@ -33,6 +50,7 @@ class WPCodePlugin {
33
50
  id: Number(data.id),
34
51
  name: String(data.title ?? ''),
35
52
  tags: Array.isArray(data.tags) ? data.tags : [],
53
+ type: resolveType(data.type, String(data.code ?? '')),
36
54
  };
37
55
  }
38
56
  toPayload(name, code, path) {
@@ -530,5 +530,5 @@
530
530
  ]
531
531
  }
532
532
  },
533
- "version": "0.1.1"
533
+ "version": "0.2.0"
534
534
  }
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.1.1",
4
+ "version": "0.2.0",
5
5
  "author": "jean-smaug",
6
6
  "bin": {
7
7
  "loopress": "bin/run.js",
@@ -16,7 +16,8 @@
16
16
  "@oclif/plugin-help": "^6.2.50",
17
17
  "@oclif/plugin-plugins": "^5.4.72",
18
18
  "glob": "13.0.6",
19
- "got": "^15.0.5"
19
+ "got": "^15.0.5",
20
+ "slugify": "^1.6.9"
20
21
  },
21
22
  "devDependencies": {
22
23
  "@eslint/compat": "2.1.0",
@@ -60,6 +61,7 @@
60
61
  ],
61
62
  "dirname": "loopress",
62
63
  "commands": "./dist/commands",
64
+ "helpClass": "./dist/help.js",
63
65
  "plugins": [
64
66
  "@oclif/plugin-help",
65
67
  "@oclif/plugin-plugins"