pdlab-cli 0.3.0 → 0.5.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 +28 -0
- package/dist/index.js +258 -49
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -50,6 +50,7 @@ pdlab schema # 一次性 JSON 输出全部命令、参数、权限要
|
|
|
50
50
|
| `pdlab project join \| leave <id>` | 报名共建 / 撤回申请或退出共建 |
|
|
51
51
|
| `pdlab project member review \| set-role \| remove <projectId> <userId>` | 审核报名、设置协作者角色、移除参与者(仅项目发起人本人) |
|
|
52
52
|
| `pdlab project revenue <id>` | 查看项目的积分分成明细(只读) |
|
|
53
|
+
| `pdlab collection list \| create \| update \| delete` | 项目集合(「解决方案云展厅」)的增删改查(列表 public 集合公开只读,写操作需 `collection:manage`) |
|
|
53
54
|
| `pdlab post list \| get \| create \| update \| delete` | 内容的增删改查(`--project-id` 选填,不填即独立发布,不挂任何项目) |
|
|
54
55
|
| `pdlab post review <id> --action approve\|reject` | 审核一条待审内容 |
|
|
55
56
|
| `pdlab taxonomy list \| create \| update \| delete` | 分类标签的增删改查(列表公开只读,写操作需 `taxonomy:manage`) |
|
|
@@ -77,6 +78,17 @@ pdlab project leave proj_123
|
|
|
77
78
|
pdlab project member review proj_123 user_456 --status approved
|
|
78
79
|
pdlab project member set-role proj_123 user_456 --role maintainer
|
|
79
80
|
|
|
81
|
+
# 创建项目集合,按顺序关联项目(需要 collection:manage 权限,即「1836发起人」角色)
|
|
82
|
+
pdlab collection create \
|
|
83
|
+
--title "1836钠电与AIDC产业白皮书" \
|
|
84
|
+
--description "汇集多个共建项目的研究成果与产业洞察" \
|
|
85
|
+
--visibility public \
|
|
86
|
+
--project-ids proj_a,proj_b,proj_c
|
|
87
|
+
|
|
88
|
+
# 更新集合关联的项目(全量替换)、排序、可见范围
|
|
89
|
+
pdlab collection update coll_123 --project-ids proj_a,proj_c --sort-order 1
|
|
90
|
+
pdlab collection list # public 集合公开只读,不登录也能用
|
|
91
|
+
|
|
80
92
|
# 往自己参与的项目发布内容(共建者发布后进待审队列)
|
|
81
93
|
pdlab post create \
|
|
82
94
|
--project-id <项目 id> \
|
|
@@ -149,6 +161,22 @@ API 地址的解析顺序:`--api-url` 参数 > `PDLAB_API_URL` 环境变量 >
|
|
|
149
161
|
作者也才能 `post get` 到自己那篇还没过审的稿子。没登录则匿名读公开内容,照常可用。
|
|
150
162
|
在 CI 里可以只给环境变量,不落配置文件。
|
|
151
163
|
|
|
164
|
+
## 版本更新提示
|
|
165
|
+
|
|
166
|
+
`pdlab` 每次运行都会顺手看一眼本地缓存的版本信息,如果有新版本会在命令结束时打印一行提示到
|
|
167
|
+
**stderr**(不影响 stdout 的 JSON 输出,脚本/agent 该怎么解析还怎么解析):
|
|
168
|
+
|
|
169
|
+
```
|
|
170
|
+
※ pdlab-cli 有新版本可用:0.3.0 → 0.4.0
|
|
171
|
+
运行 npm install -g pdlab-cli@latest 升级(可用 PDLAB_NO_UPDATE_CHECK=1 关闭此提示)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
这个检查本身不会拖慢任何命令:真正去问 npm registry 的动作放在一个独立的后台进程里做,
|
|
175
|
+
每 24 小时最多问一次,前台命令只读本地缓存(一次磁盘读,微秒级)。离线或连不上 registry
|
|
176
|
+
时静默跳过,不影响命令本身的执行结果。
|
|
177
|
+
|
|
178
|
+
不想看到这个提示:设置环境变量 `PDLAB_NO_UPDATE_CHECK=1`(CI/自动化脚本建议直接设置)。
|
|
179
|
+
|
|
152
180
|
## 凭证与安全
|
|
153
181
|
|
|
154
182
|
- **凭证怎么来的**:走设备码授权——CLI 生成一次性 code,你在浏览器里确认后服务端才签发。
|
package/dist/index.js
CHANGED
|
@@ -24,8 +24,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
));
|
|
25
25
|
|
|
26
26
|
// src/index.ts
|
|
27
|
-
var
|
|
28
|
-
var
|
|
27
|
+
var import_fs3 = require("fs");
|
|
28
|
+
var import_path3 = require("path");
|
|
29
29
|
var import_commander2 = require("commander");
|
|
30
30
|
|
|
31
31
|
// src/commands/login.ts
|
|
@@ -354,38 +354,58 @@ var postReviewSchema = import_zod3.z.object({
|
|
|
354
354
|
reviewComment: import_zod3.z.string().trim().max(500, "\u5BA1\u6838\u610F\u89C1\u6700\u591A 500 \u5B57").optional().describe("\u5BA1\u6838\u610F\u89C1\uFF08\u9A73\u56DE\u65F6\u5FC5\u586B\uFF09")
|
|
355
355
|
});
|
|
356
356
|
|
|
357
|
-
// ../shared-schemas/src/
|
|
357
|
+
// ../shared-schemas/src/collections.ts
|
|
358
358
|
var import_zod4 = require("zod");
|
|
359
|
-
var
|
|
359
|
+
var COLLECTION_VISIBILITY_VALUES = ["public", "private", "members"];
|
|
360
|
+
var collectionCreateSchema = import_zod4.z.object({
|
|
361
|
+
title: import_zod4.z.string().trim().min(1, "\u96C6\u5408\u6807\u9898\u4E0D\u80FD\u4E3A\u7A7A").max(200).describe("\u96C6\u5408\u6807\u9898"),
|
|
362
|
+
description: import_zod4.z.string().max(2e4).optional().describe("\u96C6\u5408\u63CF\u8FF0"),
|
|
363
|
+
coverImage: safeImageUrl.optional().describe("\u5C01\u9762\u56FE\u94FE\u63A5\u6216\u4E0A\u4F20\u56FE\u7247\u5730\u5740"),
|
|
364
|
+
visibility: import_zod4.z.enum(COLLECTION_VISIBILITY_VALUES).optional().default("public").describe("\u53EF\u89C1\u8303\u56F4\uFF1Apublic \u6240\u6709\u4EBA\u53EF\u89C1 / private \u4E0D\u5BF9\u5916\u5217\u51FA / members \u4EC5\u767B\u5F55\u7528\u6237\u53EF\u89C1"),
|
|
365
|
+
// 关联项目按传入顺序落成 CollectionProject.position
|
|
366
|
+
projectIds: import_zod4.z.array(import_zod4.z.string().min(1)).max(100).optional().default([]).describe("\u6309\u987A\u5E8F\u5173\u8054\u7684\u9879\u76EE id \u5217\u8868")
|
|
367
|
+
});
|
|
368
|
+
var collectionUpdateSchema = import_zod4.z.object({
|
|
369
|
+
title: import_zod4.z.string().trim().min(1, "\u96C6\u5408\u6807\u9898\u4E0D\u80FD\u4E3A\u7A7A").max(200).optional().describe("\u96C6\u5408\u6807\u9898"),
|
|
370
|
+
description: import_zod4.z.string().max(2e4).optional().describe("\u96C6\u5408\u63CF\u8FF0"),
|
|
371
|
+
coverImage: safeImageUrl.optional().describe("\u5C01\u9762\u56FE\u94FE\u63A5\u6216\u4E0A\u4F20\u56FE\u7247\u5730\u5740"),
|
|
372
|
+
visibility: import_zod4.z.enum(COLLECTION_VISIBILITY_VALUES).optional().describe("\u53EF\u89C1\u8303\u56F4\uFF1Apublic/private/members"),
|
|
373
|
+
sortOrder: import_zod4.z.number().int().optional().describe("\u6392\u5E8F\u5E8F\u53F7\uFF0C\u8D8A\u5C0F\u8D8A\u9760\u524D"),
|
|
374
|
+
projectIds: import_zod4.z.array(import_zod4.z.string().min(1)).max(100).optional().describe("\u5173\u8054\u9879\u76EE id \u5217\u8868\uFF08\u5168\u91CF\u66FF\u6362\uFF09")
|
|
375
|
+
}).refine((v) => Object.keys(v).length > 0, "\u6CA1\u6709\u9700\u8981\u66F4\u65B0\u7684\u5B57\u6BB5");
|
|
376
|
+
|
|
377
|
+
// ../shared-schemas/src/taxonomies.ts
|
|
378
|
+
var import_zod5 = require("zod");
|
|
379
|
+
var taxonomyDimensionCreateSchema = import_zod5.z.object({
|
|
360
380
|
// key 会进 URL 查询串和导出文件,限制成 slug 形态
|
|
361
|
-
key:
|
|
362
|
-
label:
|
|
363
|
-
description:
|
|
364
|
-
sortOrder:
|
|
381
|
+
key: import_zod5.z.string().trim().min(1).max(40).regex(/^[a-z][a-z0-9_]*$/, "\u7EF4\u5EA6\u6807\u8BC6\u53EA\u80FD\u7528\u5C0F\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u548C\u4E0B\u5212\u7EBF\uFF0C\u4E14\u4EE5\u5B57\u6BCD\u5F00\u5934").describe("\u7EF4\u5EA6\u6807\u8BC6\uFF0C\u5982 domain\uFF08\u521B\u5EFA\u540E\u4E0D\u53EF\u6539\uFF09"),
|
|
382
|
+
label: import_zod5.z.string().trim().min(1, "\u7EF4\u5EA6\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A").max(40).describe("\u7EF4\u5EA6\u4E2D\u6587\u540D\uFF0C\u5982\u300C\u9886\u57DF\u300D"),
|
|
383
|
+
description: import_zod5.z.string().max(500).optional().describe("\u7EF4\u5EA6\u8BF4\u660E"),
|
|
384
|
+
sortOrder: import_zod5.z.number().int().min(0).max(999).optional().default(0).describe("\u5C55\u793A\u6392\u5E8F")
|
|
365
385
|
});
|
|
366
|
-
var taxonomyDimensionUpdateSchema =
|
|
367
|
-
label:
|
|
368
|
-
description:
|
|
369
|
-
sortOrder:
|
|
386
|
+
var taxonomyDimensionUpdateSchema = import_zod5.z.object({
|
|
387
|
+
label: import_zod5.z.string().trim().min(1).max(40).optional().describe("\u7EF4\u5EA6\u4E2D\u6587\u540D"),
|
|
388
|
+
description: import_zod5.z.string().max(500).nullable().optional().describe("\u7EF4\u5EA6\u8BF4\u660E"),
|
|
389
|
+
sortOrder: import_zod5.z.number().int().min(0).max(999).optional().describe("\u5C55\u793A\u6392\u5E8F")
|
|
370
390
|
});
|
|
371
|
-
var taxonomyCreateSchema =
|
|
372
|
-
dimension:
|
|
373
|
-
label:
|
|
374
|
-
weight:
|
|
375
|
-
sortOrder:
|
|
376
|
-
description:
|
|
391
|
+
var taxonomyCreateSchema = import_zod5.z.object({
|
|
392
|
+
dimension: import_zod5.z.string().min(1).describe("\u6240\u5C5E\u7EF4\u5EA6\u7684 key\uFF0C\u5982 domain"),
|
|
393
|
+
label: import_zod5.z.string().trim().min(1, "\u6807\u7B7E\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A").max(100).describe("\u6807\u7B7E\u503C\uFF0C\u5982\u300C\u94A0\u7535\u4E0EAIDC\u5168\u7403\u57FA\u5EFA\u300D"),
|
|
394
|
+
weight: import_zod5.z.number().min(0).max(1).optional().default(0).describe("\u5EFA\u8BAE\u6743\u91CD 0~1\uFF1A\u53D1\u8D77\u9879\u76EE\u65F6\u9884\u586B\u7ED9\u53D1\u8D77\u4EBA\uFF0C\u53EF\u518D\u8C03"),
|
|
395
|
+
sortOrder: import_zod5.z.number().int().min(0).max(999).optional().default(0).describe("\u5C55\u793A\u6392\u5E8F"),
|
|
396
|
+
description: import_zod5.z.string().max(500).optional().describe("\u6807\u7B7E\u8BF4\u660E")
|
|
377
397
|
});
|
|
378
|
-
var taxonomyUpdateSchema =
|
|
379
|
-
dimension:
|
|
380
|
-
label:
|
|
381
|
-
weight:
|
|
382
|
-
sortOrder:
|
|
383
|
-
description:
|
|
398
|
+
var taxonomyUpdateSchema = import_zod5.z.object({
|
|
399
|
+
dimension: import_zod5.z.string().min(1).optional().describe("\u6240\u5C5E\u7EF4\u5EA6\u7684 key"),
|
|
400
|
+
label: import_zod5.z.string().min(1).optional().describe("\u6807\u7B7E\u503C"),
|
|
401
|
+
weight: import_zod5.z.number().min(0).max(1).optional().describe("\u5EFA\u8BAE\u6743\u91CD 0~1"),
|
|
402
|
+
sortOrder: import_zod5.z.number().int().optional().describe("\u5C55\u793A\u6392\u5E8F"),
|
|
403
|
+
description: import_zod5.z.string().optional().describe("\u6807\u7B7E\u8BF4\u660E")
|
|
384
404
|
});
|
|
385
405
|
|
|
386
406
|
// src/errors.ts
|
|
387
407
|
var import_commander = require("commander");
|
|
388
|
-
var
|
|
408
|
+
var import_zod6 = require("zod");
|
|
389
409
|
var EXIT_CODES = {
|
|
390
410
|
ok: 0,
|
|
391
411
|
unhandled: 1,
|
|
@@ -418,7 +438,7 @@ function exampleHint(examples) {
|
|
|
418
438
|
}
|
|
419
439
|
function handleCommandError(error, examples = []) {
|
|
420
440
|
let structured;
|
|
421
|
-
if (error instanceof
|
|
441
|
+
if (error instanceof import_zod6.ZodError) {
|
|
422
442
|
structured = {
|
|
423
443
|
error: "\u53C2\u6570\u6821\u9A8C\u5931\u8D25",
|
|
424
444
|
code: "validation",
|
|
@@ -679,8 +699,100 @@ function registerProjectCommand(program2) {
|
|
|
679
699
|
);
|
|
680
700
|
}
|
|
681
701
|
|
|
682
|
-
// src/commands/
|
|
702
|
+
// src/commands/collection.ts
|
|
703
|
+
var VISIBILITY_LIST = COLLECTION_VISIBILITY_VALUES.join(" | ");
|
|
704
|
+
var LIST_EXAMPLES2 = [
|
|
705
|
+
{ command: "pdlab collection list", note: "\u4E0D\u767B\u5F55\u53EA\u770B public \u96C6\u5408\uFF1B\u767B\u5F55\u540E\u540C\u65F6\u770B\u5F97\u5230 members \u96C6\u5408" }
|
|
706
|
+
];
|
|
683
707
|
var CREATE_EXAMPLES2 = [
|
|
708
|
+
{
|
|
709
|
+
command: 'pdlab collection create --title "1836\u94A0\u7535\u4E0EAIDC\u4EA7\u4E1A\u767D\u76AE\u4E66" --description "..." --project-ids proj_a,proj_b',
|
|
710
|
+
note: "title \u5FC5\u586B\uFF0C\u5176\u4F59\u5B57\u6BB5\u53EF\u7701\u7565\uFF1B\u9700\u8981\u300C1836\u53D1\u8D77\u4EBA\u300D\u89D2\u8272\uFF08collection:manage \u6743\u9650\uFF09"
|
|
711
|
+
}
|
|
712
|
+
];
|
|
713
|
+
var UPDATE_EXAMPLES2 = [
|
|
714
|
+
{ command: "pdlab collection update coll_123 --sort-order 1", note: "\u53EA\u4F20\u8981\u6539\u7684\u5B57\u6BB5" },
|
|
715
|
+
{ command: "pdlab collection update coll_123 --project-ids proj_a,proj_c", note: "project-ids \u4F1A\u5168\u91CF\u66FF\u6362\u8BE5\u96C6\u5408\u5173\u8054\u7684\u9879\u76EE\u53CA\u987A\u5E8F" }
|
|
716
|
+
];
|
|
717
|
+
var DELETE_EXAMPLES2 = [{ command: "pdlab collection delete coll_123" }];
|
|
718
|
+
function toProjectIds(value) {
|
|
719
|
+
if (value === void 0) return void 0;
|
|
720
|
+
return value.split(",").map((id) => id.trim()).filter(Boolean);
|
|
721
|
+
}
|
|
722
|
+
function withCollectionFlags(cmd) {
|
|
723
|
+
return withApiUrl(cmd).option("--title <title>", "\u96C6\u5408\u6807\u9898\uFF08\u5FC5\u586B\uFF0C1-200 \u5B57\uFF09").option("--description <description>", "\u96C6\u5408\u63CF\u8FF0\uFF08\u9009\u586B\uFF0C\u6700\u591A 20000 \u5B57\uFF09").option("--cover-image <url>", "\u5C01\u9762\u56FE http/https \u94FE\u63A5\u6216\u5E73\u53F0\u5185\u4E0A\u4F20\u56FE\u7247\u5730\u5740\uFF08\u9009\u586B\uFF09").option("--visibility <visibility>", `\u53EF\u89C1\u8303\u56F4\uFF1A${VISIBILITY_LIST}\uFF08\u9009\u586B\uFF0C\u9ED8\u8BA4 public\uFF09`).option("--project-ids <ids>", "\u9017\u53F7\u5206\u9694\u7684\u9879\u76EE id \u5217\u8868\uFF0C\u6309\u987A\u5E8F\u5173\u8054\uFF0C\u5168\u91CF\u66FF\u6362\uFF08\u9009\u586B\uFF09");
|
|
724
|
+
}
|
|
725
|
+
function registerCollectionCommand(program2) {
|
|
726
|
+
const collection = program2.command("collection").description("\u9879\u76EE\u96C6\u5408\uFF08PRD\u300C\u89E3\u51B3\u65B9\u6848\u4E91\u5C55\u5385\u300D\uFF09\u7684\u589E\u5220\u6539\u67E5");
|
|
727
|
+
attachMeta(
|
|
728
|
+
withApiUrl(collection.command("list").description("\u5217\u51FA\u96C6\u5408\uFF08public \u96C6\u5408\u516C\u5F00\u53EA\u8BFB\uFF0C\u4E0D\u767B\u5F55\u4E5F\u80FD\u7528\uFF09")).action(
|
|
729
|
+
async (opts) => {
|
|
730
|
+
const data = await apiRequest("/api/collections", { token: optionalToken(), apiUrl: opts.apiUrl });
|
|
731
|
+
console.log(JSON.stringify(data, null, 2));
|
|
732
|
+
}
|
|
733
|
+
),
|
|
734
|
+
{ examples: LIST_EXAMPLES2 }
|
|
735
|
+
);
|
|
736
|
+
attachMeta(
|
|
737
|
+
withCollectionFlags(collection.command("create").description("\u521B\u5EFA\u96C6\u5408")).action(
|
|
738
|
+
async (opts) => {
|
|
739
|
+
const token = requireToken();
|
|
740
|
+
try {
|
|
741
|
+
const body = collectionCreateSchema.parse({
|
|
742
|
+
title: opts.title,
|
|
743
|
+
description: opts.description,
|
|
744
|
+
coverImage: opts.coverImage,
|
|
745
|
+
visibility: opts.visibility,
|
|
746
|
+
projectIds: toProjectIds(opts.projectIds)
|
|
747
|
+
});
|
|
748
|
+
const data = await apiRequest("/api/collections", { method: "POST", body, token, apiUrl: opts.apiUrl });
|
|
749
|
+
console.log(JSON.stringify(data, null, 2));
|
|
750
|
+
} catch (error) {
|
|
751
|
+
handleCommandError(error, CREATE_EXAMPLES2);
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
),
|
|
755
|
+
{ permission: "collection:manage\uFF081836\u53D1\u8D77\u4EBA\u89D2\u8272\uFF09", examples: CREATE_EXAMPLES2 }
|
|
756
|
+
);
|
|
757
|
+
attachMeta(
|
|
758
|
+
withCollectionFlags(collection.command("update <id>").description("\u66F4\u65B0\u96C6\u5408")).option("--sort-order <n>", "\u6392\u5E8F\u5E8F\u53F7\uFF0C\u6574\u6570\uFF0C\u8D8A\u5C0F\u8D8A\u9760\u524D\uFF08\u9009\u586B\uFF09").action(async (id, opts) => {
|
|
759
|
+
const token = requireToken();
|
|
760
|
+
try {
|
|
761
|
+
const body = collectionUpdateSchema.parse({
|
|
762
|
+
title: opts.title,
|
|
763
|
+
description: opts.description,
|
|
764
|
+
coverImage: opts.coverImage,
|
|
765
|
+
visibility: opts.visibility,
|
|
766
|
+
sortOrder: opts.sortOrder !== void 0 ? Number(opts.sortOrder) : void 0,
|
|
767
|
+
projectIds: toProjectIds(opts.projectIds)
|
|
768
|
+
});
|
|
769
|
+
const data = await apiRequest(`/api/collections/${id}`, {
|
|
770
|
+
method: "PATCH",
|
|
771
|
+
body,
|
|
772
|
+
token,
|
|
773
|
+
apiUrl: opts.apiUrl
|
|
774
|
+
});
|
|
775
|
+
console.log(JSON.stringify(data, null, 2));
|
|
776
|
+
} catch (error) {
|
|
777
|
+
handleCommandError(error, UPDATE_EXAMPLES2);
|
|
778
|
+
}
|
|
779
|
+
}),
|
|
780
|
+
{ permission: "collection:manage\uFF081836\u53D1\u8D77\u4EBA\u89D2\u8272\uFF09", examples: UPDATE_EXAMPLES2 }
|
|
781
|
+
);
|
|
782
|
+
attachMeta(
|
|
783
|
+
withApiUrl(collection.command("delete <id>").description("\u5220\u9664\u96C6\u5408")).action(
|
|
784
|
+
async (id, opts) => {
|
|
785
|
+
const token = requireToken();
|
|
786
|
+
const data = await apiRequest(`/api/collections/${id}`, { method: "DELETE", token, apiUrl: opts.apiUrl });
|
|
787
|
+
console.log(JSON.stringify(data, null, 2));
|
|
788
|
+
}
|
|
789
|
+
),
|
|
790
|
+
{ permission: "collection:manage\uFF081836\u53D1\u8D77\u4EBA\u89D2\u8272\uFF09", examples: DELETE_EXAMPLES2 }
|
|
791
|
+
);
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
// src/commands/post.ts
|
|
795
|
+
var CREATE_EXAMPLES3 = [
|
|
684
796
|
{
|
|
685
797
|
command: 'pdlab post create --title "\u94A0\u7535\u4EA7\u4E1A\u89C2\u5BDF" --body "..."',
|
|
686
798
|
note: "\u53EA\u6709 title / body \u5FC5\u586B\uFF1A\u4E0D\u5E26 --project-id \u5C31\u662F\u72EC\u7ACB\u53D1\u5E03\uFF0C\u4E0D\u6302\u4EFB\u4F55\u5171\u5EFA\u9879\u76EE"
|
|
@@ -690,17 +802,17 @@ var CREATE_EXAMPLES2 = [
|
|
|
690
802
|
note: "\u6302\u5230\u9879\u76EE\u4E0B\u65F6\uFF0C\u9700\u8981\u662F\u8BE5\u9879\u76EE\u53D1\u8D77\u4EBA\u6216\u5DF2\u901A\u8FC7\u5BA1\u6838\u7684\u53C2\u4E0E\u8005"
|
|
691
803
|
}
|
|
692
804
|
];
|
|
693
|
-
var
|
|
805
|
+
var UPDATE_EXAMPLES3 = [
|
|
694
806
|
{ command: 'pdlab post update post_123 --title "..." --body "..."', note: "title \u548C body \u90FD\u5FC5\u987B\u4F20" }
|
|
695
807
|
];
|
|
696
|
-
var
|
|
808
|
+
var LIST_EXAMPLES3 = [
|
|
697
809
|
{ command: "pdlab post list --project-id proj_123", note: "\u53EA\u770B\u67D0\u4E2A\u9879\u76EE\u4E0B\u7684\u5185\u5BB9" },
|
|
698
810
|
{ command: "pdlab post list --project-id none", note: "\u53EA\u770B\u72EC\u7ACB\u53D1\u5E03\uFF08\u4E0D\u6302\u4EFB\u4F55\u9879\u76EE\uFF09\u7684\u5185\u5BB9" },
|
|
699
811
|
{ command: "pdlab post list --status pending", note: "\u67E5\u770B\u5F85\u5BA1\u6838\u5185\u5BB9\uFF0C\u9700\u8981 content:review \u6743\u9650\uFF0C\u5426\u5219 403" },
|
|
700
812
|
{ command: "pdlab post list --limit 10 --cursor <\u4E0A\u4E00\u9875\u8FD4\u56DE\u7684 nextCursor>", note: "\u7FFB\u9875\uFF1BnextCursor \u4E3A null \u8868\u793A\u6CA1\u6709\u4E0B\u4E00\u9875\u4E86" }
|
|
701
813
|
];
|
|
702
814
|
var GET_EXAMPLES2 = [{ command: "pdlab post get post_123" }];
|
|
703
|
-
var
|
|
815
|
+
var DELETE_EXAMPLES3 = [
|
|
704
816
|
{ command: "pdlab post delete post_123", note: "\u4F5C\u8005\u672C\u4EBA\uFF0C\u6216\u6709\u5220\u9664\u4EFB\u610F\u5185\u5BB9\u7684\u6743\u9650" }
|
|
705
817
|
];
|
|
706
818
|
var REVIEW_EXAMPLES = [
|
|
@@ -728,7 +840,7 @@ function registerPostCommand(program2) {
|
|
|
728
840
|
});
|
|
729
841
|
console.log(JSON.stringify(data, null, 2));
|
|
730
842
|
}),
|
|
731
|
-
{ examples:
|
|
843
|
+
{ examples: LIST_EXAMPLES3 }
|
|
732
844
|
);
|
|
733
845
|
attachMeta(
|
|
734
846
|
withApiUrl(post.command("get <id>").description("\u67E5\u770B\u5185\u5BB9\u8BE6\u60C5")).action(
|
|
@@ -752,10 +864,10 @@ function registerPostCommand(program2) {
|
|
|
752
864
|
const data = await apiRequest("/api/posts", { method: "POST", body, token, apiUrl: opts.apiUrl });
|
|
753
865
|
console.log(JSON.stringify(data, null, 2));
|
|
754
866
|
} catch (error) {
|
|
755
|
-
handleCommandError(error,
|
|
867
|
+
handleCommandError(error, CREATE_EXAMPLES3);
|
|
756
868
|
}
|
|
757
869
|
}),
|
|
758
|
-
{ permission: "content:create\uFF1B\u5E26 --project-id \u65F6\u8FD8\u9700\u662F\u8BE5\u9879\u76EE\u53D1\u8D77\u4EBA\u6216\u5DF2\u901A\u8FC7\u5BA1\u6838\u7684\u53C2\u4E0E\u8005", examples:
|
|
870
|
+
{ permission: "content:create\uFF1B\u5E26 --project-id \u65F6\u8FD8\u9700\u662F\u8BE5\u9879\u76EE\u53D1\u8D77\u4EBA\u6216\u5DF2\u901A\u8FC7\u5BA1\u6838\u7684\u53C2\u4E0E\u8005", examples: CREATE_EXAMPLES3 }
|
|
759
871
|
);
|
|
760
872
|
attachMeta(
|
|
761
873
|
withApiUrl(post.command("update <id>").description("\u7F16\u8F91\u5185\u5BB9\uFF08\u4F5C\u8005\u672C\u4EBA\uFF0C\u6216\u6709\u7F16\u8F91\u4EFB\u610F\u5185\u5BB9\u7684\u6743\u9650\uFF09")).option("--title <title>", "\u5185\u5BB9\u6807\u9898\uFF08\u5FC5\u586B\uFF09").option("--body <body>", "\u5185\u5BB9\u6B63\u6587\uFF08\u5FC5\u586B\uFF09").option("--media-links <urls>", "\u9017\u53F7\u5206\u9694\u7684\u56FE\u7247/\u89C6\u9891/\u5916\u94FE\u5730\u5740\uFF08\u9009\u586B\uFF0C\u6700\u591A 20 \u6761\uFF09").action(async (id, opts) => {
|
|
@@ -769,10 +881,10 @@ function registerPostCommand(program2) {
|
|
|
769
881
|
const data = await apiRequest(`/api/posts/${id}`, { method: "PATCH", body, token, apiUrl: opts.apiUrl });
|
|
770
882
|
console.log(JSON.stringify(data, null, 2));
|
|
771
883
|
} catch (error) {
|
|
772
|
-
handleCommandError(error,
|
|
884
|
+
handleCommandError(error, UPDATE_EXAMPLES3);
|
|
773
885
|
}
|
|
774
886
|
}),
|
|
775
|
-
{ examples:
|
|
887
|
+
{ examples: UPDATE_EXAMPLES3 }
|
|
776
888
|
);
|
|
777
889
|
attachMeta(
|
|
778
890
|
withApiUrl(post.command("delete <id>").description("\u5220\u9664\u5185\u5BB9\uFF08\u4F5C\u8005\u672C\u4EBA\uFF0C\u6216\u6709\u5220\u9664\u4EFB\u610F\u5185\u5BB9\u7684\u6743\u9650\uFF09")).action(
|
|
@@ -782,7 +894,7 @@ function registerPostCommand(program2) {
|
|
|
782
894
|
console.log(JSON.stringify(data, null, 2));
|
|
783
895
|
}
|
|
784
896
|
),
|
|
785
|
-
{ examples:
|
|
897
|
+
{ examples: DELETE_EXAMPLES3 }
|
|
786
898
|
);
|
|
787
899
|
attachMeta(
|
|
788
900
|
withApiUrl(post.command("review <id>").description("\u5BA1\u6838\u4E00\u6761\u5F85\u5BA1\u5185\u5BB9\uFF08approve / reject\uFF09")).requiredOption("--action <action>", "approve | reject").option("--comment <text>", "\u5BA1\u6838\u610F\u89C1\uFF0C\u6700\u591A 500 \u5B57\uFF08reject \u65F6\u5FC5\u586B\uFF09").action(async (id, opts) => {
|
|
@@ -819,17 +931,17 @@ var DIM_DELETE_EXAMPLES = [
|
|
|
819
931
|
note: "\u5185\u7F6E\u7EF4\u5EA6\uFF08domain/attribute/commercial\uFF09\u4E0D\u53EF\u5220\uFF1B\u7EF4\u5EA6\u4E0B\u8FD8\u6709\u6807\u7B7E\u65F6\u4F1A 409"
|
|
820
932
|
}
|
|
821
933
|
];
|
|
822
|
-
var
|
|
823
|
-
var
|
|
934
|
+
var LIST_EXAMPLES4 = [{ command: "pdlab taxonomy list", note: "\u516C\u5F00\u53EA\u8BFB\uFF0C\u4E0D\u767B\u5F55\u4E5F\u80FD\u7528" }];
|
|
935
|
+
var CREATE_EXAMPLES4 = [
|
|
824
936
|
{
|
|
825
937
|
command: 'pdlab taxonomy create --dimension domain --label "\u94A0\u7535\u56FA\u6001\u5316" --weight 0.2',
|
|
826
938
|
note: "dimension \u5FC5\u987B\u662F\u5DF2\u5B58\u5728\u7684\u7EF4\u5EA6 key\uFF1Bweight \u662F\u53D1\u8D77\u9879\u76EE\u65F6\u9884\u586B\u7ED9\u53D1\u8D77\u4EBA\u7684\u5EFA\u8BAE\u503C\uFF0C\u4E0D\u662F\u6700\u7EC8\u53C2\u4E0E\u8BA1\u7B97\u7684\u90A3\u4EFD"
|
|
827
939
|
}
|
|
828
940
|
];
|
|
829
|
-
var
|
|
941
|
+
var UPDATE_EXAMPLES4 = [
|
|
830
942
|
{ command: "pdlab taxonomy update tax_123 --weight 0.3", note: "\u53EA\u4F20\u8981\u6539\u7684\u5B57\u6BB5" }
|
|
831
943
|
];
|
|
832
|
-
var
|
|
944
|
+
var DELETE_EXAMPLES4 = [{ command: "pdlab taxonomy delete tax_123" }];
|
|
833
945
|
function toDimensionBody(opts) {
|
|
834
946
|
const body = {};
|
|
835
947
|
if (opts.key !== void 0) body.key = opts.key;
|
|
@@ -916,7 +1028,7 @@ function registerTaxonomyCommand(program2) {
|
|
|
916
1028
|
console.log(JSON.stringify(data, null, 2));
|
|
917
1029
|
}
|
|
918
1030
|
),
|
|
919
|
-
{ examples:
|
|
1031
|
+
{ examples: LIST_EXAMPLES4 }
|
|
920
1032
|
);
|
|
921
1033
|
attachMeta(
|
|
922
1034
|
withApiUrl(taxonomy.command("create").description("\u65B0\u5EFA\u5206\u7C7B\u6807\u7B7E")).option("--dimension <key>", "\u6240\u5C5E\u7EF4\u5EA6\u7684 key\uFF08\u5FC5\u586B\uFF0C\u987B\u662F\u5DF2\u5B58\u5728\u7684\u7EF4\u5EA6\uFF09").option("--label <label>", "\u6807\u7B7E\u503C\uFF08\u5FC5\u586B\uFF09").option("--weight <n>", "\u5EFA\u8BAE\u6743\u91CD 0~1\uFF08\u9009\u586B\uFF0C\u9ED8\u8BA4 0\uFF09").option("--sort-order <n>", "\u5C55\u793A\u6392\u5E8F\uFF0C\u6574\u6570 0-999\uFF08\u9009\u586B\uFF09").option("--description <text>", "\u6807\u7B7E\u8BF4\u660E\uFF08\u9009\u586B\uFF09").action(async (opts) => {
|
|
@@ -926,10 +1038,10 @@ function registerTaxonomyCommand(program2) {
|
|
|
926
1038
|
const data = await apiRequest("/api/taxonomies", { method: "POST", body, token, apiUrl: opts.apiUrl });
|
|
927
1039
|
console.log(JSON.stringify(data, null, 2));
|
|
928
1040
|
} catch (error) {
|
|
929
|
-
handleCommandError(error,
|
|
1041
|
+
handleCommandError(error, CREATE_EXAMPLES4);
|
|
930
1042
|
}
|
|
931
1043
|
}),
|
|
932
|
-
{ permission: PERMISSION, examples:
|
|
1044
|
+
{ permission: PERMISSION, examples: CREATE_EXAMPLES4 }
|
|
933
1045
|
);
|
|
934
1046
|
attachMeta(
|
|
935
1047
|
withApiUrl(taxonomy.command("update <id>").description("\u66F4\u65B0\u5206\u7C7B\u6807\u7B7E")).option("--dimension <key>", "\u6240\u5C5E\u7EF4\u5EA6\u7684 key").option("--label <label>", "\u6807\u7B7E\u503C").option("--weight <n>", "\u5EFA\u8BAE\u6743\u91CD 0~1").option("--sort-order <n>", "\u5C55\u793A\u6392\u5E8F").option("--description <text>", "\u6807\u7B7E\u8BF4\u660E").action(async (id, opts) => {
|
|
@@ -939,10 +1051,10 @@ function registerTaxonomyCommand(program2) {
|
|
|
939
1051
|
const data = await apiRequest(`/api/taxonomies/${id}`, { method: "PATCH", body, token, apiUrl: opts.apiUrl });
|
|
940
1052
|
console.log(JSON.stringify(data, null, 2));
|
|
941
1053
|
} catch (error) {
|
|
942
|
-
handleCommandError(error,
|
|
1054
|
+
handleCommandError(error, UPDATE_EXAMPLES4);
|
|
943
1055
|
}
|
|
944
1056
|
}),
|
|
945
|
-
{ permission: PERMISSION, examples:
|
|
1057
|
+
{ permission: PERMISSION, examples: UPDATE_EXAMPLES4 }
|
|
946
1058
|
);
|
|
947
1059
|
attachMeta(
|
|
948
1060
|
withApiUrl(taxonomy.command("delete <id>").description("\u5220\u9664\u5206\u7C7B\u6807\u7B7E")).action(
|
|
@@ -952,7 +1064,7 @@ function registerTaxonomyCommand(program2) {
|
|
|
952
1064
|
console.log(JSON.stringify(data, null, 2));
|
|
953
1065
|
}
|
|
954
1066
|
),
|
|
955
|
-
{ permission: PERMISSION, examples:
|
|
1067
|
+
{ permission: PERMISSION, examples: DELETE_EXAMPLES4 }
|
|
956
1068
|
);
|
|
957
1069
|
}
|
|
958
1070
|
|
|
@@ -975,6 +1087,9 @@ function exitCodeTable() {
|
|
|
975
1087
|
}
|
|
976
1088
|
return table;
|
|
977
1089
|
}
|
|
1090
|
+
function isInternalCommand(command) {
|
|
1091
|
+
return command.name().startsWith("__");
|
|
1092
|
+
}
|
|
978
1093
|
function serialize(command) {
|
|
979
1094
|
const meta = getMeta(command);
|
|
980
1095
|
return {
|
|
@@ -984,7 +1099,7 @@ function serialize(command) {
|
|
|
984
1099
|
arguments: command.registeredArguments.map((a) => ({ name: a.name(), required: a.required })),
|
|
985
1100
|
options: command.options.map((o) => ({ flags: o.flags, description: o.description, required: o.mandatory })),
|
|
986
1101
|
examples: meta.examples ?? [],
|
|
987
|
-
subcommands: command.commands.map(serialize)
|
|
1102
|
+
subcommands: command.commands.filter((c) => !isInternalCommand(c)).map(serialize)
|
|
988
1103
|
};
|
|
989
1104
|
}
|
|
990
1105
|
function registerSchemaCommand(program2) {
|
|
@@ -993,7 +1108,7 @@ function registerSchemaCommand(program2) {
|
|
|
993
1108
|
JSON.stringify(
|
|
994
1109
|
{
|
|
995
1110
|
exitCodes: exitCodeTable(),
|
|
996
|
-
commands: program2.commands.map(serialize)
|
|
1111
|
+
commands: program2.commands.filter((c) => !isInternalCommand(c)).map(serialize)
|
|
997
1112
|
},
|
|
998
1113
|
null,
|
|
999
1114
|
2
|
|
@@ -1002,8 +1117,96 @@ function registerSchemaCommand(program2) {
|
|
|
1002
1117
|
});
|
|
1003
1118
|
}
|
|
1004
1119
|
|
|
1120
|
+
// src/update-check.ts
|
|
1121
|
+
var import_fs2 = require("fs");
|
|
1122
|
+
var import_child_process = require("child_process");
|
|
1123
|
+
var import_path2 = require("path");
|
|
1124
|
+
var CACHE_FILE = (0, import_path2.join)(CONFIG_DIR, "update-check.json");
|
|
1125
|
+
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
1126
|
+
var FETCH_TIMEOUT_MS = 3e3;
|
|
1127
|
+
function readUpdateCache() {
|
|
1128
|
+
if (!(0, import_fs2.existsSync)(CACHE_FILE)) return { lastCheckedAt: 0 };
|
|
1129
|
+
try {
|
|
1130
|
+
return JSON.parse((0, import_fs2.readFileSync)(CACHE_FILE, "utf8"));
|
|
1131
|
+
} catch {
|
|
1132
|
+
return { lastCheckedAt: 0 };
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
function writeUpdateCache(cache) {
|
|
1136
|
+
if (!(0, import_fs2.existsSync)(CONFIG_DIR)) (0, import_fs2.mkdirSync)(CONFIG_DIR, { recursive: true, mode: 448 });
|
|
1137
|
+
(0, import_fs2.writeFileSync)(CACHE_FILE, JSON.stringify(cache, null, 2));
|
|
1138
|
+
}
|
|
1139
|
+
function parseVersion(version) {
|
|
1140
|
+
const match = /^(\d+)\.(\d+)\.(\d+)/.exec(version.trim());
|
|
1141
|
+
if (!match) return null;
|
|
1142
|
+
return [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
1143
|
+
}
|
|
1144
|
+
function isNewerVersion(candidate, current) {
|
|
1145
|
+
const a = parseVersion(candidate);
|
|
1146
|
+
const b = parseVersion(current);
|
|
1147
|
+
if (!a || !b) return false;
|
|
1148
|
+
for (let i = 0; i < 3; i++) {
|
|
1149
|
+
if (a[i] !== b[i]) return a[i] > b[i];
|
|
1150
|
+
}
|
|
1151
|
+
return false;
|
|
1152
|
+
}
|
|
1153
|
+
async function fetchLatestVersion(packageName) {
|
|
1154
|
+
const controller = new AbortController();
|
|
1155
|
+
const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
1156
|
+
try {
|
|
1157
|
+
const res = await fetch(`https://registry.npmjs.org/-/package/${packageName}/dist-tags`, {
|
|
1158
|
+
signal: controller.signal
|
|
1159
|
+
});
|
|
1160
|
+
if (!res.ok) return null;
|
|
1161
|
+
const data = await res.json();
|
|
1162
|
+
return data.latest ?? null;
|
|
1163
|
+
} catch {
|
|
1164
|
+
return null;
|
|
1165
|
+
} finally {
|
|
1166
|
+
clearTimeout(timer);
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
async function refreshUpdateCache(packageName) {
|
|
1170
|
+
const latestVersion = await fetchLatestVersion(packageName);
|
|
1171
|
+
const previous = readUpdateCache();
|
|
1172
|
+
writeUpdateCache({
|
|
1173
|
+
lastCheckedAt: Date.now(),
|
|
1174
|
+
latestVersion: latestVersion ?? previous.latestVersion
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
function spawnBackgroundRefresh(packageName) {
|
|
1178
|
+
try {
|
|
1179
|
+
const entry = process.argv[1];
|
|
1180
|
+
if (!entry) return;
|
|
1181
|
+
const child = (0, import_child_process.spawn)(process.execPath, [entry, "__update-check-worker", packageName], {
|
|
1182
|
+
detached: true,
|
|
1183
|
+
stdio: "ignore"
|
|
1184
|
+
});
|
|
1185
|
+
child.unref();
|
|
1186
|
+
} catch {
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
function notifyIfUpdateAvailable(currentVersion, packageName) {
|
|
1190
|
+
if (process.env.PDLAB_NO_UPDATE_CHECK) return;
|
|
1191
|
+
try {
|
|
1192
|
+
const cache = readUpdateCache();
|
|
1193
|
+
if (cache.latestVersion && isNewerVersion(cache.latestVersion, currentVersion)) {
|
|
1194
|
+
console.error(
|
|
1195
|
+
`
|
|
1196
|
+
\u203B ${packageName} \u6709\u65B0\u7248\u672C\u53EF\u7528\uFF1A${currentVersion} \u2192 ${cache.latestVersion}
|
|
1197
|
+
\u8FD0\u884C npm install -g ${packageName}@latest \u5347\u7EA7\uFF08\u53EF\u7528 PDLAB_NO_UPDATE_CHECK=1 \u5173\u95ED\u6B64\u63D0\u793A\uFF09
|
|
1198
|
+
`
|
|
1199
|
+
);
|
|
1200
|
+
}
|
|
1201
|
+
if (Date.now() - cache.lastCheckedAt > CHECK_INTERVAL_MS) {
|
|
1202
|
+
spawnBackgroundRefresh(packageName);
|
|
1203
|
+
}
|
|
1204
|
+
} catch {
|
|
1205
|
+
}
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1005
1208
|
// src/index.ts
|
|
1006
|
-
var pkg = JSON.parse((0,
|
|
1209
|
+
var pkg = JSON.parse((0, import_fs3.readFileSync)((0, import_path3.join)(__dirname, "../package.json"), "utf8"));
|
|
1007
1210
|
var program = new import_commander2.Command();
|
|
1008
1211
|
program.name("pdlab").description("1836 \u5F00\u6E90\u5171\u5EFA\u5E73\u53F0\u547D\u4EE4\u884C\u5DE5\u5177\u2014\u2014\u662F\u73B0\u6709 REST API \u7684\u8584\u5C01\u88C5\u3002\u7ED9 agent/\u811A\u672C\u7528\uFF1Apdlab schema \u4E00\u6B21\u6027\u5217\u51FA\u5168\u90E8\u547D\u4EE4\u3001\u53C2\u6570\u4E0E\u9000\u51FA\u7801\u542B\u4E49\u3002").version(pkg.version);
|
|
1009
1212
|
program.exitOverride();
|
|
@@ -1015,9 +1218,15 @@ registerLogoutCommand(program);
|
|
|
1015
1218
|
registerWhoamiCommand(program);
|
|
1016
1219
|
registerConfigCommand(program);
|
|
1017
1220
|
registerProjectCommand(program);
|
|
1221
|
+
registerCollectionCommand(program);
|
|
1018
1222
|
registerPostCommand(program);
|
|
1019
1223
|
registerTaxonomyCommand(program);
|
|
1020
1224
|
registerSchemaCommand(program);
|
|
1225
|
+
program.command("__update-check-worker <packageName>", { hidden: true }).action(async (packageName) => {
|
|
1226
|
+
await refreshUpdateCache(packageName);
|
|
1227
|
+
process.exit(0);
|
|
1228
|
+
});
|
|
1229
|
+
notifyIfUpdateAvailable(pkg.version, "pdlab-cli");
|
|
1021
1230
|
program.parseAsync(process.argv).catch((error) => {
|
|
1022
1231
|
if (error instanceof import_commander2.CommanderError && error.exitCode === 0) {
|
|
1023
1232
|
process.exit(0);
|