siluzan-website-cli 1.0.1-beta.1 → 1.0.1-beta.3
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 +9 -2
- package/dist/index.js +1317 -62
- package/dist/skill/SKILL.md +28 -13
- package/dist/skill/_meta.json +2 -2
- package/dist/skill/references/content.md +39 -0
- package/dist/skill/references/media.md +11 -0
- package/dist/skill/references/pages.md +12 -0
- package/dist/skill/references/plugins.md +60 -15
- package/dist/skill/references/search.md +12 -0
- package/dist/skill/references/terms.md +14 -0
- package/dist/skill/scripts/install.ps1 +1 -1
- package/dist/skill/scripts/install.sh +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1960,6 +1960,7 @@ import * as fs from "fs";
|
|
|
1960
1960
|
import * as path from "path";
|
|
1961
1961
|
import * as os from "os";
|
|
1962
1962
|
import lockfile from "proper-lockfile";
|
|
1963
|
+
import { randomBytes } from "crypto";
|
|
1963
1964
|
import * as https from "https";
|
|
1964
1965
|
import * as http from "http";
|
|
1965
1966
|
import * as zlib from "zlib";
|
|
@@ -2460,7 +2461,13 @@ function rawRequest(url, options) {
|
|
|
2460
2461
|
}
|
|
2461
2462
|
reject(err);
|
|
2462
2463
|
});
|
|
2463
|
-
if (options.body)
|
|
2464
|
+
if (options.body !== void 0) {
|
|
2465
|
+
const payload = typeof options.body === "string" ? Buffer.from(options.body) : options.body;
|
|
2466
|
+
if (!headers["Content-Length"] && !headers["content-length"]) {
|
|
2467
|
+
req.setHeader("Content-Length", payload.length);
|
|
2468
|
+
}
|
|
2469
|
+
req.write(payload);
|
|
2470
|
+
}
|
|
2464
2471
|
req.end();
|
|
2465
2472
|
});
|
|
2466
2473
|
}
|
|
@@ -2557,6 +2564,54 @@ function formatHttpError(status, rawBody, opts) {
|
|
|
2557
2564
|
function buildAuthHeaders(config) {
|
|
2558
2565
|
return buildSiluzanAuthHeaders(config);
|
|
2559
2566
|
}
|
|
2567
|
+
function buildMultipartBody(fields, files) {
|
|
2568
|
+
const boundary = `----SiluzanForm${randomBytes(16).toString("hex")}`;
|
|
2569
|
+
const chunks = [];
|
|
2570
|
+
for (const [name, value] of Object.entries(fields)) {
|
|
2571
|
+
chunks.push(
|
|
2572
|
+
Buffer.from(
|
|
2573
|
+
`--${boundary}\r
|
|
2574
|
+
Content-Disposition: form-data; name="${name}"\r
|
|
2575
|
+
\r
|
|
2576
|
+
${value}\r
|
|
2577
|
+
`
|
|
2578
|
+
)
|
|
2579
|
+
);
|
|
2580
|
+
}
|
|
2581
|
+
for (const file of files) {
|
|
2582
|
+
chunks.push(
|
|
2583
|
+
Buffer.from(
|
|
2584
|
+
`--${boundary}\r
|
|
2585
|
+
Content-Disposition: form-data; name="${file.field}"; filename="${file.filename}"\r
|
|
2586
|
+
Content-Type: ${file.contentType}\r
|
|
2587
|
+
\r
|
|
2588
|
+
`
|
|
2589
|
+
)
|
|
2590
|
+
);
|
|
2591
|
+
chunks.push(file.data);
|
|
2592
|
+
chunks.push(Buffer.from("\r\n"));
|
|
2593
|
+
}
|
|
2594
|
+
chunks.push(Buffer.from(`--${boundary}--\r
|
|
2595
|
+
`));
|
|
2596
|
+
return {
|
|
2597
|
+
body: Buffer.concat(chunks),
|
|
2598
|
+
contentType: `multipart/form-data; boundary=${boundary}`
|
|
2599
|
+
};
|
|
2600
|
+
}
|
|
2601
|
+
async function parseApiResponse(status, text, verbose) {
|
|
2602
|
+
if (status < 200 || status >= 300) {
|
|
2603
|
+
throw new Error(formatHttpError(status, text, { verbose }));
|
|
2604
|
+
}
|
|
2605
|
+
if (!text.trim()) return null;
|
|
2606
|
+
try {
|
|
2607
|
+
return parseJsonWithStringIds(text);
|
|
2608
|
+
} catch {
|
|
2609
|
+
if (verbose) {
|
|
2610
|
+
console.error(` \u26A0\uFE0F \u54CD\u5E94\u975E JSON\uFF0C\u539F\u59CB\u5185\u5BB9\uFF1A${redactSensitive(text).slice(0, 200)}`);
|
|
2611
|
+
}
|
|
2612
|
+
return text;
|
|
2613
|
+
}
|
|
2614
|
+
}
|
|
2560
2615
|
async function apiFetch(url, config, options = {}, verbose = false) {
|
|
2561
2616
|
const method = options.method ?? "GET";
|
|
2562
2617
|
const reqHeaders = {
|
|
@@ -2575,19 +2630,23 @@ async function apiFetch(url, config, options = {}, verbose = false) {
|
|
|
2575
2630
|
headers: reqHeaders,
|
|
2576
2631
|
body
|
|
2577
2632
|
});
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
}
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2633
|
+
return parseApiResponse(res.status, res.text, verbose);
|
|
2634
|
+
}
|
|
2635
|
+
async function apiFetchMultipart(url, config, payload, verbose = false) {
|
|
2636
|
+
const packed = buildMultipartBody(payload.fields ?? {}, payload.files);
|
|
2637
|
+
const reqHeaders = {
|
|
2638
|
+
"Content-Type": packed.contentType,
|
|
2639
|
+
"Accept-Language": "zh-CN",
|
|
2640
|
+
"Accept-Encoding": "gzip, deflate, br",
|
|
2641
|
+
...buildAuthHeaders(config),
|
|
2642
|
+
Datapermission: config.dataPermission ?? ""
|
|
2643
|
+
};
|
|
2644
|
+
const res = await rawRequest(url, {
|
|
2645
|
+
method: "POST",
|
|
2646
|
+
headers: reqHeaders,
|
|
2647
|
+
body: packed.body
|
|
2648
|
+
});
|
|
2649
|
+
return parseApiResponse(res.status, res.text, verbose);
|
|
2591
2650
|
}
|
|
2592
2651
|
function getCurrentVersion(importMetaUrl) {
|
|
2593
2652
|
try {
|
|
@@ -3691,6 +3750,9 @@ function loadConfig() {
|
|
|
3691
3750
|
function apiFetch2(url, config, options = {}, verbose = false) {
|
|
3692
3751
|
return apiFetch(url, config, options, verbose);
|
|
3693
3752
|
}
|
|
3753
|
+
function apiFetchMultipart2(url, config, payload, verbose = false) {
|
|
3754
|
+
return apiFetchMultipart(url, config, payload, verbose);
|
|
3755
|
+
}
|
|
3694
3756
|
|
|
3695
3757
|
// src/utils/site-url.ts
|
|
3696
3758
|
function normalizeRegion(raw) {
|
|
@@ -3842,6 +3904,57 @@ function register5(program2) {
|
|
|
3842
3904
|
|
|
3843
3905
|
// src/commands/pages.ts
|
|
3844
3906
|
import * as fs6 from "fs";
|
|
3907
|
+
|
|
3908
|
+
// src/utils/wp-site.ts
|
|
3909
|
+
async function resolveTarget(opts) {
|
|
3910
|
+
const config = loadConfig();
|
|
3911
|
+
const site = await resolveSite(config, opts);
|
|
3912
|
+
return { config, site, base: trimTrailingSlash(site.url) };
|
|
3913
|
+
}
|
|
3914
|
+
function wpV2(base, path6) {
|
|
3915
|
+
const suffix = path6.startsWith("/") ? path6 : `/${path6}`;
|
|
3916
|
+
return `${base}/wp-json/wp/v2${suffix}`;
|
|
3917
|
+
}
|
|
3918
|
+
async function resolveTypeRestBase(target, typeArg, verbose = false) {
|
|
3919
|
+
const needle = typeArg.trim().toLowerCase();
|
|
3920
|
+
if (!needle) {
|
|
3921
|
+
throw new Error("\u8BF7\u63D0\u4F9B --type\uFF08\u5148 content types \u770B rest_base\uFF09");
|
|
3922
|
+
}
|
|
3923
|
+
const types = await apiFetch2(
|
|
3924
|
+
wpV2(target.base, "/types?context=edit"),
|
|
3925
|
+
target.config,
|
|
3926
|
+
{},
|
|
3927
|
+
verbose
|
|
3928
|
+
);
|
|
3929
|
+
for (const [slug, info] of Object.entries(types || {})) {
|
|
3930
|
+
const restBase = (info.rest_base || slug).toLowerCase();
|
|
3931
|
+
if (slug.toLowerCase() === needle || restBase === needle) {
|
|
3932
|
+
return info.rest_base || slug;
|
|
3933
|
+
}
|
|
3934
|
+
}
|
|
3935
|
+
return typeArg.trim();
|
|
3936
|
+
}
|
|
3937
|
+
async function resolveTaxonomyRestBase(target, taxonomyArg, verbose = false) {
|
|
3938
|
+
const needle = taxonomyArg.trim().toLowerCase();
|
|
3939
|
+
if (!needle) {
|
|
3940
|
+
throw new Error("\u8BF7\u63D0\u4F9B --taxonomy\uFF08\u5982 category\u3001post_tag\uFF09");
|
|
3941
|
+
}
|
|
3942
|
+
const taxes = await apiFetch2(
|
|
3943
|
+
wpV2(target.base, "/taxonomies?context=edit"),
|
|
3944
|
+
target.config,
|
|
3945
|
+
{},
|
|
3946
|
+
verbose
|
|
3947
|
+
);
|
|
3948
|
+
for (const [slug, info] of Object.entries(taxes || {})) {
|
|
3949
|
+
const restBase = (info.rest_base || slug).toLowerCase();
|
|
3950
|
+
if (slug.toLowerCase() === needle || restBase === needle) {
|
|
3951
|
+
return info.rest_base || slug;
|
|
3952
|
+
}
|
|
3953
|
+
}
|
|
3954
|
+
return taxonomyArg.trim();
|
|
3955
|
+
}
|
|
3956
|
+
|
|
3957
|
+
// src/commands/pages.ts
|
|
3845
3958
|
function pageTitle(page) {
|
|
3846
3959
|
if (typeof page.title === "string") return page.title;
|
|
3847
3960
|
return page.title?.rendered ?? "";
|
|
@@ -3909,6 +4022,7 @@ async function runPagesList(opts) {
|
|
|
3909
4022
|
{ key: "id", header: "id" },
|
|
3910
4023
|
{ key: "title", header: "\u6807\u9898" },
|
|
3911
4024
|
{ key: "status", header: "\u72B6\u6001" },
|
|
4025
|
+
{ key: "slug", header: "slug" },
|
|
3912
4026
|
{ key: "link", header: "\u94FE\u63A5" }
|
|
3913
4027
|
];
|
|
3914
4028
|
console.log(`
|
|
@@ -3919,6 +4033,7 @@ ${site.name} \u9875\u9762\uFF08${pages.length}\uFF09
|
|
|
3919
4033
|
id: String(p.id),
|
|
3920
4034
|
title: pageTitle(p) || "(\u65E0\u6807\u9898)",
|
|
3921
4035
|
status: p.status ?? "-",
|
|
4036
|
+
slug: p.slug ?? "-",
|
|
3922
4037
|
link: p.link ?? "-"
|
|
3923
4038
|
})),
|
|
3924
4039
|
columns
|
|
@@ -3981,6 +4096,103 @@ async function runPagesWrite(mode, opts) {
|
|
|
3981
4096
|
console.log(` \u7AD9\u70B9 : ${base}
|
|
3982
4097
|
`);
|
|
3983
4098
|
}
|
|
4099
|
+
async function runPagesGet(opts) {
|
|
4100
|
+
const id = Number(opts.id);
|
|
4101
|
+
if (!Number.isFinite(id) || id <= 0) {
|
|
4102
|
+
console.error("\n\u274C \u8BF7\u63D0\u4F9B --id\n");
|
|
4103
|
+
process.exit(1);
|
|
4104
|
+
}
|
|
4105
|
+
const target = await resolveTarget(opts);
|
|
4106
|
+
const page = await apiFetch2(
|
|
4107
|
+
wpV2(target.base, `/pages/${id}?context=edit`),
|
|
4108
|
+
target.config,
|
|
4109
|
+
{},
|
|
4110
|
+
opts.verbose
|
|
4111
|
+
).catch((e) => {
|
|
4112
|
+
console.error(`
|
|
4113
|
+
\u274C \u83B7\u53D6\u9875\u9762\u5931\u8D25\uFF1A${e.message}
|
|
4114
|
+
`);
|
|
4115
|
+
process.exit(1);
|
|
4116
|
+
});
|
|
4117
|
+
if (opts.json) {
|
|
4118
|
+
console.log(JSON.stringify(page, null, 2));
|
|
4119
|
+
return;
|
|
4120
|
+
}
|
|
4121
|
+
console.log(`
|
|
4122
|
+
\u9875\u9762 #${page.id}`);
|
|
4123
|
+
console.log(` \u6807\u9898 : ${pageTitle(page) || "-"}`);
|
|
4124
|
+
console.log(` \u72B6\u6001 : ${page.status || "-"}`);
|
|
4125
|
+
console.log(` slug : ${page.slug || "-"}`);
|
|
4126
|
+
console.log(` \u94FE\u63A5 : ${page.link || "-"}`);
|
|
4127
|
+
if (page.parent) console.log(` \u7236\u9875 : ${page.parent}`);
|
|
4128
|
+
if (page.featured_media) console.log(` \u7279\u8272\u56FE : ${page.featured_media}`);
|
|
4129
|
+
console.log();
|
|
4130
|
+
}
|
|
4131
|
+
async function runPagesMeta(opts) {
|
|
4132
|
+
const id = Number(opts.id);
|
|
4133
|
+
if (!Number.isFinite(id) || id <= 0) {
|
|
4134
|
+
console.error("\n\u274C \u8BF7\u63D0\u4F9B --id\n");
|
|
4135
|
+
process.exit(1);
|
|
4136
|
+
}
|
|
4137
|
+
const body = {};
|
|
4138
|
+
if (opts.title?.trim()) body.title = opts.title.trim();
|
|
4139
|
+
if (opts.slug?.trim()) body.slug = opts.slug.trim();
|
|
4140
|
+
if (opts.status?.trim()) body.status = opts.status.trim();
|
|
4141
|
+
const parent = Number(opts.parent);
|
|
4142
|
+
if (opts.parent !== void 0 && Number.isFinite(parent)) body.parent = parent;
|
|
4143
|
+
const featured = Number(opts.featuredMedia);
|
|
4144
|
+
if (Number.isFinite(featured) && featured > 0) body.featured_media = featured;
|
|
4145
|
+
if (Object.keys(body).length === 0) {
|
|
4146
|
+
console.error("\n\u274C \u6CA1\u6709\u8981\u6539\u7684\u5B57\u6BB5\u3002\u6B63\u6587\u8BF7\u7528 pages update\u3002\n");
|
|
4147
|
+
process.exit(1);
|
|
4148
|
+
}
|
|
4149
|
+
const target = await resolveTarget(opts);
|
|
4150
|
+
const page = await apiFetch2(
|
|
4151
|
+
wpV2(target.base, `/pages/${id}`),
|
|
4152
|
+
target.config,
|
|
4153
|
+
{ method: "POST", body: JSON.stringify(body) },
|
|
4154
|
+
opts.verbose
|
|
4155
|
+
).catch((e) => {
|
|
4156
|
+
console.error(`
|
|
4157
|
+
\u274C \u66F4\u65B0\u9875\u9762\u5143\u6570\u636E\u5931\u8D25\uFF1A${e.message}
|
|
4158
|
+
`);
|
|
4159
|
+
process.exit(1);
|
|
4160
|
+
});
|
|
4161
|
+
console.log(`
|
|
4162
|
+
\u2705 \u9875\u9762 #${page.id} \u5143\u6570\u636E\u5DF2\u66F4\u65B0`);
|
|
4163
|
+
console.log(` \u6807\u9898 : ${pageTitle(page) || "-"}`);
|
|
4164
|
+
console.log(` \u72B6\u6001 : ${page.status || "-"}`);
|
|
4165
|
+
console.log(` slug : ${page.slug || "-"}`);
|
|
4166
|
+
if (page.link) console.log(` \u94FE\u63A5 : ${page.link}`);
|
|
4167
|
+
console.log();
|
|
4168
|
+
}
|
|
4169
|
+
async function runPagesTrash(opts) {
|
|
4170
|
+
const id = Number(opts.id);
|
|
4171
|
+
if (!Number.isFinite(id) || id <= 0) {
|
|
4172
|
+
console.error("\n\u274C \u8BF7\u63D0\u4F9B --id\n");
|
|
4173
|
+
process.exit(1);
|
|
4174
|
+
}
|
|
4175
|
+
const target = await resolveTarget(opts);
|
|
4176
|
+
const qs = opts.force ? "?force=true" : "";
|
|
4177
|
+
const page = await apiFetch2(
|
|
4178
|
+
wpV2(target.base, `/pages/${id}${qs}`),
|
|
4179
|
+
target.config,
|
|
4180
|
+
{ method: "DELETE" },
|
|
4181
|
+
opts.verbose
|
|
4182
|
+
).catch((e) => {
|
|
4183
|
+
console.error(`
|
|
4184
|
+
\u274C \u5220\u9664\u9875\u9762\u5931\u8D25\uFF1A${e.message}
|
|
4185
|
+
`);
|
|
4186
|
+
process.exit(1);
|
|
4187
|
+
});
|
|
4188
|
+
console.log(
|
|
4189
|
+
opts.force ? `
|
|
4190
|
+
\u2705 \u5DF2\u6C38\u4E45\u5220\u9664\u9875\u9762 #${id}
|
|
4191
|
+
` : `
|
|
4192
|
+
\u2705 \u9875\u9762 #${id} \u5DF2\u8FDB\u56DE\u6536\u7AD9\uFF08status=${page.status || "trash"}\uFF09
|
|
4193
|
+
`
|
|
4194
|
+
);
|
|
4195
|
+
}
|
|
3984
4196
|
function register6(program2) {
|
|
3985
4197
|
const pages = program2.command("pages").description("WordPress \u9875\u9762\uFF08zionbuilder visual-edit\uFF09");
|
|
3986
4198
|
pages.command("list").description("\u5217\u51FA\u7AD9\u70B9\u9875\u9762").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740\uFF08\u8DF3\u8FC7 all-sites\uFF09").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
@@ -3992,47 +4204,149 @@ function register6(program2) {
|
|
|
3992
4204
|
pages.command("update").description("\u7528 HTML \u8986\u76D6\u5DF2\u6709\u9875\u9762\uFF08\u8D70 save-visual-edit\uFF0C\u4F1A\u76F4\u63A5\u53D1\u5E03\uFF09").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").requiredOption("--id <id>", "\u9875\u9762 ID").option("-t, --title <title>", "\u65B0\u6807\u9898\uFF08\u53EF\u7701\u7565\uFF09").option("-c, --content <html>", "HTML \u6B63\u6587").option("--content-file <path>", "\u4ECE\u6587\u4EF6\u8BFB\u53D6 HTML \u6B63\u6587").option("--css <css>", "\u9644\u52A0 CSS").option("--css-file <path>", "\u4ECE\u6587\u4EF6\u8BFB\u53D6 CSS").option("--js <js>", "\u9644\u52A0 JS").option("--js-file <path>", "\u4ECE\u6587\u4EF6\u8BFB\u53D6 JS").option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
3993
4205
|
await runPagesWrite("update", opts);
|
|
3994
4206
|
});
|
|
4207
|
+
pages.command("get").description("\u67E5\u770B\u5355\u4E2A\u9875\u9762\u7684\u5143\u6570\u636E").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").requiredOption("--id <id>", "\u9875\u9762 ID").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
4208
|
+
await runPagesGet(opts);
|
|
4209
|
+
});
|
|
4210
|
+
pages.command("meta").description("\u6539\u9875\u9762 slug / \u72B6\u6001 / \u7236\u9875 / \u7279\u8272\u56FE\uFF08\u4E0D\u6539 Zion \u6B63\u6587\uFF09").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").requiredOption("--id <id>", "\u9875\u9762 ID").option("-t, --title <title>", "\u6807\u9898").option("--slug <slug>", "\u522B\u540D").option("--status <status>", "publish / draft / private / pending").option("--parent <id>", "\u7236\u9875\u9762 ID\uFF0C0 \u8868\u793A\u53D6\u6D88").option("--featured-media <id>", "\u7279\u8272\u56FE\u5A92\u4F53 ID").option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
4211
|
+
await runPagesMeta(opts);
|
|
4212
|
+
});
|
|
4213
|
+
pages.command("trash").description("\u9875\u9762\u8FDB\u56DE\u6536\u7AD9\uFF1B\u52A0 --force \u6C38\u4E45\u5220\u9664").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").requiredOption("--id <id>", "\u9875\u9762 ID").option("--force", "\u6C38\u4E45\u5220\u9664", false).option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
4214
|
+
await runPagesTrash(opts);
|
|
4215
|
+
});
|
|
3995
4216
|
}
|
|
3996
4217
|
|
|
3997
4218
|
// src/commands/plugins.ts
|
|
4219
|
+
import { readFileSync as readFileSync6, existsSync as existsSync3 } from "fs";
|
|
4220
|
+
import { basename as basename2, resolve as resolve2 } from "path";
|
|
4221
|
+
var MAX_ZIP_BYTES = 20 * 1024 * 1024;
|
|
4222
|
+
var PROTECTED_PLUGIN_PREFIXES = ["siluzan-helper-plugin", "wp-oauth2"];
|
|
4223
|
+
function isProtectedPlugin(plugin) {
|
|
4224
|
+
const key = pluginKey(plugin);
|
|
4225
|
+
return PROTECTED_PLUGIN_PREFIXES.some((prefix) => key === prefix || key.startsWith(`${prefix}/`));
|
|
4226
|
+
}
|
|
4227
|
+
function wpPluginRestPath(plugin) {
|
|
4228
|
+
return plugin.replace(/\\/g, "/").split("/").filter(Boolean).map((part) => encodeURIComponent(part)).join("/");
|
|
4229
|
+
}
|
|
3998
4230
|
function pluginName(item) {
|
|
3999
4231
|
if (typeof item.name === "string") return item.name;
|
|
4000
4232
|
return item.name?.raw || item.name?.rendered || item.plugin || "";
|
|
4001
4233
|
}
|
|
4002
|
-
|
|
4234
|
+
function pluginKey(value) {
|
|
4235
|
+
return value.replace(/\\/g, "/").replace(/\.php$/i, "").toLowerCase();
|
|
4236
|
+
}
|
|
4237
|
+
async function resolveTarget2(opts) {
|
|
4003
4238
|
const config = loadConfig();
|
|
4004
4239
|
const site = await resolveSite(config, opts);
|
|
4005
4240
|
return { config, site, base: trimTrailingSlash(site.url) };
|
|
4006
4241
|
}
|
|
4242
|
+
function isRouteMissing(err) {
|
|
4243
|
+
const msg = err.message || "";
|
|
4244
|
+
return /HTTP 404/.test(msg) && /No route was found|rest_no_route/i.test(msg);
|
|
4245
|
+
}
|
|
4246
|
+
function readZipPayload(zipPath) {
|
|
4247
|
+
const abs = resolve2(zipPath);
|
|
4248
|
+
if (!existsSync3(abs)) {
|
|
4249
|
+
console.error(`
|
|
4250
|
+
\u274C zip \u4E0D\u5B58\u5728\uFF1A${abs}
|
|
4251
|
+
`);
|
|
4252
|
+
process.exit(1);
|
|
4253
|
+
}
|
|
4254
|
+
const buf = readFileSync6(abs);
|
|
4255
|
+
if (buf.length > MAX_ZIP_BYTES) {
|
|
4256
|
+
console.error("\n\u274C zip \u8D85\u8FC7 20MB\uFF0C\u8BF7\u6362\u66F4\u5C0F\u7684\u5305\n");
|
|
4257
|
+
process.exit(1);
|
|
4258
|
+
}
|
|
4259
|
+
return {
|
|
4260
|
+
filename: basename2(abs),
|
|
4261
|
+
zip_base64: buf.toString("base64")
|
|
4262
|
+
};
|
|
4263
|
+
}
|
|
4264
|
+
function printActionResult(result, site, base, okTitle) {
|
|
4265
|
+
if (!result.success) {
|
|
4266
|
+
console.error(`
|
|
4267
|
+
\u274C ${result.message || "\u7AD9\u70B9\u62D2\u7EDD\u4E86\u8FD9\u6B21\u64CD\u4F5C"}`);
|
|
4268
|
+
if (result.code) console.error(` code : ${result.code}`);
|
|
4269
|
+
process.exit(1);
|
|
4270
|
+
}
|
|
4271
|
+
console.log(result.already ? "\n\u2705 \u63D2\u4EF6\u5DF2\u5728\u7AD9\u70B9\u4E0A\uFF08\u5DF2\u542F\u7528\uFF09" : `
|
|
4272
|
+
\u2705 ${okTitle}`);
|
|
4273
|
+
if (result.plugin) console.log(` plugin : ${result.plugin}`);
|
|
4274
|
+
if (result.version) console.log(` \u7248\u672C : ${result.version}`);
|
|
4275
|
+
if (result.zip) console.log(` zip : ${result.zip}`);
|
|
4276
|
+
if (result.message) console.log(` \u8BF4\u660E : ${result.message}`);
|
|
4277
|
+
console.log(` \u7AD9\u70B9 : ${site.name} (${base})
|
|
4278
|
+
`);
|
|
4279
|
+
}
|
|
4280
|
+
async function withHelperBootstrap(opts, target, run) {
|
|
4281
|
+
try {
|
|
4282
|
+
return await run();
|
|
4283
|
+
} catch (e) {
|
|
4284
|
+
const err = e;
|
|
4285
|
+
if (!isRouteMissing(err)) throw err;
|
|
4286
|
+
console.log("\u7AD9\u70B9 helper REST \u4E0D\u53EF\u7528\uFF0C\u5148\u4ECE\u955C\u50CF\u672C\u5730 zip \u5347\u7EA7 helper\u2026");
|
|
4287
|
+
await runUpdateHelper({ ...opts, site: target.site.guid || opts.site, url: target.site.url }, true);
|
|
4288
|
+
return await run();
|
|
4289
|
+
}
|
|
4290
|
+
}
|
|
4007
4291
|
async function runPluginsList(opts) {
|
|
4008
|
-
const { config, site, base } = await
|
|
4292
|
+
const { config, site, base } = await resolveTarget2(opts);
|
|
4009
4293
|
const api = `${base}/wp-json/wp/v2/plugins`;
|
|
4010
4294
|
let plugins;
|
|
4011
4295
|
try {
|
|
4012
4296
|
plugins = await apiFetch2(api, config, {}, opts.verbose);
|
|
4013
4297
|
} catch (e) {
|
|
4298
|
+
const msg = e.message || "";
|
|
4014
4299
|
console.error(`
|
|
4015
|
-
\u274C \u83B7\u53D6\u5DF2\u88C5\u63D2\u4EF6\u5931\u8D25\uFF1A${
|
|
4016
|
-
|
|
4300
|
+
\u274C \u83B7\u53D6\u5DF2\u88C5\u63D2\u4EF6\u5931\u8D25\uFF1A${msg}`);
|
|
4301
|
+
if (/HTTP 401/.test(msg)) {
|
|
4302
|
+
console.error(" \u7AD9\u70B9 oauth2 \u8FC7\u65E7\u6216\u4E0D\u8BA4 API Key\uFF0C\u9700\u8981\u5148\u505A SiteMan \u955C\u50CF\u5347\u7EA7\u3002\n");
|
|
4303
|
+
}
|
|
4304
|
+
if (opts.exitOnError === false) return;
|
|
4017
4305
|
process.exit(1);
|
|
4018
4306
|
return;
|
|
4019
4307
|
}
|
|
4020
4308
|
if (!Array.isArray(plugins)) {
|
|
4021
4309
|
console.error("\n\u274C \u7AD9\u70B9\u8FD4\u56DE\u7684\u63D2\u4EF6\u5217\u8868\u683C\u5F0F\u5F02\u5E38\n");
|
|
4310
|
+
if (opts.exitOnError === false) return;
|
|
4022
4311
|
process.exit(1);
|
|
4023
4312
|
}
|
|
4313
|
+
let catalog = [];
|
|
4314
|
+
try {
|
|
4315
|
+
const res = await apiFetch2(
|
|
4316
|
+
`${base}/wp-json/siluzan-helper/v1/plugins/catalog`,
|
|
4317
|
+
config,
|
|
4318
|
+
{},
|
|
4319
|
+
opts.verbose
|
|
4320
|
+
);
|
|
4321
|
+
catalog = Array.isArray(res.items) ? res.items : [];
|
|
4322
|
+
} catch {
|
|
4323
|
+
}
|
|
4324
|
+
const catalogByKey = /* @__PURE__ */ new Map();
|
|
4325
|
+
for (const item of catalog) {
|
|
4326
|
+
if (item.plugin) catalogByKey.set(pluginKey(item.plugin), item);
|
|
4327
|
+
if (item.slug) catalogByKey.set(pluginKey(item.slug), item);
|
|
4328
|
+
}
|
|
4329
|
+
const rows = plugins.map((p) => {
|
|
4330
|
+
const plugin = p.plugin ?? "";
|
|
4331
|
+
const hit = catalogByKey.get(pluginKey(plugin));
|
|
4332
|
+
let updateSource = "none";
|
|
4333
|
+
if (hit?.update_available) updateSource = "catalog";
|
|
4334
|
+
return {
|
|
4335
|
+
plugin,
|
|
4336
|
+
name: pluginName(p),
|
|
4337
|
+
status: p.status ?? "",
|
|
4338
|
+
version: p.version ?? "",
|
|
4339
|
+
updateSource,
|
|
4340
|
+
catalogVersion: hit?.new_version ?? ""
|
|
4341
|
+
};
|
|
4342
|
+
});
|
|
4024
4343
|
if (opts.json) {
|
|
4025
4344
|
console.log(
|
|
4026
4345
|
JSON.stringify(
|
|
4027
4346
|
{
|
|
4028
4347
|
site: { guid: site.guid, name: site.name, url: site.url },
|
|
4029
|
-
total:
|
|
4030
|
-
plugins:
|
|
4031
|
-
plugin: p.plugin ?? "",
|
|
4032
|
-
name: pluginName(p),
|
|
4033
|
-
status: p.status ?? "",
|
|
4034
|
-
version: p.version ?? ""
|
|
4035
|
-
}))
|
|
4348
|
+
total: rows.length,
|
|
4349
|
+
plugins: rows
|
|
4036
4350
|
},
|
|
4037
4351
|
null,
|
|
4038
4352
|
2
|
|
@@ -4040,7 +4354,7 @@ async function runPluginsList(opts) {
|
|
|
4040
4354
|
);
|
|
4041
4355
|
return;
|
|
4042
4356
|
}
|
|
4043
|
-
if (
|
|
4357
|
+
if (rows.length === 0) {
|
|
4044
4358
|
console.log(`
|
|
4045
4359
|
\u7AD9\u70B9 ${site.name} \u672A\u8FD4\u56DE\u63D2\u4EF6\u3002
|
|
4046
4360
|
`);
|
|
@@ -4050,32 +4364,45 @@ async function runPluginsList(opts) {
|
|
|
4050
4364
|
{ key: "plugin", header: "plugin" },
|
|
4051
4365
|
{ key: "name", header: "\u540D\u79F0" },
|
|
4052
4366
|
{ key: "status", header: "\u72B6\u6001" },
|
|
4053
|
-
{ key: "version", header: "\u7248\u672C" }
|
|
4367
|
+
{ key: "version", header: "\u7248\u672C" },
|
|
4368
|
+
{ key: "updateSource", header: "\u66F4\u65B0\u6E90" },
|
|
4369
|
+
{ key: "catalogVersion", header: "\u76EE\u5F55\u7248\u672C" }
|
|
4054
4370
|
];
|
|
4055
4371
|
console.log(`
|
|
4056
|
-
${site.name} \u5DF2\u88C5\u63D2\u4EF6\uFF08${
|
|
4372
|
+
${site.name} \u5DF2\u88C5\u63D2\u4EF6\uFF08${rows.length}\uFF09
|
|
4057
4373
|
`);
|
|
4058
4374
|
printCliTable(
|
|
4059
|
-
|
|
4060
|
-
plugin:
|
|
4061
|
-
name:
|
|
4062
|
-
status:
|
|
4063
|
-
version:
|
|
4375
|
+
rows.map((r) => ({
|
|
4376
|
+
plugin: r.plugin || "-",
|
|
4377
|
+
name: r.name || "-",
|
|
4378
|
+
status: r.status || "-",
|
|
4379
|
+
version: r.version || "-",
|
|
4380
|
+
updateSource: r.updateSource,
|
|
4381
|
+
catalogVersion: r.catalogVersion || "-"
|
|
4064
4382
|
})),
|
|
4065
4383
|
columns
|
|
4066
4384
|
);
|
|
4067
4385
|
console.log();
|
|
4068
4386
|
}
|
|
4069
4387
|
async function runPluginsCatalog(opts) {
|
|
4070
|
-
const
|
|
4071
|
-
const
|
|
4388
|
+
const target = await resolveTarget2(opts);
|
|
4389
|
+
const { site, base } = target;
|
|
4072
4390
|
let res;
|
|
4073
4391
|
try {
|
|
4074
|
-
res = await
|
|
4392
|
+
res = await withHelperBootstrap(
|
|
4393
|
+
opts,
|
|
4394
|
+
target,
|
|
4395
|
+
() => apiFetch2(
|
|
4396
|
+
`${base}/wp-json/siluzan-helper/v1/plugins/catalog`,
|
|
4397
|
+
target.config,
|
|
4398
|
+
{},
|
|
4399
|
+
opts.verbose
|
|
4400
|
+
)
|
|
4401
|
+
);
|
|
4075
4402
|
} catch (e) {
|
|
4076
4403
|
console.error(`
|
|
4077
|
-
\u274C \u83B7\u53D6\u63D2\u4EF6\u76EE\u5F55\u5931\u8D25\uFF1A${e.message}
|
|
4078
|
-
|
|
4404
|
+
\u274C \u83B7\u53D6\u63D2\u4EF6\u76EE\u5F55\u5931\u8D25\uFF1A${e.message}
|
|
4405
|
+
`);
|
|
4079
4406
|
process.exit(1);
|
|
4080
4407
|
return;
|
|
4081
4408
|
}
|
|
@@ -4101,7 +4428,8 @@ async function runPluginsCatalog(opts) {
|
|
|
4101
4428
|
{ key: "name", header: "\u540D\u79F0" },
|
|
4102
4429
|
{ key: "new_version", header: "\u76EE\u5F55\u7248\u672C" },
|
|
4103
4430
|
{ key: "installed", header: "\u5DF2\u88C5" },
|
|
4104
|
-
{ key: "active", header: "\u542F\u7528" }
|
|
4431
|
+
{ key: "active", header: "\u542F\u7528" },
|
|
4432
|
+
{ key: "update_available", header: "\u53EF\u66F4\u65B0" }
|
|
4105
4433
|
];
|
|
4106
4434
|
console.log(`
|
|
4107
4435
|
${site.name} \u53EF\u5B89\u88C5\u76EE\u5F55\uFF08${items.length}\uFF09
|
|
@@ -4112,68 +4440,991 @@ ${site.name} \u53EF\u5B89\u88C5\u76EE\u5F55\uFF08${items.length}\uFF09
|
|
|
4112
4440
|
name: p.name || "-",
|
|
4113
4441
|
new_version: p.new_version || "-",
|
|
4114
4442
|
installed: p.installed ? "yes" : "no",
|
|
4115
|
-
active: p.active ? "yes" : "no"
|
|
4443
|
+
active: p.active ? "yes" : "no",
|
|
4444
|
+
update_available: p.update_available ? "yes" : "no"
|
|
4116
4445
|
})),
|
|
4117
4446
|
columns
|
|
4118
4447
|
);
|
|
4119
|
-
console.log("\n\u5B89\u88C5\uFF1Asiluzan-website plugins install --site <guid> --slug <slug>\n");
|
|
4448
|
+
console.log("\n\u5B89\u88C5 / \u5347\u7EA7\uFF1Asiluzan-website plugins install --site <guid> --slug <slug>\n");
|
|
4120
4449
|
}
|
|
4121
4450
|
async function runPluginsInstall(opts) {
|
|
4122
4451
|
const slug = opts.slug?.trim() ?? "";
|
|
4123
|
-
|
|
4124
|
-
|
|
4452
|
+
const zipPath = opts.zip?.trim() ?? "";
|
|
4453
|
+
if (slug && zipPath || !slug && !zipPath) {
|
|
4454
|
+
console.error("\n\u274C \u76EE\u5F55\u63D2\u4EF6\u7528 --slug\uFF0C\u5916\u90E8\u63D2\u4EF6\u7528 --zip\uFF0C\u4E24\u8005\u53EA\u4F20\u4E00\u4E2A\n");
|
|
4455
|
+
process.exit(1);
|
|
4456
|
+
}
|
|
4457
|
+
const target = await resolveTarget2(opts);
|
|
4458
|
+
const { site, base } = target;
|
|
4459
|
+
let result;
|
|
4460
|
+
try {
|
|
4461
|
+
result = await withHelperBootstrap(opts, target, async () => {
|
|
4462
|
+
if (slug) {
|
|
4463
|
+
return apiFetch2(
|
|
4464
|
+
`${base}/wp-json/siluzan-helper/v1/plugins/install`,
|
|
4465
|
+
target.config,
|
|
4466
|
+
{ method: "POST", body: JSON.stringify({ slug }) },
|
|
4467
|
+
opts.verbose
|
|
4468
|
+
);
|
|
4469
|
+
}
|
|
4470
|
+
const zip = readZipPayload(zipPath);
|
|
4471
|
+
return apiFetch2(
|
|
4472
|
+
`${base}/wp-json/siluzan-helper/v1/plugins/install-zip`,
|
|
4473
|
+
target.config,
|
|
4474
|
+
{ method: "POST", body: JSON.stringify(zip) },
|
|
4475
|
+
opts.verbose
|
|
4476
|
+
);
|
|
4477
|
+
});
|
|
4478
|
+
} catch (e) {
|
|
4479
|
+
console.error(`
|
|
4480
|
+
\u274C \u5B89\u88C5\u5931\u8D25\uFF1A${e.message}
|
|
4481
|
+
`);
|
|
4482
|
+
process.exit(1);
|
|
4483
|
+
return;
|
|
4484
|
+
}
|
|
4485
|
+
printActionResult(result, site, base, "\u63D2\u4EF6\u5DF2\u5B89\u88C5\u5E76\u542F\u7528");
|
|
4486
|
+
await runPluginsList({
|
|
4487
|
+
site: site.guid || opts.site,
|
|
4488
|
+
url: site.url,
|
|
4489
|
+
verbose: opts.verbose,
|
|
4490
|
+
exitOnError: false
|
|
4491
|
+
});
|
|
4492
|
+
}
|
|
4493
|
+
async function runPluginsUpdate(opts) {
|
|
4494
|
+
const plugin = opts.plugin?.trim() ?? "";
|
|
4495
|
+
if (!plugin) {
|
|
4496
|
+
console.error("\n\u274C \u8BF7\u63D0\u4F9B --plugin\uFF08\u5148 plugins list \u770B plugin \u5217\uFF09\n");
|
|
4497
|
+
process.exit(1);
|
|
4498
|
+
}
|
|
4499
|
+
const target = await resolveTarget2(opts);
|
|
4500
|
+
const { site, base } = target;
|
|
4501
|
+
const zipPath = opts.zip?.trim() ?? "";
|
|
4502
|
+
const body = { plugin };
|
|
4503
|
+
if (zipPath) {
|
|
4504
|
+
const zip = readZipPayload(zipPath);
|
|
4505
|
+
body.zip_base64 = zip.zip_base64;
|
|
4506
|
+
body.filename = zip.filename;
|
|
4507
|
+
}
|
|
4508
|
+
let result;
|
|
4509
|
+
try {
|
|
4510
|
+
result = await withHelperBootstrap(
|
|
4511
|
+
opts,
|
|
4512
|
+
target,
|
|
4513
|
+
() => apiFetch2(
|
|
4514
|
+
`${base}/wp-json/siluzan-helper/v1/plugins/update`,
|
|
4515
|
+
target.config,
|
|
4516
|
+
{ method: "POST", body: JSON.stringify(body) },
|
|
4517
|
+
opts.verbose
|
|
4518
|
+
)
|
|
4519
|
+
);
|
|
4520
|
+
} catch (e) {
|
|
4521
|
+
const msg = e.message || "";
|
|
4522
|
+
if (/HTTP 409/.test(msg) && /no_package/i.test(msg)) {
|
|
4523
|
+
console.error(`
|
|
4524
|
+
\u274C ${msg}`);
|
|
4525
|
+
console.error(" \u76EE\u5F55\u548C WordPress.org \u90FD\u6CA1\u6709\u5B89\u88C5\u5305\u3002\u5916\u90E8\u63D2\u4EF6\u8BF7\u5E26 --zip \u518D\u5347\u7EA7\u3002\n");
|
|
4526
|
+
process.exit(1);
|
|
4527
|
+
}
|
|
4528
|
+
console.error(`
|
|
4529
|
+
\u274C \u5347\u7EA7\u5931\u8D25\uFF1A${msg}
|
|
4530
|
+
`);
|
|
4531
|
+
process.exit(1);
|
|
4532
|
+
return;
|
|
4533
|
+
}
|
|
4534
|
+
printActionResult(result, site, base, "\u63D2\u4EF6\u5DF2\u5347\u7EA7");
|
|
4535
|
+
await runPluginsList({
|
|
4536
|
+
site: site.guid || opts.site,
|
|
4537
|
+
url: site.url,
|
|
4538
|
+
verbose: opts.verbose,
|
|
4539
|
+
exitOnError: false
|
|
4540
|
+
});
|
|
4541
|
+
}
|
|
4542
|
+
async function runHelperStatus(opts) {
|
|
4543
|
+
const { config, site, base } = await resolveTarget2(opts);
|
|
4544
|
+
let status;
|
|
4545
|
+
try {
|
|
4546
|
+
status = await apiFetch2(
|
|
4547
|
+
`${base}/wp-json/wposso/v1/helper/status`,
|
|
4548
|
+
config,
|
|
4549
|
+
{},
|
|
4550
|
+
opts.verbose
|
|
4551
|
+
);
|
|
4552
|
+
} catch (e) {
|
|
4553
|
+
const msg = e.message || "";
|
|
4554
|
+
console.error(`
|
|
4555
|
+
\u274C \u65E0\u6CD5\u8BFB\u53D6 helper \u72B6\u6001\uFF1A${msg}`);
|
|
4556
|
+
if (isRouteMissing(e) || /HTTP 404/.test(msg)) {
|
|
4557
|
+
console.error(" \u7AD9\u70B9 oauth2 \u8FD8\u6CA1\u6709\u5F15\u5BFC\u5347\u7EA7\u63A5\u53E3\uFF0C\u9700\u8981\u5148\u505A SiteMan \u955C\u50CF\u5347\u7EA7\u3002\n");
|
|
4558
|
+
}
|
|
4125
4559
|
process.exit(1);
|
|
4560
|
+
return;
|
|
4561
|
+
}
|
|
4562
|
+
if (opts.json) {
|
|
4563
|
+
console.log(JSON.stringify({ site: { guid: site.guid, name: site.name, url: site.url }, ...status }, null, 2));
|
|
4564
|
+
return;
|
|
4126
4565
|
}
|
|
4127
|
-
|
|
4128
|
-
|
|
4566
|
+
console.log(`
|
|
4567
|
+
${site.name} helper \u72B6\u6001`);
|
|
4568
|
+
console.log(` \u5DF2\u5B89\u88C5 : ${status.helper_installed ? "yes" : "no"}`);
|
|
4569
|
+
console.log(` \u5DF2\u542F\u7528 : ${status.helper_active ? "yes" : "no"}`);
|
|
4570
|
+
console.log(` \u7248\u672C : ${status.helper_version || "-"}`);
|
|
4571
|
+
console.log(` helper REST: ${status.helper_rest_available ? "yes" : "no"}`);
|
|
4572
|
+
console.log(` \u955C\u50CF zip : ${status.bootstrap_zip || "-"}`);
|
|
4573
|
+
console.log(` \u53EF\u5F15\u5BFC\u5347\u7EA7 : ${status.can_upgrade ? "yes" : "no"}
|
|
4574
|
+
`);
|
|
4575
|
+
}
|
|
4576
|
+
async function runUpdateHelper(opts, fromBootstrap = false) {
|
|
4577
|
+
const { config, site, base } = await resolveTarget2(opts);
|
|
4129
4578
|
let result;
|
|
4130
4579
|
try {
|
|
4131
4580
|
result = await apiFetch2(
|
|
4132
|
-
|
|
4581
|
+
`${base}/wp-json/wposso/v1/helper/upgrade`,
|
|
4133
4582
|
config,
|
|
4134
|
-
{ method: "POST", body: JSON.stringify({
|
|
4583
|
+
{ method: "POST", body: JSON.stringify({}) },
|
|
4135
4584
|
opts.verbose
|
|
4136
4585
|
);
|
|
4137
4586
|
} catch (e) {
|
|
4587
|
+
const msg = e.message || "";
|
|
4138
4588
|
console.error(`
|
|
4139
|
-
\u274C \
|
|
4589
|
+
\u274C helper \u5347\u7EA7\u5931\u8D25\uFF1A${msg}`);
|
|
4590
|
+
if (isRouteMissing(e)) {
|
|
4591
|
+
console.error(" \u7AD9\u70B9 oauth2 \u8FD8\u6CA1\u6709\u5F15\u5BFC\u5347\u7EA7\u63A5\u53E3\uFF0C\u9700\u8981\u5148\u505A SiteMan \u955C\u50CF\u5347\u7EA7\u3002");
|
|
4592
|
+
} else if (/HTTP 409/.test(msg)) {
|
|
4593
|
+
console.error(" \u5F53\u524D\u955C\u50CF\u91CC\u6CA1\u6709 siluzan-helper-plugin.1.0.*.zip\u3002");
|
|
4594
|
+
}
|
|
4595
|
+
console.error();
|
|
4596
|
+
process.exit(1);
|
|
4597
|
+
return;
|
|
4598
|
+
}
|
|
4599
|
+
printActionResult(result, site, base, "helper \u5DF2\u4ECE\u955C\u50CF\u672C\u5730 zip \u5347\u7EA7");
|
|
4600
|
+
if (!fromBootstrap) {
|
|
4601
|
+
await runHelperStatus({ site: site.guid || opts.site, url: site.url, verbose: opts.verbose });
|
|
4602
|
+
}
|
|
4603
|
+
}
|
|
4604
|
+
async function findInstalledPlugin(base, config, pluginArg, verbose = false) {
|
|
4605
|
+
const plugins = await apiFetch2(`${base}/wp-json/wp/v2/plugins`, config, {}, verbose);
|
|
4606
|
+
if (!Array.isArray(plugins)) {
|
|
4607
|
+
throw new Error("\u7AD9\u70B9\u8FD4\u56DE\u7684\u63D2\u4EF6\u5217\u8868\u683C\u5F0F\u5F02\u5E38");
|
|
4608
|
+
}
|
|
4609
|
+
const needle = pluginKey(pluginArg);
|
|
4610
|
+
const exact = plugins.find((p) => pluginKey(p.plugin || "") === needle);
|
|
4611
|
+
if (exact?.plugin) return exact;
|
|
4612
|
+
const hits = plugins.filter((p) => {
|
|
4613
|
+
const key = pluginKey(p.plugin || "");
|
|
4614
|
+
return key === needle || key.startsWith(`${needle}/`) || key.endsWith(`/${needle}`);
|
|
4615
|
+
});
|
|
4616
|
+
if (hits.length === 1 && hits[0].plugin) return hits[0];
|
|
4617
|
+
if (hits.length > 1) {
|
|
4618
|
+
const names = hits.map((p) => p.plugin).join("\u3001");
|
|
4619
|
+
throw new Error(`\u300C${pluginArg}\u300D\u5339\u914D\u5230\u591A\u4E2A\u63D2\u4EF6\uFF0C\u8BF7\u6539\u7528\u5B8C\u6574 --plugin\uFF1A${names}`);
|
|
4620
|
+
}
|
|
4621
|
+
throw new Error(`\u7AD9\u70B9\u4E0A\u6CA1\u6709\u63D2\u4EF6\u300C${pluginArg}\u300D\uFF0C\u5148 plugins list \u770B plugin \u5217`);
|
|
4622
|
+
}
|
|
4623
|
+
async function runPluginsUninstall(opts) {
|
|
4624
|
+
const pluginArg = opts.plugin?.trim() ?? "";
|
|
4625
|
+
if (!pluginArg) {
|
|
4626
|
+
console.error("\n\u274C \u8BF7\u63D0\u4F9B --plugin\uFF08\u5148 plugins list \u770B plugin \u5217\uFF09\n");
|
|
4627
|
+
process.exit(1);
|
|
4628
|
+
}
|
|
4629
|
+
if (isProtectedPlugin(pluginArg)) {
|
|
4630
|
+
console.error("\n\u274C \u4E0D\u80FD\u5378\u8F7D siluzan-helper-plugin \u6216 wp-oauth2\uFF0C\u5378\u6389\u540E\u7AD9\u70B9\u65E0\u6CD5\u518D\u7528 Skill \u7BA1\u7406\u3002\n");
|
|
4631
|
+
process.exit(1);
|
|
4632
|
+
}
|
|
4633
|
+
const target = await resolveTarget2(opts);
|
|
4634
|
+
const { site, base } = target;
|
|
4635
|
+
let current;
|
|
4636
|
+
try {
|
|
4637
|
+
current = await findInstalledPlugin(base, target.config, pluginArg, opts.verbose);
|
|
4638
|
+
} catch (e) {
|
|
4639
|
+
console.error(`
|
|
4640
|
+
\u274C ${e.message}
|
|
4140
4641
|
`);
|
|
4141
4642
|
process.exit(1);
|
|
4142
4643
|
return;
|
|
4143
4644
|
}
|
|
4144
|
-
|
|
4645
|
+
const plugin = current.plugin || pluginArg;
|
|
4646
|
+
if (isProtectedPlugin(plugin)) {
|
|
4647
|
+
console.error("\n\u274C \u4E0D\u80FD\u5378\u8F7D siluzan-helper-plugin \u6216 wp-oauth2\uFF0C\u5378\u6389\u540E\u7AD9\u70B9\u65E0\u6CD5\u518D\u7528 Skill \u7BA1\u7406\u3002\n");
|
|
4648
|
+
process.exit(1);
|
|
4649
|
+
}
|
|
4650
|
+
const restPath = `${base}/wp-json/wp/v2/plugins/${wpPluginRestPath(plugin)}`;
|
|
4651
|
+
try {
|
|
4652
|
+
if (current.status === "active") {
|
|
4653
|
+
console.log(`\u5148\u505C\u7528 ${plugin} \u2026`);
|
|
4654
|
+
await apiFetch2(
|
|
4655
|
+
restPath,
|
|
4656
|
+
target.config,
|
|
4657
|
+
{ method: "POST", body: JSON.stringify({ status: "inactive" }) },
|
|
4658
|
+
opts.verbose
|
|
4659
|
+
);
|
|
4660
|
+
}
|
|
4661
|
+
await apiFetch2(restPath, target.config, { method: "DELETE" }, opts.verbose);
|
|
4662
|
+
} catch (e) {
|
|
4145
4663
|
console.error(`
|
|
4146
|
-
\u274C
|
|
4664
|
+
\u274C \u5378\u8F7D\u5931\u8D25\uFF1A${e.message}
|
|
4147
4665
|
`);
|
|
4148
4666
|
process.exit(1);
|
|
4667
|
+
return;
|
|
4149
4668
|
}
|
|
4150
|
-
console.log(
|
|
4151
|
-
|
|
4152
|
-
if (result.message) console.log(` \u8BF4\u660E : ${result.message}`);
|
|
4669
|
+
console.log(`
|
|
4670
|
+
\u2705 \u5DF2\u5378\u8F7D ${plugin}`);
|
|
4153
4671
|
console.log(` \u7AD9\u70B9 : ${site.name} (${base})
|
|
4154
4672
|
`);
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4673
|
+
await runPluginsList({
|
|
4674
|
+
site: site.guid || opts.site,
|
|
4675
|
+
url: site.url,
|
|
4676
|
+
verbose: opts.verbose,
|
|
4677
|
+
exitOnError: false
|
|
4678
|
+
});
|
|
4159
4679
|
}
|
|
4160
4680
|
function register7(program2) {
|
|
4161
|
-
const plugins = program2.command("plugins").description("WordPress \u63D2\u4EF6\uFF1A\u5217\u51FA\u3001\u76EE\u5F55\u3001\u5B89\u88C5");
|
|
4162
|
-
plugins.command("list").description("\u5217\u51FA\u7AD9\u70B9\u5DF2\u5B89\u88C5\u63D2\u4EF6").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
4681
|
+
const plugins = program2.command("plugins").description("WordPress \u63D2\u4EF6\uFF1A\u5217\u51FA\u3001\u76EE\u5F55\u3001\u5B89\u88C5\u3001\u5347\u7EA7\u3001\u5378\u8F7D");
|
|
4682
|
+
plugins.command("list").description("\u5217\u51FA\u7AD9\u70B9\u5DF2\u5B89\u88C5\u7684\u5168\u90E8\u63D2\u4EF6").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
4163
4683
|
await runPluginsList(opts);
|
|
4164
4684
|
});
|
|
4165
|
-
plugins.command("catalog").description("\u5217\u51FA\u4E1D\u8DEF\u8D5E\u63D2\u4EF6\u76EE\u5F55\uFF08\u53EF\u5B89\u88C5\
|
|
4685
|
+
plugins.command("catalog").description("\u5217\u51FA\u4E1D\u8DEF\u8D5E\u63D2\u4EF6\u76EE\u5F55\uFF08\u53EF\u5B89\u88C5 / \u53EF\u5347\u7EA7\uFF09").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
4166
4686
|
await runPluginsCatalog(opts);
|
|
4167
4687
|
});
|
|
4168
|
-
plugins.command("install").description("\
|
|
4688
|
+
plugins.command("install").description("\u5B89\u88C5\u5E76\u542F\u7528\u63D2\u4EF6\uFF1A\u76EE\u5F55\u7528 --slug\uFF0C\u5916\u90E8\u7528 --zip").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").option("--slug <slug>", "\u4E1D\u8DEF\u8D5E\u76EE\u5F55\u4E2D\u7684 slug \u6216 plugin \u8DEF\u5F84").option("--zip <file>", "\u5916\u90E8\u63D2\u4EF6 zip\uFF08\u6839\u76EE\u5F55\u5FC5\u987B\u662F\u63D2\u4EF6\u76EE\u5F55\uFF09").option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
4169
4689
|
await runPluginsInstall(opts);
|
|
4170
4690
|
});
|
|
4691
|
+
plugins.command("update").description("\u5347\u7EA7\u5DF2\u88C5\u63D2\u4EF6\uFF1A\u6709\u76EE\u5F55/\u5B98\u65B9\u5305\u5219\u4E0D\u7528 zip\uFF0C\u5916\u90E8\u63D2\u4EF6\u5E26 --zip").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").requiredOption("--plugin <plugin>", "\u5DF2\u88C5\u63D2\u4EF6\u8DEF\u5F84\uFF0C\u5982 theme-manage/theme-manage").option("--zip <file>", "\u5916\u90E8\u63D2\u4EF6\u5347\u7EA7\u5305").option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
4692
|
+
await runPluginsUpdate(opts);
|
|
4693
|
+
});
|
|
4694
|
+
plugins.command("uninstall").description("\u5378\u8F7D\u5DF2\u88C5\u63D2\u4EF6\uFF08\u5148\u505C\u7528\u518D\u5220\u9664\uFF1Bhelper / oauth2 \u4E0D\u5141\u8BB8\uFF09").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").requiredOption("--plugin <plugin>", "\u5DF2\u88C5\u63D2\u4EF6\u8DEF\u5F84\uFF0C\u5982 dummy-e2e-plugin/dummy-e2e-plugin").option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
4695
|
+
await runPluginsUninstall(opts);
|
|
4696
|
+
});
|
|
4697
|
+
plugins.command("helper-status").description("\u67E5\u770B\u7AD9\u70B9 helper \u4E0E\u955C\u50CF\u672C\u5730 zip").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
4698
|
+
await runHelperStatus(opts);
|
|
4699
|
+
});
|
|
4700
|
+
plugins.command("update-helper").description("\u7528\u955C\u50CF\u91CC\u7684 siluzan-helper-plugin.1.0.*.zip \u5347\u7EA7 helper\uFF08\u5199\u64CD\u4F5C\uFF09").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
4701
|
+
await runUpdateHelper(opts);
|
|
4702
|
+
});
|
|
4703
|
+
}
|
|
4704
|
+
|
|
4705
|
+
// src/commands/content.ts
|
|
4706
|
+
import * as fs7 from "fs";
|
|
4707
|
+
|
|
4708
|
+
// src/types/wp-rest.ts
|
|
4709
|
+
function wpRenderedText(value) {
|
|
4710
|
+
if (!value) return "";
|
|
4711
|
+
if (typeof value === "string") return value;
|
|
4712
|
+
return value.raw || value.rendered || "";
|
|
4713
|
+
}
|
|
4714
|
+
|
|
4715
|
+
// src/commands/content.ts
|
|
4716
|
+
function parseIdList(raw) {
|
|
4717
|
+
if (!raw?.trim()) return void 0;
|
|
4718
|
+
return raw.split(",").map((s) => Number(s.trim())).filter((n) => Number.isFinite(n) && n > 0);
|
|
4719
|
+
}
|
|
4720
|
+
function printPost(item, restBase) {
|
|
4721
|
+
console.log(`
|
|
4722
|
+
\u2705 ${restBase} #${item.id}`);
|
|
4723
|
+
console.log(` \u6807\u9898 : ${wpRenderedText(item.title) || "-"}`);
|
|
4724
|
+
console.log(` \u72B6\u6001 : ${item.status || "-"}`);
|
|
4725
|
+
console.log(` slug : ${item.slug || "-"}`);
|
|
4726
|
+
if (item.link) console.log(` \u94FE\u63A5 : ${item.link}`);
|
|
4727
|
+
console.log();
|
|
4728
|
+
}
|
|
4729
|
+
async function runContentTypes(opts) {
|
|
4730
|
+
const target = await resolveTarget(opts);
|
|
4731
|
+
let types;
|
|
4732
|
+
try {
|
|
4733
|
+
types = await apiFetch2(
|
|
4734
|
+
wpV2(target.base, "/types?context=edit"),
|
|
4735
|
+
target.config,
|
|
4736
|
+
{},
|
|
4737
|
+
opts.verbose
|
|
4738
|
+
);
|
|
4739
|
+
} catch (e) {
|
|
4740
|
+
console.error(`
|
|
4741
|
+
\u274C \u83B7\u53D6\u5185\u5BB9\u7C7B\u578B\u5931\u8D25\uFF1A${e.message}
|
|
4742
|
+
`);
|
|
4743
|
+
process.exit(1);
|
|
4744
|
+
return;
|
|
4745
|
+
}
|
|
4746
|
+
const rows = Object.entries(types || {}).map(([slug, info]) => ({
|
|
4747
|
+
slug,
|
|
4748
|
+
rest_base: info.rest_base || slug,
|
|
4749
|
+
name: info.name || slug
|
|
4750
|
+
}));
|
|
4751
|
+
if (opts.json) {
|
|
4752
|
+
console.log(JSON.stringify({ site: target.site, types: rows }, null, 2));
|
|
4753
|
+
return;
|
|
4754
|
+
}
|
|
4755
|
+
console.log(`
|
|
4756
|
+
${target.site.name} \u53EF REST \u7BA1\u7406\u7684\u5185\u5BB9\u7C7B\u578B\uFF08${rows.length}\uFF09
|
|
4757
|
+
`);
|
|
4758
|
+
printCliTable(rows, [
|
|
4759
|
+
{ key: "slug", header: "slug" },
|
|
4760
|
+
{ key: "rest_base", header: "rest_base\uFF08--type\uFF09" },
|
|
4761
|
+
{ key: "name", header: "\u540D\u79F0" }
|
|
4762
|
+
]);
|
|
4763
|
+
console.log("\n\u9875\u9762\u6B63\u6587\u8BF7\u7528 pages add/update\uFF1B\u5176\u5B83\u7C7B\u578B\u7528 content add --type <rest_base>\n");
|
|
4764
|
+
}
|
|
4765
|
+
async function runContentList(opts) {
|
|
4766
|
+
const typeArg = opts.type?.trim() || "posts";
|
|
4767
|
+
const target = await resolveTarget(opts);
|
|
4768
|
+
let restBase;
|
|
4769
|
+
try {
|
|
4770
|
+
restBase = await resolveTypeRestBase(target, typeArg, opts.verbose);
|
|
4771
|
+
} catch (e) {
|
|
4772
|
+
console.error(`
|
|
4773
|
+
\u274C ${e.message}
|
|
4774
|
+
`);
|
|
4775
|
+
process.exit(1);
|
|
4776
|
+
return;
|
|
4777
|
+
}
|
|
4778
|
+
const status = opts.status?.trim() || "publish,draft,private,pending";
|
|
4779
|
+
const api = wpV2(target.base, `/${restBase}?per_page=100&status=${encodeURIComponent(status)}`);
|
|
4780
|
+
let items;
|
|
4781
|
+
try {
|
|
4782
|
+
items = await apiFetch2(api, target.config, {}, opts.verbose);
|
|
4783
|
+
} catch (e) {
|
|
4784
|
+
console.error(`
|
|
4785
|
+
\u274C \u83B7\u53D6 ${restBase} \u5931\u8D25\uFF1A${e.message}
|
|
4786
|
+
`);
|
|
4787
|
+
process.exit(1);
|
|
4788
|
+
return;
|
|
4789
|
+
}
|
|
4790
|
+
if (!Array.isArray(items)) {
|
|
4791
|
+
console.error("\n\u274C \u7AD9\u70B9\u8FD4\u56DE\u7684\u5217\u8868\u683C\u5F0F\u5F02\u5E38\n");
|
|
4792
|
+
process.exit(1);
|
|
4793
|
+
}
|
|
4794
|
+
if (opts.json) {
|
|
4795
|
+
console.log(
|
|
4796
|
+
JSON.stringify(
|
|
4797
|
+
{
|
|
4798
|
+
site: { guid: target.site.guid, name: target.site.name, url: target.site.url },
|
|
4799
|
+
type: restBase,
|
|
4800
|
+
total: items.length,
|
|
4801
|
+
items: items.map((p) => ({
|
|
4802
|
+
id: p.id,
|
|
4803
|
+
title: wpRenderedText(p.title),
|
|
4804
|
+
status: p.status ?? "",
|
|
4805
|
+
slug: p.slug ?? "",
|
|
4806
|
+
link: p.link ?? "",
|
|
4807
|
+
modified: p.modified ?? ""
|
|
4808
|
+
}))
|
|
4809
|
+
},
|
|
4810
|
+
null,
|
|
4811
|
+
2
|
|
4812
|
+
)
|
|
4813
|
+
);
|
|
4814
|
+
return;
|
|
4815
|
+
}
|
|
4816
|
+
if (items.length === 0) {
|
|
4817
|
+
console.log(`
|
|
4818
|
+
${target.site.name} \u6CA1\u6709 ${restBase}\u3002
|
|
4819
|
+
`);
|
|
4820
|
+
return;
|
|
4821
|
+
}
|
|
4822
|
+
const columns = [
|
|
4823
|
+
{ key: "id", header: "id" },
|
|
4824
|
+
{ key: "title", header: "\u6807\u9898" },
|
|
4825
|
+
{ key: "status", header: "\u72B6\u6001" },
|
|
4826
|
+
{ key: "slug", header: "slug" },
|
|
4827
|
+
{ key: "link", header: "\u94FE\u63A5" }
|
|
4828
|
+
];
|
|
4829
|
+
console.log(`
|
|
4830
|
+
${target.site.name} ${restBase}\uFF08${items.length}\uFF09
|
|
4831
|
+
`);
|
|
4832
|
+
printCliTable(
|
|
4833
|
+
items.map((p) => ({
|
|
4834
|
+
id: String(p.id),
|
|
4835
|
+
title: wpRenderedText(p.title) || "(\u65E0\u6807\u9898)",
|
|
4836
|
+
status: p.status ?? "-",
|
|
4837
|
+
slug: p.slug ?? "-",
|
|
4838
|
+
link: p.link ?? "-"
|
|
4839
|
+
})),
|
|
4840
|
+
columns
|
|
4841
|
+
);
|
|
4842
|
+
console.log();
|
|
4843
|
+
}
|
|
4844
|
+
async function runContentGet(opts) {
|
|
4845
|
+
const id = Number(opts.id);
|
|
4846
|
+
if (!Number.isFinite(id) || id <= 0) {
|
|
4847
|
+
console.error("\n\u274C \u8BF7\u63D0\u4F9B\u6709\u6548 --id\n");
|
|
4848
|
+
process.exit(1);
|
|
4849
|
+
}
|
|
4850
|
+
const target = await resolveTarget(opts);
|
|
4851
|
+
const restBase = await resolveTypeRestBase(target, opts.type?.trim() || "posts", opts.verbose);
|
|
4852
|
+
const item = await apiFetch2(
|
|
4853
|
+
wpV2(target.base, `/${restBase}/${id}?context=edit`),
|
|
4854
|
+
target.config,
|
|
4855
|
+
{},
|
|
4856
|
+
opts.verbose
|
|
4857
|
+
).catch((e) => {
|
|
4858
|
+
console.error(`
|
|
4859
|
+
\u274C \u83B7\u53D6\u5931\u8D25\uFF1A${e.message}
|
|
4860
|
+
`);
|
|
4861
|
+
process.exit(1);
|
|
4862
|
+
});
|
|
4863
|
+
if (opts.json) {
|
|
4864
|
+
console.log(JSON.stringify(item, null, 2));
|
|
4865
|
+
return;
|
|
4866
|
+
}
|
|
4867
|
+
console.log(`
|
|
4868
|
+
${restBase} #${item.id}`);
|
|
4869
|
+
console.log(` \u6807\u9898 : ${wpRenderedText(item.title) || "-"}`);
|
|
4870
|
+
console.log(` \u72B6\u6001 : ${item.status || "-"}`);
|
|
4871
|
+
console.log(` slug : ${item.slug || "-"}`);
|
|
4872
|
+
console.log(` \u94FE\u63A5 : ${item.link || "-"}`);
|
|
4873
|
+
if (item.featured_media) console.log(` \u7279\u8272\u56FE : ${item.featured_media}`);
|
|
4874
|
+
const excerpt = wpRenderedText(item.excerpt);
|
|
4875
|
+
if (excerpt) console.log(` \u6458\u8981 : ${excerpt.slice(0, 120)}`);
|
|
4876
|
+
console.log();
|
|
4877
|
+
}
|
|
4878
|
+
async function runContentWrite(mode, opts) {
|
|
4879
|
+
const typeArg = opts.type?.trim() || "posts";
|
|
4880
|
+
if (typeArg === "page" || typeArg === "pages") {
|
|
4881
|
+
console.error("\n\u274C \u9875\u9762\u6B63\u6587\u8BF7\u7528 pages add / pages update\uFF08Zion visual-edit\uFF09\u3002");
|
|
4882
|
+
console.error(" \u53EA\u6539 slug/\u72B6\u6001/\u56DE\u6536\u7AD9\u7528 pages meta / pages trash\u3002\n");
|
|
4883
|
+
process.exit(1);
|
|
4884
|
+
}
|
|
4885
|
+
const target = await resolveTarget(opts);
|
|
4886
|
+
const restBase = await resolveTypeRestBase(target, typeArg, opts.verbose);
|
|
4887
|
+
const content = opts.contentFile ? fs7.readFileSync(opts.contentFile, "utf8") : opts.content ?? "";
|
|
4888
|
+
if (mode === "add" && !opts.title?.trim() && !content.trim()) {
|
|
4889
|
+
console.error("\n\u274C \u65B0\u589E\u81F3\u5C11\u8981 --title \u6216 --content / --content-file\n");
|
|
4890
|
+
process.exit(1);
|
|
4891
|
+
}
|
|
4892
|
+
const body = {};
|
|
4893
|
+
if (opts.title?.trim()) body.title = opts.title.trim();
|
|
4894
|
+
if (content.trim()) body.content = content;
|
|
4895
|
+
if (opts.status?.trim()) body.status = opts.status.trim();
|
|
4896
|
+
if (opts.slug?.trim()) body.slug = opts.slug.trim();
|
|
4897
|
+
if (opts.excerpt?.trim()) body.excerpt = opts.excerpt.trim();
|
|
4898
|
+
const featured = Number(opts.featuredMedia);
|
|
4899
|
+
if (Number.isFinite(featured) && featured > 0) body.featured_media = featured;
|
|
4900
|
+
const cats = parseIdList(opts.categories);
|
|
4901
|
+
if (cats) body.categories = cats;
|
|
4902
|
+
const tags = parseIdList(opts.tags);
|
|
4903
|
+
if (tags) body.tags = tags;
|
|
4904
|
+
if (mode === "update") {
|
|
4905
|
+
const id = Number(opts.id);
|
|
4906
|
+
if (!Number.isFinite(id) || id <= 0) {
|
|
4907
|
+
console.error("\n\u274C \u66F4\u65B0\u5FC5\u987B\u63D0\u4F9B --id\uFF08\u5148 content list\uFF09\n");
|
|
4908
|
+
process.exit(1);
|
|
4909
|
+
}
|
|
4910
|
+
if (Object.keys(body).length === 0) {
|
|
4911
|
+
console.error("\n\u274C \u6CA1\u6709\u8981\u6539\u7684\u5B57\u6BB5\n");
|
|
4912
|
+
process.exit(1);
|
|
4913
|
+
}
|
|
4914
|
+
const item2 = await apiFetch2(
|
|
4915
|
+
wpV2(target.base, `/${restBase}/${id}`),
|
|
4916
|
+
target.config,
|
|
4917
|
+
{ method: "POST", body: JSON.stringify(body) },
|
|
4918
|
+
opts.verbose
|
|
4919
|
+
).catch((e) => {
|
|
4920
|
+
console.error(`
|
|
4921
|
+
\u274C \u66F4\u65B0\u5931\u8D25\uFF1A${e.message}
|
|
4922
|
+
`);
|
|
4923
|
+
process.exit(1);
|
|
4924
|
+
});
|
|
4925
|
+
printPost(item2, restBase);
|
|
4926
|
+
return;
|
|
4927
|
+
}
|
|
4928
|
+
const item = await apiFetch2(
|
|
4929
|
+
wpV2(target.base, `/${restBase}`),
|
|
4930
|
+
target.config,
|
|
4931
|
+
{ method: "POST", body: JSON.stringify(body) },
|
|
4932
|
+
opts.verbose
|
|
4933
|
+
).catch((e) => {
|
|
4934
|
+
console.error(`
|
|
4935
|
+
\u274C \u65B0\u589E\u5931\u8D25\uFF1A${e.message}
|
|
4936
|
+
`);
|
|
4937
|
+
process.exit(1);
|
|
4938
|
+
});
|
|
4939
|
+
printPost(item, restBase);
|
|
4940
|
+
}
|
|
4941
|
+
async function runContentTrash(opts) {
|
|
4942
|
+
const id = Number(opts.id);
|
|
4943
|
+
if (!Number.isFinite(id) || id <= 0) {
|
|
4944
|
+
console.error("\n\u274C \u8BF7\u63D0\u4F9B --id\n");
|
|
4945
|
+
process.exit(1);
|
|
4946
|
+
}
|
|
4947
|
+
const target = await resolveTarget(opts);
|
|
4948
|
+
const restBase = await resolveTypeRestBase(target, opts.type?.trim() || "posts", opts.verbose);
|
|
4949
|
+
const qs = opts.force ? "?force=true" : "";
|
|
4950
|
+
const item = await apiFetch2(
|
|
4951
|
+
wpV2(target.base, `/${restBase}/${id}${qs}`),
|
|
4952
|
+
target.config,
|
|
4953
|
+
{ method: "DELETE" },
|
|
4954
|
+
opts.verbose
|
|
4955
|
+
).catch((e) => {
|
|
4956
|
+
console.error(`
|
|
4957
|
+
\u274C \u5220\u9664\u5931\u8D25\uFF1A${e.message}
|
|
4958
|
+
`);
|
|
4959
|
+
process.exit(1);
|
|
4960
|
+
});
|
|
4961
|
+
console.log(opts.force ? `
|
|
4962
|
+
\u2705 \u5DF2\u6C38\u4E45\u5220\u9664 ${restBase} #${id}
|
|
4963
|
+
` : `
|
|
4964
|
+
\u2705 \u5DF2\u79FB\u5165\u56DE\u6536\u7AD9 ${restBase} #${id}\uFF08status=${item.status || "trash"}\uFF09
|
|
4965
|
+
`);
|
|
4966
|
+
}
|
|
4967
|
+
function register8(program2) {
|
|
4968
|
+
const content = program2.command("content").description("\u901A\u7528\u5185\u5BB9\uFF1A\u6587\u7AE0/\u4EA7\u54C1\u7B49 REST \u7C7B\u578B\uFF08\u9875\u9762\u6B63\u6587\u8BF7\u7528 pages\uFF09");
|
|
4969
|
+
content.command("types").description("\u5217\u51FA\u7AD9\u70B9\u53EF REST \u7BA1\u7406\u7684\u5185\u5BB9\u7C7B\u578B").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
4970
|
+
await runContentTypes(opts);
|
|
4971
|
+
});
|
|
4972
|
+
content.command("list").description("\u5217\u51FA\u67D0\u4E00\u7C7B\u578B\u7684\u5185\u5BB9").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").option("--type <restBase>", "\u7C7B\u578B rest_base\uFF0C\u9ED8\u8BA4 posts", "posts").option("--status <status>", "\u72B6\u6001\uFF0C\u9017\u53F7\u5206\u9694", "publish,draft,private,pending").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
4973
|
+
await runContentList(opts);
|
|
4974
|
+
});
|
|
4975
|
+
content.command("get").description("\u67E5\u770B\u5355\u6761\u5185\u5BB9").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").option("--type <restBase>", "\u7C7B\u578B rest_base\uFF0C\u9ED8\u8BA4 posts", "posts").requiredOption("--id <id>", "\u5185\u5BB9 ID").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
4976
|
+
await runContentGet(opts);
|
|
4977
|
+
});
|
|
4978
|
+
content.command("add").description("\u65B0\u589E\u6587\u7AE0\u6216\u5176\u5B83 CPT\uFF08\u4E0D\u8981\u7528\u6765\u52A0 Zion \u9875\u9762\uFF09").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").option("--type <restBase>", "\u7C7B\u578B rest_base\uFF0C\u9ED8\u8BA4 posts", "posts").option("-t, --title <title>", "\u6807\u9898").option("-c, --content <html>", "\u6B63\u6587 HTML").option("--content-file <path>", "\u4ECE\u6587\u4EF6\u8BFB\u6B63\u6587").option("--status <status>", "publish / draft / private", "draft").option("--slug <slug>", "\u522B\u540D").option("--excerpt <text>", "\u6458\u8981").option("--featured-media <id>", "\u7279\u8272\u56FE\u5A92\u4F53 ID").option("--categories <ids>", "\u5206\u7C7B ID\uFF0C\u9017\u53F7\u5206\u9694").option("--tags <ids>", "\u6807\u7B7E ID\uFF0C\u9017\u53F7\u5206\u9694").option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
4979
|
+
await runContentWrite("add", opts);
|
|
4980
|
+
});
|
|
4981
|
+
content.command("update").description("\u66F4\u65B0\u5DF2\u6709\u5185\u5BB9\u5B57\u6BB5").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").option("--type <restBase>", "\u7C7B\u578B rest_base\uFF0C\u9ED8\u8BA4 posts", "posts").requiredOption("--id <id>", "\u5185\u5BB9 ID").option("-t, --title <title>", "\u6807\u9898").option("-c, --content <html>", "\u6B63\u6587 HTML").option("--content-file <path>", "\u4ECE\u6587\u4EF6\u8BFB\u6B63\u6587").option("--status <status>", "publish / draft / private / pending").option("--slug <slug>", "\u522B\u540D").option("--excerpt <text>", "\u6458\u8981").option("--featured-media <id>", "\u7279\u8272\u56FE\u5A92\u4F53 ID").option("--categories <ids>", "\u5206\u7C7B ID\uFF0C\u9017\u53F7\u5206\u9694").option("--tags <ids>", "\u6807\u7B7E ID\uFF0C\u9017\u53F7\u5206\u9694").option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
4982
|
+
await runContentWrite("update", opts);
|
|
4983
|
+
});
|
|
4984
|
+
content.command("trash").description("\u79FB\u5165\u56DE\u6536\u7AD9\uFF1B\u52A0 --force \u6C38\u4E45\u5220\u9664").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").option("--type <restBase>", "\u7C7B\u578B rest_base\uFF0C\u9ED8\u8BA4 posts", "posts").requiredOption("--id <id>", "\u5185\u5BB9 ID").option("--force", "\u6C38\u4E45\u5220\u9664", false).option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
4985
|
+
await runContentTrash(opts);
|
|
4986
|
+
});
|
|
4987
|
+
}
|
|
4988
|
+
|
|
4989
|
+
// src/commands/media.ts
|
|
4990
|
+
import { existsSync as existsSync4, readFileSync as readFileSync8 } from "fs";
|
|
4991
|
+
import { basename as basename3, extname, resolve as resolve3 } from "path";
|
|
4992
|
+
var MIME_BY_EXT = {
|
|
4993
|
+
".jpg": "image/jpeg",
|
|
4994
|
+
".jpeg": "image/jpeg",
|
|
4995
|
+
".png": "image/png",
|
|
4996
|
+
".gif": "image/gif",
|
|
4997
|
+
".webp": "image/webp",
|
|
4998
|
+
".svg": "image/svg+xml",
|
|
4999
|
+
".pdf": "application/pdf",
|
|
5000
|
+
".mp4": "video/mp4",
|
|
5001
|
+
".zip": "application/zip"
|
|
5002
|
+
};
|
|
5003
|
+
var MAX_MEDIA_BYTES = 20 * 1024 * 1024;
|
|
5004
|
+
function guessMime(filename) {
|
|
5005
|
+
return MIME_BY_EXT[extname(filename).toLowerCase()] || "application/octet-stream";
|
|
5006
|
+
}
|
|
5007
|
+
async function runMediaList(opts) {
|
|
5008
|
+
const target = await resolveTarget(opts);
|
|
5009
|
+
let items;
|
|
5010
|
+
try {
|
|
5011
|
+
items = await apiFetch2(
|
|
5012
|
+
wpV2(target.base, "/media?per_page=50"),
|
|
5013
|
+
target.config,
|
|
5014
|
+
{},
|
|
5015
|
+
opts.verbose
|
|
5016
|
+
);
|
|
5017
|
+
} catch (e) {
|
|
5018
|
+
console.error(`
|
|
5019
|
+
\u274C \u83B7\u53D6\u5A92\u4F53\u5E93\u5931\u8D25\uFF1A${e.message}
|
|
5020
|
+
`);
|
|
5021
|
+
process.exit(1);
|
|
5022
|
+
return;
|
|
5023
|
+
}
|
|
5024
|
+
if (!Array.isArray(items)) {
|
|
5025
|
+
console.error("\n\u274C \u7AD9\u70B9\u8FD4\u56DE\u7684\u5A92\u4F53\u5217\u8868\u683C\u5F0F\u5F02\u5E38\n");
|
|
5026
|
+
process.exit(1);
|
|
5027
|
+
}
|
|
5028
|
+
if (opts.json) {
|
|
5029
|
+
console.log(
|
|
5030
|
+
JSON.stringify(
|
|
5031
|
+
{
|
|
5032
|
+
site: { guid: target.site.guid, name: target.site.name, url: target.site.url },
|
|
5033
|
+
total: items.length,
|
|
5034
|
+
items: items.map((m) => ({
|
|
5035
|
+
id: m.id,
|
|
5036
|
+
title: wpRenderedText(m.title),
|
|
5037
|
+
mime: m.mime_type ?? "",
|
|
5038
|
+
url: m.source_url ?? ""
|
|
5039
|
+
}))
|
|
5040
|
+
},
|
|
5041
|
+
null,
|
|
5042
|
+
2
|
|
5043
|
+
)
|
|
5044
|
+
);
|
|
5045
|
+
return;
|
|
5046
|
+
}
|
|
5047
|
+
if (items.length === 0) {
|
|
5048
|
+
console.log(`
|
|
5049
|
+
${target.site.name} \u5A92\u4F53\u5E93\u4E3A\u7A7A\u3002
|
|
5050
|
+
`);
|
|
5051
|
+
return;
|
|
5052
|
+
}
|
|
5053
|
+
console.log(`
|
|
5054
|
+
${target.site.name} \u5A92\u4F53\uFF08\u6700\u8FD1 ${items.length}\uFF09
|
|
5055
|
+
`);
|
|
5056
|
+
printCliTable(
|
|
5057
|
+
items.map((m) => ({
|
|
5058
|
+
id: String(m.id),
|
|
5059
|
+
title: wpRenderedText(m.title) || "-",
|
|
5060
|
+
mime: m.mime_type || "-",
|
|
5061
|
+
url: m.source_url || "-"
|
|
5062
|
+
})),
|
|
5063
|
+
[
|
|
5064
|
+
{ key: "id", header: "id" },
|
|
5065
|
+
{ key: "title", header: "\u6807\u9898" },
|
|
5066
|
+
{ key: "mime", header: "\u7C7B\u578B" },
|
|
5067
|
+
{ key: "url", header: "\u5730\u5740" }
|
|
5068
|
+
]
|
|
5069
|
+
);
|
|
5070
|
+
console.log();
|
|
5071
|
+
}
|
|
5072
|
+
async function runMediaGet(opts) {
|
|
5073
|
+
const id = Number(opts.id);
|
|
5074
|
+
if (!Number.isFinite(id) || id <= 0) {
|
|
5075
|
+
console.error("\n\u274C \u8BF7\u63D0\u4F9B --id\n");
|
|
5076
|
+
process.exit(1);
|
|
5077
|
+
}
|
|
5078
|
+
const target = await resolveTarget(opts);
|
|
5079
|
+
const item = await apiFetch2(
|
|
5080
|
+
wpV2(target.base, `/media/${id}`),
|
|
5081
|
+
target.config,
|
|
5082
|
+
{},
|
|
5083
|
+
opts.verbose
|
|
5084
|
+
).catch((e) => {
|
|
5085
|
+
console.error(`
|
|
5086
|
+
\u274C \u83B7\u53D6\u5A92\u4F53\u5931\u8D25\uFF1A${e.message}
|
|
5087
|
+
`);
|
|
5088
|
+
process.exit(1);
|
|
5089
|
+
});
|
|
5090
|
+
if (opts.json) {
|
|
5091
|
+
console.log(JSON.stringify(item, null, 2));
|
|
5092
|
+
return;
|
|
5093
|
+
}
|
|
5094
|
+
console.log(`
|
|
5095
|
+
\u5A92\u4F53 #${item.id}`);
|
|
5096
|
+
console.log(` \u6807\u9898 : ${wpRenderedText(item.title) || "-"}`);
|
|
5097
|
+
console.log(` \u7C7B\u578B : ${item.mime_type || "-"}`);
|
|
5098
|
+
console.log(` \u5730\u5740 : ${item.source_url || "-"}`);
|
|
5099
|
+
if (item.alt_text) console.log(` alt : ${item.alt_text}`);
|
|
5100
|
+
console.log();
|
|
5101
|
+
}
|
|
5102
|
+
async function runMediaUpload(opts) {
|
|
5103
|
+
const filePath = opts.file?.trim() ?? "";
|
|
5104
|
+
if (!filePath) {
|
|
5105
|
+
console.error("\n\u274C \u8BF7\u63D0\u4F9B --file\n");
|
|
5106
|
+
process.exit(1);
|
|
5107
|
+
}
|
|
5108
|
+
const abs = resolve3(filePath);
|
|
5109
|
+
if (!existsSync4(abs)) {
|
|
5110
|
+
console.error(`
|
|
5111
|
+
\u274C \u6587\u4EF6\u4E0D\u5B58\u5728\uFF1A${abs}
|
|
5112
|
+
`);
|
|
5113
|
+
process.exit(1);
|
|
5114
|
+
}
|
|
5115
|
+
const data = readFileSync8(abs);
|
|
5116
|
+
if (data.length > MAX_MEDIA_BYTES) {
|
|
5117
|
+
console.error("\n\u274C \u6587\u4EF6\u8D85\u8FC7 20MB\n");
|
|
5118
|
+
process.exit(1);
|
|
5119
|
+
}
|
|
5120
|
+
const filename = basename3(abs);
|
|
5121
|
+
const target = await resolveTarget(opts);
|
|
5122
|
+
const fields = {};
|
|
5123
|
+
if (opts.title?.trim()) fields.title = opts.title.trim();
|
|
5124
|
+
if (opts.alt?.trim()) fields.alt_text = opts.alt.trim();
|
|
5125
|
+
if (opts.caption?.trim()) fields.caption = opts.caption.trim();
|
|
5126
|
+
let item;
|
|
5127
|
+
try {
|
|
5128
|
+
item = await apiFetchMultipart2(
|
|
5129
|
+
wpV2(target.base, "/media"),
|
|
5130
|
+
target.config,
|
|
5131
|
+
{
|
|
5132
|
+
fields,
|
|
5133
|
+
files: [
|
|
5134
|
+
{
|
|
5135
|
+
field: "file",
|
|
5136
|
+
filename,
|
|
5137
|
+
contentType: guessMime(filename),
|
|
5138
|
+
data
|
|
5139
|
+
}
|
|
5140
|
+
]
|
|
5141
|
+
},
|
|
5142
|
+
opts.verbose
|
|
5143
|
+
);
|
|
5144
|
+
} catch (e) {
|
|
5145
|
+
console.error(`
|
|
5146
|
+
\u274C \u4E0A\u4F20\u5931\u8D25\uFF1A${e.message}
|
|
5147
|
+
`);
|
|
5148
|
+
process.exit(1);
|
|
5149
|
+
return;
|
|
5150
|
+
}
|
|
5151
|
+
console.log(`
|
|
5152
|
+
\u2705 \u5DF2\u4E0A\u4F20\u5A92\u4F53 #${item.id}`);
|
|
5153
|
+
console.log(` \u5730\u5740 : ${item.source_url || "-"}`);
|
|
5154
|
+
console.log(` \u6807\u9898 : ${wpRenderedText(item.title) || filename}`);
|
|
5155
|
+
console.log();
|
|
5156
|
+
}
|
|
5157
|
+
function register9(program2) {
|
|
5158
|
+
const media = program2.command("media").description("\u5A92\u4F53\u5E93\uFF1A\u5217\u51FA\u3001\u67E5\u770B\u3001\u4E0A\u4F20");
|
|
5159
|
+
media.command("list").description("\u5217\u51FA\u5A92\u4F53\u5E93\uFF08\u6700\u8FD1 50 \u6761\uFF09").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
5160
|
+
await runMediaList(opts);
|
|
5161
|
+
});
|
|
5162
|
+
media.command("get").description("\u67E5\u770B\u5355\u4E2A\u5A92\u4F53").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").requiredOption("--id <id>", "\u5A92\u4F53 ID").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
5163
|
+
await runMediaGet(opts);
|
|
5164
|
+
});
|
|
5165
|
+
media.command("upload").description("\u4E0A\u4F20\u672C\u5730\u6587\u4EF6\u5230\u5A92\u4F53\u5E93\uFF08\u5199\u64CD\u4F5C\uFF09").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").requiredOption("--file <path>", "\u672C\u5730\u6587\u4EF6\u8DEF\u5F84").option("-t, --title <title>", "\u5A92\u4F53\u6807\u9898").option("--alt <text>", "\u56FE\u7247 alt").option("--caption <text>", "\u8BF4\u660E").option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
5166
|
+
await runMediaUpload(opts);
|
|
5167
|
+
});
|
|
5168
|
+
}
|
|
5169
|
+
|
|
5170
|
+
// src/commands/terms.ts
|
|
5171
|
+
async function runTermsTaxonomies(opts) {
|
|
5172
|
+
const target = await resolveTarget(opts);
|
|
5173
|
+
let taxes;
|
|
5174
|
+
try {
|
|
5175
|
+
taxes = await apiFetch2(
|
|
5176
|
+
wpV2(target.base, "/taxonomies?context=edit"),
|
|
5177
|
+
target.config,
|
|
5178
|
+
{},
|
|
5179
|
+
opts.verbose
|
|
5180
|
+
);
|
|
5181
|
+
} catch (e) {
|
|
5182
|
+
console.error(`
|
|
5183
|
+
\u274C \u83B7\u53D6\u5206\u7C7B\u6CD5\u5931\u8D25\uFF1A${e.message}
|
|
5184
|
+
`);
|
|
5185
|
+
process.exit(1);
|
|
5186
|
+
return;
|
|
5187
|
+
}
|
|
5188
|
+
const rows = Object.entries(taxes || {}).map(([slug, info]) => ({
|
|
5189
|
+
slug,
|
|
5190
|
+
rest_base: info.rest_base || slug,
|
|
5191
|
+
name: info.name || slug
|
|
5192
|
+
}));
|
|
5193
|
+
if (opts.json) {
|
|
5194
|
+
console.log(JSON.stringify({ site: target.site, taxonomies: rows }, null, 2));
|
|
5195
|
+
return;
|
|
5196
|
+
}
|
|
5197
|
+
console.log(`
|
|
5198
|
+
${target.site.name} \u5206\u7C7B\u6CD5\uFF08${rows.length}\uFF09
|
|
5199
|
+
`);
|
|
5200
|
+
printCliTable(rows, [
|
|
5201
|
+
{ key: "slug", header: "slug" },
|
|
5202
|
+
{ key: "rest_base", header: "--taxonomy" },
|
|
5203
|
+
{ key: "name", header: "\u540D\u79F0" }
|
|
5204
|
+
]);
|
|
5205
|
+
console.log();
|
|
5206
|
+
}
|
|
5207
|
+
async function runTermsList(opts) {
|
|
5208
|
+
const target = await resolveTarget(opts);
|
|
5209
|
+
const restBase = await resolveTaxonomyRestBase(target, opts.taxonomy || "category", opts.verbose);
|
|
5210
|
+
let items;
|
|
5211
|
+
try {
|
|
5212
|
+
items = await apiFetch2(
|
|
5213
|
+
wpV2(target.base, `/${restBase}?per_page=100`),
|
|
5214
|
+
target.config,
|
|
5215
|
+
{},
|
|
5216
|
+
opts.verbose
|
|
5217
|
+
);
|
|
5218
|
+
} catch (e) {
|
|
5219
|
+
console.error(`
|
|
5220
|
+
\u274C \u83B7\u53D6 ${restBase} \u5931\u8D25\uFF1A${e.message}
|
|
5221
|
+
`);
|
|
5222
|
+
process.exit(1);
|
|
5223
|
+
return;
|
|
5224
|
+
}
|
|
5225
|
+
if (!Array.isArray(items)) {
|
|
5226
|
+
console.error("\n\u274C \u7AD9\u70B9\u8FD4\u56DE\u7684\u672F\u8BED\u5217\u8868\u683C\u5F0F\u5F02\u5E38\n");
|
|
5227
|
+
process.exit(1);
|
|
5228
|
+
}
|
|
5229
|
+
if (opts.json) {
|
|
5230
|
+
console.log(JSON.stringify({ taxonomy: restBase, total: items.length, items }, null, 2));
|
|
5231
|
+
return;
|
|
5232
|
+
}
|
|
5233
|
+
if (items.length === 0) {
|
|
5234
|
+
console.log(`
|
|
5235
|
+
\u6CA1\u6709 ${restBase}\u3002
|
|
5236
|
+
`);
|
|
5237
|
+
return;
|
|
5238
|
+
}
|
|
5239
|
+
console.log(`
|
|
5240
|
+
${target.site.name} ${restBase}\uFF08${items.length}\uFF09
|
|
5241
|
+
`);
|
|
5242
|
+
printCliTable(
|
|
5243
|
+
items.map((t) => ({
|
|
5244
|
+
id: String(t.id),
|
|
5245
|
+
name: t.name || "-",
|
|
5246
|
+
slug: t.slug || "-",
|
|
5247
|
+
count: String(t.count ?? 0)
|
|
5248
|
+
})),
|
|
5249
|
+
[
|
|
5250
|
+
{ key: "id", header: "id" },
|
|
5251
|
+
{ key: "name", header: "\u540D\u79F0" },
|
|
5252
|
+
{ key: "slug", header: "slug" },
|
|
5253
|
+
{ key: "count", header: "\u6570\u91CF" }
|
|
5254
|
+
]
|
|
5255
|
+
);
|
|
5256
|
+
console.log();
|
|
5257
|
+
}
|
|
5258
|
+
async function runTermsAdd(opts) {
|
|
5259
|
+
const name = opts.name?.trim() ?? "";
|
|
5260
|
+
if (!name) {
|
|
5261
|
+
console.error("\n\u274C \u8BF7\u63D0\u4F9B --name\n");
|
|
5262
|
+
process.exit(1);
|
|
5263
|
+
}
|
|
5264
|
+
const target = await resolveTarget(opts);
|
|
5265
|
+
const restBase = await resolveTaxonomyRestBase(target, opts.taxonomy || "category", opts.verbose);
|
|
5266
|
+
const body = { name };
|
|
5267
|
+
if (opts.slug?.trim()) body.slug = opts.slug.trim();
|
|
5268
|
+
const parent = Number(opts.parent);
|
|
5269
|
+
if (Number.isFinite(parent) && parent > 0) body.parent = parent;
|
|
5270
|
+
const item = await apiFetch2(
|
|
5271
|
+
wpV2(target.base, `/${restBase}`),
|
|
5272
|
+
target.config,
|
|
5273
|
+
{ method: "POST", body: JSON.stringify(body) },
|
|
5274
|
+
opts.verbose
|
|
5275
|
+
).catch((e) => {
|
|
5276
|
+
console.error(`
|
|
5277
|
+
\u274C \u65B0\u589E\u5931\u8D25\uFF1A${e.message}
|
|
5278
|
+
`);
|
|
5279
|
+
process.exit(1);
|
|
5280
|
+
});
|
|
5281
|
+
console.log(`
|
|
5282
|
+
\u2705 \u5DF2\u65B0\u589E ${restBase} #${item.id} ${item.name || name}
|
|
5283
|
+
`);
|
|
5284
|
+
}
|
|
5285
|
+
async function runTermsUpdate(opts) {
|
|
5286
|
+
const id = Number(opts.id);
|
|
5287
|
+
if (!Number.isFinite(id) || id <= 0) {
|
|
5288
|
+
console.error("\n\u274C \u8BF7\u63D0\u4F9B --id\n");
|
|
5289
|
+
process.exit(1);
|
|
5290
|
+
}
|
|
5291
|
+
const body = {};
|
|
5292
|
+
if (opts.name?.trim()) body.name = opts.name.trim();
|
|
5293
|
+
if (opts.slug?.trim()) body.slug = opts.slug.trim();
|
|
5294
|
+
if (Object.keys(body).length === 0) {
|
|
5295
|
+
console.error("\n\u274C \u6CA1\u6709\u8981\u6539\u7684\u5B57\u6BB5\n");
|
|
5296
|
+
process.exit(1);
|
|
5297
|
+
}
|
|
5298
|
+
const target = await resolveTarget(opts);
|
|
5299
|
+
const restBase = await resolveTaxonomyRestBase(target, opts.taxonomy || "category", opts.verbose);
|
|
5300
|
+
const item = await apiFetch2(
|
|
5301
|
+
wpV2(target.base, `/${restBase}/${id}`),
|
|
5302
|
+
target.config,
|
|
5303
|
+
{ method: "POST", body: JSON.stringify(body) },
|
|
5304
|
+
opts.verbose
|
|
5305
|
+
).catch((e) => {
|
|
5306
|
+
console.error(`
|
|
5307
|
+
\u274C \u66F4\u65B0\u5931\u8D25\uFF1A${e.message}
|
|
5308
|
+
`);
|
|
5309
|
+
process.exit(1);
|
|
5310
|
+
});
|
|
5311
|
+
console.log(`
|
|
5312
|
+
\u2705 \u5DF2\u66F4\u65B0 ${restBase} #${item.id} ${item.name || ""}
|
|
5313
|
+
`);
|
|
5314
|
+
}
|
|
5315
|
+
async function runTermsDelete(opts) {
|
|
5316
|
+
const id = Number(opts.id);
|
|
5317
|
+
if (!Number.isFinite(id) || id <= 0) {
|
|
5318
|
+
console.error("\n\u274C \u8BF7\u63D0\u4F9B --id\n");
|
|
5319
|
+
process.exit(1);
|
|
5320
|
+
}
|
|
5321
|
+
const target = await resolveTarget(opts);
|
|
5322
|
+
const restBase = await resolveTaxonomyRestBase(target, opts.taxonomy || "category", opts.verbose);
|
|
5323
|
+
await apiFetch2(
|
|
5324
|
+
wpV2(target.base, `/${restBase}/${id}?force=true`),
|
|
5325
|
+
target.config,
|
|
5326
|
+
{ method: "DELETE" },
|
|
5327
|
+
opts.verbose
|
|
5328
|
+
).catch((e) => {
|
|
5329
|
+
console.error(`
|
|
5330
|
+
\u274C \u5220\u9664\u5931\u8D25\uFF1A${e.message}
|
|
5331
|
+
`);
|
|
5332
|
+
process.exit(1);
|
|
5333
|
+
});
|
|
5334
|
+
console.log(`
|
|
5335
|
+
\u2705 \u5DF2\u5220\u9664 ${restBase} #${id}
|
|
5336
|
+
`);
|
|
5337
|
+
}
|
|
5338
|
+
function register10(program2) {
|
|
5339
|
+
const terms = program2.command("terms").description("\u5206\u7C7B / \u6807\u7B7E / \u81EA\u5B9A\u4E49\u5206\u7C7B\u6CD5");
|
|
5340
|
+
terms.command("taxonomies").description("\u5217\u51FA\u5206\u7C7B\u6CD5").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
5341
|
+
await runTermsTaxonomies(opts);
|
|
5342
|
+
});
|
|
5343
|
+
terms.command("list").description("\u5217\u51FA\u67D0\u5206\u7C7B\u6CD5\u4E0B\u7684\u672F\u8BED").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").option("--taxonomy <slug>", "category / post_tag / \u5176\u5B83 rest_base", "category").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
5344
|
+
await runTermsList(opts);
|
|
5345
|
+
});
|
|
5346
|
+
terms.command("add").description("\u65B0\u589E\u672F\u8BED\uFF08\u5199\u64CD\u4F5C\uFF09").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").option("--taxonomy <slug>", "\u9ED8\u8BA4 category", "category").requiredOption("-n, --name <name>", "\u540D\u79F0").option("--slug <slug>", "\u522B\u540D").option("--parent <id>", "\u7236\u7EA7 ID").option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
5347
|
+
await runTermsAdd(opts);
|
|
5348
|
+
});
|
|
5349
|
+
terms.command("update").description("\u66F4\u65B0\u672F\u8BED\uFF08\u5199\u64CD\u4F5C\uFF09").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").option("--taxonomy <slug>", "\u9ED8\u8BA4 category", "category").requiredOption("--id <id>", "\u672F\u8BED ID").option("-n, --name <name>", "\u540D\u79F0").option("--slug <slug>", "\u522B\u540D").option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
5350
|
+
await runTermsUpdate(opts);
|
|
5351
|
+
});
|
|
5352
|
+
terms.command("delete").description("\u5220\u9664\u672F\u8BED\uFF08\u5199\u64CD\u4F5C\uFF0C\u4E0D\u53EF\u8FDB\u56DE\u6536\u7AD9\uFF09").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").option("--taxonomy <slug>", "\u9ED8\u8BA4 category", "category").requiredOption("--id <id>", "\u672F\u8BED ID").option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
5353
|
+
await runTermsDelete(opts);
|
|
5354
|
+
});
|
|
5355
|
+
}
|
|
5356
|
+
|
|
5357
|
+
// src/commands/search.ts
|
|
5358
|
+
async function runSearch(opts) {
|
|
5359
|
+
const q = opts.q?.trim() ?? "";
|
|
5360
|
+
if (!q) {
|
|
5361
|
+
console.error("\n\u274C \u8BF7\u63D0\u4F9B --q\n");
|
|
5362
|
+
process.exit(1);
|
|
5363
|
+
}
|
|
5364
|
+
const target = await resolveTarget(opts);
|
|
5365
|
+
const params = new URLSearchParams({
|
|
5366
|
+
search: q,
|
|
5367
|
+
per_page: "20"
|
|
5368
|
+
});
|
|
5369
|
+
if (opts.type?.trim()) params.set("subtype", opts.type.trim());
|
|
5370
|
+
let hits;
|
|
5371
|
+
try {
|
|
5372
|
+
hits = await apiFetch2(
|
|
5373
|
+
wpV2(target.base, `/search?${params.toString()}`),
|
|
5374
|
+
target.config,
|
|
5375
|
+
{},
|
|
5376
|
+
opts.verbose
|
|
5377
|
+
);
|
|
5378
|
+
} catch (e) {
|
|
5379
|
+
console.error(`
|
|
5380
|
+
\u274C \u641C\u7D22\u5931\u8D25\uFF1A${e.message}
|
|
5381
|
+
`);
|
|
5382
|
+
process.exit(1);
|
|
5383
|
+
return;
|
|
5384
|
+
}
|
|
5385
|
+
if (!Array.isArray(hits)) {
|
|
5386
|
+
console.error("\n\u274C \u7AD9\u70B9\u8FD4\u56DE\u7684\u641C\u7D22\u7ED3\u679C\u683C\u5F0F\u5F02\u5E38\n");
|
|
5387
|
+
process.exit(1);
|
|
5388
|
+
}
|
|
5389
|
+
if (opts.json) {
|
|
5390
|
+
console.log(JSON.stringify({ q, total: hits.length, hits }, null, 2));
|
|
5391
|
+
return;
|
|
5392
|
+
}
|
|
5393
|
+
if (hits.length === 0) {
|
|
5394
|
+
console.log(`
|
|
5395
|
+
\u6CA1\u6709\u5339\u914D\u300C${q}\u300D\u7684\u7ED3\u679C\u3002
|
|
5396
|
+
`);
|
|
5397
|
+
return;
|
|
5398
|
+
}
|
|
5399
|
+
console.log(`
|
|
5400
|
+
${target.site.name} \u641C\u7D22\u300C${q}\u300D\uFF08${hits.length}\uFF09
|
|
5401
|
+
`);
|
|
5402
|
+
printCliTable(
|
|
5403
|
+
hits.map((h) => ({
|
|
5404
|
+
id: h.id != null ? String(h.id) : "-",
|
|
5405
|
+
title: h.title || "-",
|
|
5406
|
+
type: [h.type, h.subtype].filter(Boolean).join("/") || "-",
|
|
5407
|
+
url: h.url || "-"
|
|
5408
|
+
})),
|
|
5409
|
+
[
|
|
5410
|
+
{ key: "id", header: "id" },
|
|
5411
|
+
{ key: "title", header: "\u6807\u9898" },
|
|
5412
|
+
{ key: "type", header: "\u7C7B\u578B" },
|
|
5413
|
+
{ key: "url", header: "\u94FE\u63A5" }
|
|
5414
|
+
]
|
|
5415
|
+
);
|
|
5416
|
+
console.log();
|
|
5417
|
+
}
|
|
5418
|
+
function register11(program2) {
|
|
5419
|
+
program2.command("search").description("\u5168\u7AD9\u641C\u7D22\uFF08\u9875\u9762/\u6587\u7AE0/\u5A92\u4F53\u7B49\uFF09").option("-s, --site <guidOrName>", "\u7AD9\u70B9 guid \u6216\u540D\u79F0").option("--url <url>", "\u76F4\u63A5\u6307\u5B9A\u7AD9\u70B9\u5730\u5740").requiredOption("-q, --q <keyword>", "\u5173\u952E\u8BCD").option("--type <subtype>", "\u9650\u5B9A rest \u5B50\u7C7B\u578B\uFF0C\u5982 page / post").option("--json", "\u8F93\u51FA JSON", false).option("--verbose", "\u8F93\u51FA\u8BF7\u6C42\u8BE6\u60C5", false).action(async (opts) => {
|
|
5420
|
+
await runSearch(opts);
|
|
5421
|
+
});
|
|
4171
5422
|
}
|
|
4172
5423
|
|
|
4173
5424
|
// src/index.ts
|
|
4174
5425
|
installProcessHandlers();
|
|
4175
5426
|
var program = new Command();
|
|
4176
|
-
program.name("siluzan-website").description("Siluzan WordPress \u7AD9\u70B9\u7BA1\u7406\uFF1A\
|
|
5427
|
+
program.name("siluzan-website").description("Siluzan WordPress \u7AD9\u70B9\u7BA1\u7406\uFF1A\u7AD9\u70B9\u3001\u9875\u9762\u3001\u6587\u7AE0\u3001\u5A92\u4F53\u3001\u5206\u7C7B\u3001\u63D2\u4EF6").version(getCurrentVersion2());
|
|
4177
5428
|
var REGISTRARS = [
|
|
4178
5429
|
register,
|
|
4179
5430
|
register2,
|
|
@@ -4181,6 +5432,10 @@ var REGISTRARS = [
|
|
|
4181
5432
|
register4,
|
|
4182
5433
|
register5,
|
|
4183
5434
|
register6,
|
|
5435
|
+
register8,
|
|
5436
|
+
register9,
|
|
5437
|
+
register10,
|
|
5438
|
+
register11,
|
|
4184
5439
|
register7
|
|
4185
5440
|
];
|
|
4186
5441
|
for (const reg of REGISTRARS) reg(program);
|