@loopress/cli 0.4.0 → 0.6.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 +122 -102
- package/dist/commands/{style → composer}/pull.d.ts +2 -2
- package/dist/commands/composer/pull.js +33 -0
- package/dist/commands/{style → composer}/push.d.ts +3 -4
- package/dist/commands/composer/push.js +49 -0
- package/dist/commands/init.d.ts +6 -0
- package/dist/commands/init.js +73 -0
- package/dist/commands/plugin/{require.d.ts → add.d.ts} +3 -1
- package/dist/commands/plugin/{require.js → add.js} +29 -8
- package/dist/commands/plugin/pull.js +10 -1
- package/dist/commands/plugin/push.d.ts +2 -2
- package/dist/commands/plugin/push.js +15 -4
- package/dist/commands/project/config.js +2 -2
- package/dist/commands/snippet/list.d.ts +1 -1
- package/dist/commands/snippet/list.js +3 -3
- package/dist/commands/snippet/pull.d.ts +4 -1
- package/dist/commands/snippet/pull.js +26 -37
- package/dist/commands/snippet/push.d.ts +4 -5
- package/dist/commands/snippet/push.js +50 -39
- package/dist/config/auth.manager.js +2 -2
- package/dist/config/project-config.manager.js +2 -2
- package/dist/lib/base.d.ts +1 -1
- package/dist/lib/base.js +18 -6
- package/dist/lib/push-command.d.ts +7 -0
- package/dist/lib/push-command.js +32 -0
- package/dist/utils/composer.d.ts +7 -0
- package/dist/utils/composer.js +33 -0
- package/dist/utils/loopress-config.d.ts +3 -2
- package/dist/utils/snippet-plugin.js +1 -1
- package/oclif.manifest.json +238 -220
- package/package.json +17 -17
- package/dist/commands/style/pull.js +0 -52
- package/dist/commands/style/push.js +0 -78
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.
|
|
4
|
+
"version": "0.6.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.
|
|
16
|
-
"@oclif/plugin-help": "^6.2.
|
|
17
|
-
"@oclif/plugin-plugins": "^5.4.
|
|
15
|
+
"@oclif/core": "^4.11.11",
|
|
16
|
+
"@oclif/plugin-help": "^6.2.53",
|
|
17
|
+
"@oclif/plugin-plugins": "^5.4.80",
|
|
18
18
|
"glob": "13.0.6",
|
|
19
|
-
"got": "^15.0.
|
|
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/
|
|
27
|
-
"@types/mocha": "^10.0.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
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"prettier": "3.8.4",
|
|
30
|
+
"oclif": "^4.23.24",
|
|
31
|
+
"prettier": "3.9.4",
|
|
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": "^4.1.9"
|
|
40
36
|
},
|
|
41
37
|
"engines": {
|
|
42
38
|
"node": ">=18.0.0"
|
|
@@ -52,6 +48,10 @@
|
|
|
52
48
|
],
|
|
53
49
|
"license": "MPL-2.0",
|
|
54
50
|
"main": "dist/index.js",
|
|
51
|
+
"exports": {
|
|
52
|
+
".": "./dist/index.js",
|
|
53
|
+
"./schema": "./loopress.schema.json"
|
|
54
|
+
},
|
|
55
55
|
"type": "module",
|
|
56
56
|
"oclif": {
|
|
57
57
|
"bin": "lps",
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"build": "shx rm -rf dist && tsc -b",
|
|
81
81
|
"lint": "eslint",
|
|
82
82
|
"posttest": "pnpm run lint",
|
|
83
|
-
"test": "
|
|
83
|
+
"test": "vitest run",
|
|
84
84
|
"version": "oclif readme && git add README.md",
|
|
85
85
|
"format": "prettier . --write"
|
|
86
86
|
}
|
|
@@ -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
|
-
}
|