pdlab-cli 0.2.2 → 0.4.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 +30 -1
- package/dist/index.js +325 -21
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -50,8 +50,10 @@ 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 post list \| get \| create \| update \| delete` |
|
|
53
|
+
| `pdlab post list \| get \| create \| update \| delete` | 内容的增删改查(`--project-id` 选填,不填即独立发布,不挂任何项目) |
|
|
54
54
|
| `pdlab post review <id> --action approve\|reject` | 审核一条待审内容 |
|
|
55
|
+
| `pdlab taxonomy list \| create \| update \| delete` | 分类标签的增删改查(列表公开只读,写操作需 `taxonomy:manage`) |
|
|
56
|
+
| `pdlab taxonomy dimension list \| create \| update \| delete <key>` | 分类维度的增删改查(内置维度不可删) |
|
|
55
57
|
|
|
56
58
|
任何命令加 `--help` 看具体参数——示例已经直接打在 `--help` 末尾,不用等一次报错才能看到。
|
|
57
59
|
|
|
@@ -88,6 +90,17 @@ pdlab post list --project-id <项目 id>
|
|
|
88
90
|
# 审核待审内容(需要 content:review 权限)
|
|
89
91
|
pdlab post review post_123 --action approve
|
|
90
92
|
pdlab post review post_123 --action reject --comment "缺少数据来源,请补充引用"
|
|
93
|
+
|
|
94
|
+
# 独立发布内容(不挂任何项目),任何已生效账号都能发;非免审角色发出去要等发起人审
|
|
95
|
+
pdlab post create --title "钠电产业观察" --body "……"
|
|
96
|
+
|
|
97
|
+
# 分类维度与标签管理(需要 taxonomy:manage 权限,即「1836发起人」角色)
|
|
98
|
+
pdlab taxonomy dimension list # 公开只读
|
|
99
|
+
pdlab taxonomy dimension create --key region --label "地区" --sort-order 3
|
|
100
|
+
pdlab taxonomy create --dimension domain --label "钠电固态化" --weight 0.2
|
|
101
|
+
pdlab taxonomy update tax_123 --weight 0.3
|
|
102
|
+
pdlab taxonomy delete tax_123
|
|
103
|
+
pdlab taxonomy dimension delete region # 内置维度(domain/attribute/commercial)不可删
|
|
91
104
|
```
|
|
92
105
|
|
|
93
106
|
### 分页
|
|
@@ -136,6 +149,22 @@ API 地址的解析顺序:`--api-url` 参数 > `PDLAB_API_URL` 环境变量 >
|
|
|
136
149
|
作者也才能 `post get` 到自己那篇还没过审的稿子。没登录则匿名读公开内容,照常可用。
|
|
137
150
|
在 CI 里可以只给环境变量,不落配置文件。
|
|
138
151
|
|
|
152
|
+
## 版本更新提示
|
|
153
|
+
|
|
154
|
+
`pdlab` 每次运行都会顺手看一眼本地缓存的版本信息,如果有新版本会在命令结束时打印一行提示到
|
|
155
|
+
**stderr**(不影响 stdout 的 JSON 输出,脚本/agent 该怎么解析还怎么解析):
|
|
156
|
+
|
|
157
|
+
```
|
|
158
|
+
※ pdlab-cli 有新版本可用:0.3.0 → 0.4.0
|
|
159
|
+
运行 npm install -g pdlab-cli@latest 升级(可用 PDLAB_NO_UPDATE_CHECK=1 关闭此提示)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
这个检查本身不会拖慢任何命令:真正去问 npm registry 的动作放在一个独立的后台进程里做,
|
|
163
|
+
每 24 小时最多问一次,前台命令只读本地缓存(一次磁盘读,微秒级)。离线或连不上 registry
|
|
164
|
+
时静默跳过,不影响命令本身的执行结果。
|
|
165
|
+
|
|
166
|
+
不想看到这个提示:设置环境变量 `PDLAB_NO_UPDATE_CHECK=1`(CI/自动化脚本建议直接设置)。
|
|
167
|
+
|
|
139
168
|
## 凭证与安全
|
|
140
169
|
|
|
141
170
|
- **凭证怎么来的**:走设备码授权——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
|
|
@@ -297,27 +297,42 @@ function isSafeHttpUrl(raw) {
|
|
|
297
297
|
return ALLOWED_PROTOCOLS.has(url.protocol);
|
|
298
298
|
}
|
|
299
299
|
var safeHttpUrl = import_zod.z.string().trim().max(2048, "\u94FE\u63A5\u8FC7\u957F").refine(isSafeHttpUrl, "\u53EA\u652F\u6301 http/https \u5F00\u5934\u7684\u94FE\u63A5");
|
|
300
|
+
var INTERNAL_IMAGE_PATH = /^\/api\/images\/[a-z0-9]{1,64}$/;
|
|
301
|
+
function isInternalImagePath(raw) {
|
|
302
|
+
return INTERNAL_IMAGE_PATH.test(raw.trim());
|
|
303
|
+
}
|
|
304
|
+
function isSafeImageSrc(raw) {
|
|
305
|
+
return isInternalImagePath(raw) || isSafeHttpUrl(raw);
|
|
306
|
+
}
|
|
307
|
+
var safeImageUrl = import_zod.z.string().trim().max(2048, "\u94FE\u63A5\u8FC7\u957F").refine(isSafeImageSrc, "\u53EA\u652F\u6301 http/https \u94FE\u63A5\u6216\u5E73\u53F0\u5185\u4E0A\u4F20\u7684\u56FE\u7247");
|
|
300
308
|
|
|
301
309
|
// ../shared-schemas/src/projects.ts
|
|
302
310
|
var import_zod2 = require("zod");
|
|
311
|
+
var taxonomySelectionSchema = import_zod2.z.object({
|
|
312
|
+
taxonomyId: import_zod2.z.string().min(1).describe("\u5206\u7C7B\u6807\u7B7E id"),
|
|
313
|
+
weight: import_zod2.z.number().min(0).max(1).describe("\u8BE5\u6807\u7B7E\u5728\u672C\u9879\u76EE\u91CC\u7684\u6743\u91CD 0~1")
|
|
314
|
+
});
|
|
303
315
|
var PROJECT_STATUS_VALUES = ["planning", "active", "review", "completed"];
|
|
304
316
|
var projectCreateSchema = import_zod2.z.object({
|
|
305
317
|
title: import_zod2.z.string().trim().min(1, "\u9879\u76EE\u6807\u9898\u4E0D\u80FD\u4E3A\u7A7A").max(200).describe("\u9879\u76EE\u6807\u9898"),
|
|
306
318
|
description: import_zod2.z.string().max(2e4).optional().describe("\u9879\u76EE\u63CF\u8FF0"),
|
|
307
|
-
coverImage:
|
|
308
|
-
commercialType: import_zod2.z.string().max(100).optional().describe("\u5546\u4E1A\
|
|
319
|
+
coverImage: safeImageUrl.optional().describe("\u5C01\u9762\u56FE\u94FE\u63A5\u6216\u4E0A\u4F20\u56FE\u7247\u5730\u5740"),
|
|
320
|
+
commercialType: import_zod2.z.string().max(100).optional().describe("\u5546\u4E1A\u5408\u4F5C\u72B6\u6001\uFF0C\u5982\u300C\u4E0E\u67D0IDC\u5382\u5546\u63A5\u6D3D\u4E2D\u300D"),
|
|
309
321
|
status: import_zod2.z.enum(PROJECT_STATUS_VALUES).optional().describe("\u9879\u76EE\u72B6\u6001\uFF1Aplanning/active/review/completed"),
|
|
310
322
|
progress: import_zod2.z.number().int().min(0).max(100).optional().describe("\u9879\u76EE\u8FDB\u5EA6\u767E\u5206\u6BD4 0-100"),
|
|
311
|
-
|
|
323
|
+
taxonomies: import_zod2.z.array(taxonomySelectionSchema).max(50).optional().describe("\u5206\u7C7B\u6807\u7B7E\u53CA\u5176\u5728\u672C\u9879\u76EE\u91CC\u7684\u6743\u91CD\uFF0C\u6BCF\u4E2A\u7EF4\u5EA6\u6700\u591A\u4E00\u4E2A\u6807\u7B7E"),
|
|
324
|
+
// 兼容 pdlab CLI 的旧参数:只给 id、不给权重时,服务端按标签的全局建议权重(Taxonomy.weight)填充
|
|
325
|
+
taxonomyIds: import_zod2.z.array(import_zod2.z.string().min(1)).max(50).optional().default([]).describe("\u5206\u7C7B\u6807\u7B7E id \u5217\u8868\uFF08\u65E7\u53C2\u6570\uFF0C\u6743\u91CD\u53D6\u6807\u7B7E\u9ED8\u8BA4\u503C\uFF09")
|
|
312
326
|
});
|
|
313
327
|
var projectUpdateSchema = import_zod2.z.object({
|
|
314
328
|
title: import_zod2.z.string().trim().min(1, "\u9879\u76EE\u6807\u9898\u4E0D\u80FD\u4E3A\u7A7A").max(200).optional().describe("\u9879\u76EE\u6807\u9898"),
|
|
315
329
|
description: import_zod2.z.string().max(2e4).nullable().optional().describe("\u9879\u76EE\u63CF\u8FF0"),
|
|
316
|
-
coverImage:
|
|
317
|
-
commercialType: import_zod2.z.string().max(100).nullable().optional().describe("\u5546\u4E1A\
|
|
330
|
+
coverImage: safeImageUrl.nullable().optional().describe("\u5C01\u9762\u56FE\u94FE\u63A5\u6216\u4E0A\u4F20\u56FE\u7247\u5730\u5740"),
|
|
331
|
+
commercialType: import_zod2.z.string().max(100).nullable().optional().describe("\u5546\u4E1A\u5408\u4F5C\u72B6\u6001"),
|
|
318
332
|
progress: import_zod2.z.number().int().min(0).max(100).optional().describe("\u9879\u76EE\u8FDB\u5EA6\u767E\u5206\u6BD4 0-100"),
|
|
319
333
|
status: import_zod2.z.enum(PROJECT_STATUS_VALUES).optional().describe("\u9879\u76EE\u72B6\u6001\uFF1Aplanning/active/review/completed"),
|
|
320
|
-
|
|
334
|
+
taxonomies: import_zod2.z.array(taxonomySelectionSchema).max(50).optional().describe("\u5206\u7C7B\u6807\u7B7E\u53CA\u5176\u6743\u91CD\uFF08\u5168\u91CF\u66FF\u6362\uFF09"),
|
|
335
|
+
taxonomyIds: import_zod2.z.array(import_zod2.z.string().min(1)).max(50).optional().describe("\u5206\u7C7B\u6807\u7B7E id \u5217\u8868\uFF08\u65E7\u53C2\u6570\uFF0C\u5168\u91CF\u66FF\u6362\uFF0C\u6743\u91CD\u53D6\u6807\u7B7E\u9ED8\u8BA4\u503C\uFF09")
|
|
321
336
|
}).refine((v) => Object.keys(v).length > 0, "\u6CA1\u6709\u9700\u8981\u66F4\u65B0\u7684\u5B57\u6BB5");
|
|
322
337
|
|
|
323
338
|
// ../shared-schemas/src/posts.ts
|
|
@@ -325,22 +340,52 @@ var import_zod3 = require("zod");
|
|
|
325
340
|
var postCreateSchema = import_zod3.z.object({
|
|
326
341
|
title: import_zod3.z.string().min(1).describe("\u5185\u5BB9\u6807\u9898"),
|
|
327
342
|
body: import_zod3.z.string().min(1).describe("\u5185\u5BB9\u6B63\u6587"),
|
|
328
|
-
|
|
329
|
-
|
|
343
|
+
// V3.1:可以不挂项目独立发布。挂项目时仍然要求发布者是该项目的发起人或已通过审核的参与者。
|
|
344
|
+
projectId: import_zod3.z.string().min(1).nullish().describe("\u6240\u5C5E\u9879\u76EE id\uFF0C\u4E0D\u586B\u8868\u793A\u72EC\u7ACB\u53D1\u5E03"),
|
|
345
|
+
mediaLinks: import_zod3.z.array(safeImageUrl).max(20, "\u5A92\u4F53\u4E0E\u56FE\u7247\u6700\u591A 20 \u6761").optional().default([]).describe("\u4E0A\u4F20\u7684\u56FE\u7247\u5730\u5740\u3001\u89C6\u9891\u94FE\u63A5\u4E0E\u5916\u90E8\u94FE\u63A5")
|
|
330
346
|
});
|
|
331
347
|
var postUpdateSchema = import_zod3.z.object({
|
|
332
348
|
title: import_zod3.z.string().trim().min(1, "\u6807\u9898\u4E0D\u80FD\u4E3A\u7A7A").max(200).describe("\u5185\u5BB9\u6807\u9898"),
|
|
333
349
|
body: import_zod3.z.string().trim().min(1, "\u6B63\u6587\u4E0D\u80FD\u4E3A\u7A7A").max(5e4).describe("\u5185\u5BB9\u6B63\u6587"),
|
|
334
|
-
mediaLinks: import_zod3.z.array(
|
|
350
|
+
mediaLinks: import_zod3.z.array(safeImageUrl).max(20).optional().default([]).describe("\u4E0A\u4F20\u7684\u56FE\u7247\u5730\u5740\u3001\u89C6\u9891\u94FE\u63A5\u4E0E\u5916\u90E8\u94FE\u63A5")
|
|
335
351
|
});
|
|
336
352
|
var postReviewSchema = import_zod3.z.object({
|
|
337
353
|
action: import_zod3.z.enum(["approve", "reject"]).describe("\u5BA1\u6838\u7ED3\u679C\uFF1Aapprove/reject"),
|
|
338
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")
|
|
339
355
|
});
|
|
340
356
|
|
|
357
|
+
// ../shared-schemas/src/taxonomies.ts
|
|
358
|
+
var import_zod4 = require("zod");
|
|
359
|
+
var taxonomyDimensionCreateSchema = import_zod4.z.object({
|
|
360
|
+
// key 会进 URL 查询串和导出文件,限制成 slug 形态
|
|
361
|
+
key: import_zod4.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"),
|
|
362
|
+
label: import_zod4.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"),
|
|
363
|
+
description: import_zod4.z.string().max(500).optional().describe("\u7EF4\u5EA6\u8BF4\u660E"),
|
|
364
|
+
sortOrder: import_zod4.z.number().int().min(0).max(999).optional().default(0).describe("\u5C55\u793A\u6392\u5E8F")
|
|
365
|
+
});
|
|
366
|
+
var taxonomyDimensionUpdateSchema = import_zod4.z.object({
|
|
367
|
+
label: import_zod4.z.string().trim().min(1).max(40).optional().describe("\u7EF4\u5EA6\u4E2D\u6587\u540D"),
|
|
368
|
+
description: import_zod4.z.string().max(500).nullable().optional().describe("\u7EF4\u5EA6\u8BF4\u660E"),
|
|
369
|
+
sortOrder: import_zod4.z.number().int().min(0).max(999).optional().describe("\u5C55\u793A\u6392\u5E8F")
|
|
370
|
+
});
|
|
371
|
+
var taxonomyCreateSchema = import_zod4.z.object({
|
|
372
|
+
dimension: import_zod4.z.string().min(1).describe("\u6240\u5C5E\u7EF4\u5EA6\u7684 key\uFF0C\u5982 domain"),
|
|
373
|
+
label: import_zod4.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"),
|
|
374
|
+
weight: import_zod4.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"),
|
|
375
|
+
sortOrder: import_zod4.z.number().int().min(0).max(999).optional().default(0).describe("\u5C55\u793A\u6392\u5E8F"),
|
|
376
|
+
description: import_zod4.z.string().max(500).optional().describe("\u6807\u7B7E\u8BF4\u660E")
|
|
377
|
+
});
|
|
378
|
+
var taxonomyUpdateSchema = import_zod4.z.object({
|
|
379
|
+
dimension: import_zod4.z.string().min(1).optional().describe("\u6240\u5C5E\u7EF4\u5EA6\u7684 key"),
|
|
380
|
+
label: import_zod4.z.string().min(1).optional().describe("\u6807\u7B7E\u503C"),
|
|
381
|
+
weight: import_zod4.z.number().min(0).max(1).optional().describe("\u5EFA\u8BAE\u6743\u91CD 0~1"),
|
|
382
|
+
sortOrder: import_zod4.z.number().int().optional().describe("\u5C55\u793A\u6392\u5E8F"),
|
|
383
|
+
description: import_zod4.z.string().optional().describe("\u6807\u7B7E\u8BF4\u660E")
|
|
384
|
+
});
|
|
385
|
+
|
|
341
386
|
// src/errors.ts
|
|
342
387
|
var import_commander = require("commander");
|
|
343
|
-
var
|
|
388
|
+
var import_zod5 = require("zod");
|
|
344
389
|
var EXIT_CODES = {
|
|
345
390
|
ok: 0,
|
|
346
391
|
unhandled: 1,
|
|
@@ -373,7 +418,7 @@ function exampleHint(examples) {
|
|
|
373
418
|
}
|
|
374
419
|
function handleCommandError(error, examples = []) {
|
|
375
420
|
let structured;
|
|
376
|
-
if (error instanceof
|
|
421
|
+
if (error instanceof import_zod5.ZodError) {
|
|
377
422
|
structured = {
|
|
378
423
|
error: "\u53C2\u6570\u6821\u9A8C\u5931\u8D25",
|
|
379
424
|
code: "validation",
|
|
@@ -636,9 +681,13 @@ function registerProjectCommand(program2) {
|
|
|
636
681
|
|
|
637
682
|
// src/commands/post.ts
|
|
638
683
|
var CREATE_EXAMPLES2 = [
|
|
684
|
+
{
|
|
685
|
+
command: 'pdlab post create --title "\u94A0\u7535\u4EA7\u4E1A\u89C2\u5BDF" --body "..."',
|
|
686
|
+
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"
|
|
687
|
+
},
|
|
639
688
|
{
|
|
640
689
|
command: 'pdlab post create --title "\u7B2C\u4E00\u5468\u8FDB\u5C55" --body "..." --project-id proj_123 --media-links https://example.com/a.png',
|
|
641
|
-
note: "
|
|
690
|
+
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"
|
|
642
691
|
}
|
|
643
692
|
];
|
|
644
693
|
var UPDATE_EXAMPLES2 = [
|
|
@@ -646,6 +695,7 @@ var UPDATE_EXAMPLES2 = [
|
|
|
646
695
|
];
|
|
647
696
|
var LIST_EXAMPLES2 = [
|
|
648
697
|
{ command: "pdlab post list --project-id proj_123", note: "\u53EA\u770B\u67D0\u4E2A\u9879\u76EE\u4E0B\u7684\u5185\u5BB9" },
|
|
698
|
+
{ 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" },
|
|
649
699
|
{ 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" },
|
|
650
700
|
{ 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" }
|
|
651
701
|
];
|
|
@@ -670,7 +720,7 @@ function toMediaLinks(value) {
|
|
|
670
720
|
function registerPostCommand(program2) {
|
|
671
721
|
const post = program2.command("post").description("\u5185\u5BB9\uFF08\u5E16\u5B50\uFF09\u7684\u589E\u5220\u6539\u67E5\u4E0E\u5BA1\u6838");
|
|
672
722
|
attachMeta(
|
|
673
|
-
withApiUrl(post.command("list").description("\u5217\u51FA\u5185\u5BB9\uFF08approved \u5185\u5BB9\u516C\u5F00\u53EA\u8BFB\uFF0C\u4E0D\u767B\u5F55\u4E5F\u80FD\u7528\uFF09")).option("--project-id <id>", "\u6309\u9879\u76EE\u7B5B\u9009").option("--status <status>", "pending | approved | rejected\uFF08\u67E5\u770B\u975E approved \u9700\u8981\u5BA1\u6838\u6743\u9650\uFF09").option("--limit <n>", "\u5355\u9875\u6570\u91CF\uFF0C\u9ED8\u8BA4 30\uFF0C\u4E0A\u9650 100").option("--cursor <token>", "\u7FFB\u9875\u6E38\u6807\uFF0C\u53D6\u4E0A\u4E00\u9875\u54CD\u5E94\u91CC\u7684 nextCursor").action(async (opts) => {
|
|
723
|
+
withApiUrl(post.command("list").description("\u5217\u51FA\u5185\u5BB9\uFF08approved \u5185\u5BB9\u516C\u5F00\u53EA\u8BFB\uFF0C\u4E0D\u767B\u5F55\u4E5F\u80FD\u7528\uFF09")).option("--project-id <id>", "\u6309\u9879\u76EE\u7B5B\u9009\uFF1B\u4F20 none \u53EA\u770B\u72EC\u7ACB\u53D1\u5E03\uFF08\u4E0D\u6302\u9879\u76EE\uFF09\u7684\u5185\u5BB9").option("--status <status>", "pending | approved | rejected\uFF08\u67E5\u770B\u975E approved \u9700\u8981\u5BA1\u6838\u6743\u9650\uFF09").option("--limit <n>", "\u5355\u9875\u6570\u91CF\uFF0C\u9ED8\u8BA4 30\uFF0C\u4E0A\u9650 100").option("--cursor <token>", "\u7FFB\u9875\u6E38\u6807\uFF0C\u53D6\u4E0A\u4E00\u9875\u54CD\u5E94\u91CC\u7684 nextCursor").action(async (opts) => {
|
|
674
724
|
const data = await apiRequest("/api/posts", {
|
|
675
725
|
query: { projectId: opts.projectId, status: opts.status, limit: opts.limit, cursor: opts.cursor },
|
|
676
726
|
token: optionalToken(),
|
|
@@ -690,7 +740,7 @@ function registerPostCommand(program2) {
|
|
|
690
740
|
{ examples: GET_EXAMPLES2 }
|
|
691
741
|
);
|
|
692
742
|
attachMeta(
|
|
693
|
-
withApiUrl(post.command("create").description("\u53D1\u5E03\u5185\u5BB9")).option("--title <title>", "\u5185\u5BB9\u6807\u9898\uFF08\u5FC5\u586B\uFF09").option("--body <body>", "\u5185\u5BB9\u6B63\u6587\uFF08\u5FC5\u586B\uFF09").option("--project-id <id>", "\u6240\u5C5E\u9879\u76EE id\uFF08\
|
|
743
|
+
withApiUrl(post.command("create").description("\u53D1\u5E03\u5185\u5BB9")).option("--title <title>", "\u5185\u5BB9\u6807\u9898\uFF08\u5FC5\u586B\uFF09").option("--body <body>", "\u5185\u5BB9\u6B63\u6587\uFF08\u5FC5\u586B\uFF09").option("--project-id <id>", "\u6240\u5C5E\u9879\u76EE id\uFF08\u9009\u586B\uFF0C\u4E0D\u586B\u5373\u72EC\u7ACB\u53D1\u5E03\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 (opts) => {
|
|
694
744
|
const token = requireToken();
|
|
695
745
|
try {
|
|
696
746
|
const body = postCreateSchema.parse({
|
|
@@ -705,10 +755,10 @@ function registerPostCommand(program2) {
|
|
|
705
755
|
handleCommandError(error, CREATE_EXAMPLES2);
|
|
706
756
|
}
|
|
707
757
|
}),
|
|
708
|
-
{ permission: "content:create\
|
|
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: CREATE_EXAMPLES2 }
|
|
709
759
|
);
|
|
710
760
|
attachMeta(
|
|
711
|
-
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\
|
|
761
|
+
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) => {
|
|
712
762
|
const token = requireToken();
|
|
713
763
|
try {
|
|
714
764
|
const body = postUpdateSchema.parse({
|
|
@@ -749,6 +799,163 @@ function registerPostCommand(program2) {
|
|
|
749
799
|
);
|
|
750
800
|
}
|
|
751
801
|
|
|
802
|
+
// src/commands/taxonomy.ts
|
|
803
|
+
var PERMISSION = "taxonomy:manage\uFF08\u4EC5\u300C1836\u53D1\u8D77\u4EBA\u300D\u89D2\u8272\uFF09";
|
|
804
|
+
var DIM_LIST_EXAMPLES = [
|
|
805
|
+
{ command: "pdlab taxonomy dimension list", note: "\u516C\u5F00\u53EA\u8BFB\uFF0C\u4E0D\u767B\u5F55\u4E5F\u80FD\u7528" }
|
|
806
|
+
];
|
|
807
|
+
var DIM_CREATE_EXAMPLES = [
|
|
808
|
+
{
|
|
809
|
+
command: 'pdlab taxonomy dimension create --key region --label "\u5730\u533A" --sort-order 3',
|
|
810
|
+
note: "key \u53EA\u80FD\u5C0F\u5199\u5B57\u6BCD/\u6570\u5B57/\u4E0B\u5212\u7EBF\u4E14\u4EE5\u5B57\u6BCD\u5F00\u5934\uFF0C\u5EFA\u597D\u4E4B\u540E\u4E0D\u80FD\u6539"
|
|
811
|
+
}
|
|
812
|
+
];
|
|
813
|
+
var DIM_UPDATE_EXAMPLES = [
|
|
814
|
+
{ command: 'pdlab taxonomy dimension update domain --label "\u9886\u57DF\uFF08\u66F4\u65B0\uFF09"', note: "key \u4E0D\u53EF\u6539\uFF0C\u53EA\u80FD\u6539\u5C55\u793A\u5C5E\u6027" }
|
|
815
|
+
];
|
|
816
|
+
var DIM_DELETE_EXAMPLES = [
|
|
817
|
+
{
|
|
818
|
+
command: "pdlab taxonomy dimension delete region",
|
|
819
|
+
note: "\u5185\u7F6E\u7EF4\u5EA6\uFF08domain/attribute/commercial\uFF09\u4E0D\u53EF\u5220\uFF1B\u7EF4\u5EA6\u4E0B\u8FD8\u6709\u6807\u7B7E\u65F6\u4F1A 409"
|
|
820
|
+
}
|
|
821
|
+
];
|
|
822
|
+
var LIST_EXAMPLES3 = [{ command: "pdlab taxonomy list", note: "\u516C\u5F00\u53EA\u8BFB\uFF0C\u4E0D\u767B\u5F55\u4E5F\u80FD\u7528" }];
|
|
823
|
+
var CREATE_EXAMPLES3 = [
|
|
824
|
+
{
|
|
825
|
+
command: 'pdlab taxonomy create --dimension domain --label "\u94A0\u7535\u56FA\u6001\u5316" --weight 0.2',
|
|
826
|
+
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
|
+
}
|
|
828
|
+
];
|
|
829
|
+
var UPDATE_EXAMPLES3 = [
|
|
830
|
+
{ command: "pdlab taxonomy update tax_123 --weight 0.3", note: "\u53EA\u4F20\u8981\u6539\u7684\u5B57\u6BB5" }
|
|
831
|
+
];
|
|
832
|
+
var DELETE_EXAMPLES3 = [{ command: "pdlab taxonomy delete tax_123" }];
|
|
833
|
+
function toDimensionBody(opts) {
|
|
834
|
+
const body = {};
|
|
835
|
+
if (opts.key !== void 0) body.key = opts.key;
|
|
836
|
+
if (opts.label !== void 0) body.label = opts.label;
|
|
837
|
+
if (opts.description !== void 0) body.description = opts.description;
|
|
838
|
+
if (opts.sortOrder !== void 0) body.sortOrder = Number(opts.sortOrder);
|
|
839
|
+
return body;
|
|
840
|
+
}
|
|
841
|
+
function toTaxonomyBody(opts) {
|
|
842
|
+
const body = {};
|
|
843
|
+
if (opts.dimension !== void 0) body.dimension = opts.dimension;
|
|
844
|
+
if (opts.label !== void 0) body.label = opts.label;
|
|
845
|
+
if (opts.weight !== void 0) body.weight = Number(opts.weight);
|
|
846
|
+
if (opts.sortOrder !== void 0) body.sortOrder = Number(opts.sortOrder);
|
|
847
|
+
if (opts.description !== void 0) body.description = opts.description;
|
|
848
|
+
return body;
|
|
849
|
+
}
|
|
850
|
+
function registerTaxonomyCommand(program2) {
|
|
851
|
+
const taxonomy = program2.command("taxonomy").description("\u5206\u7C7B\u7EF4\u5EA6\u4E0E\u5206\u7C7B\u6807\u7B7E\u7684\u589E\u5220\u6539\u67E5\uFF08PRD 4.2.4\uFF09");
|
|
852
|
+
const dimension = taxonomy.command("dimension").description("\u5206\u7C7B\u7EF4\u5EA6\uFF08\u9886\u57DF/\u5C5E\u6027/\u5546\u4E1A\u2026\u2026\uFF09\u7684\u589E\u5220\u6539\u67E5");
|
|
853
|
+
attachMeta(
|
|
854
|
+
withApiUrl(dimension.command("list").description("\u5217\u51FA\u5168\u90E8\u5206\u7C7B\u7EF4\u5EA6\uFF08\u516C\u5F00\u53EA\u8BFB\uFF0C\u4E0D\u767B\u5F55\u4E5F\u80FD\u7528\uFF09")).action(
|
|
855
|
+
async (opts) => {
|
|
856
|
+
const data = await apiRequest("/api/taxonomy-dimensions", { token: optionalToken(), apiUrl: opts.apiUrl });
|
|
857
|
+
console.log(JSON.stringify(data, null, 2));
|
|
858
|
+
}
|
|
859
|
+
),
|
|
860
|
+
{ examples: DIM_LIST_EXAMPLES }
|
|
861
|
+
);
|
|
862
|
+
attachMeta(
|
|
863
|
+
withApiUrl(dimension.command("create").description("\u65B0\u5EFA\u5206\u7C7B\u7EF4\u5EA6")).option("--key <key>", "\u7EF4\u5EA6\u6807\u8BC6\uFF08\u5FC5\u586B\uFF0C\u5C0F\u5199\u5B57\u6BCD/\u6570\u5B57/\u4E0B\u5212\u7EBF\uFF0C\u4EE5\u5B57\u6BCD\u5F00\u5934\uFF0C\u521B\u5EFA\u540E\u4E0D\u53EF\u6539\uFF09").option("--label <label>", "\u7EF4\u5EA6\u4E2D\u6587\u540D\uFF08\u5FC5\u586B\uFF09").option("--description <text>", "\u7EF4\u5EA6\u8BF4\u660E\uFF08\u9009\u586B\uFF09").option("--sort-order <n>", "\u5C55\u793A\u6392\u5E8F\uFF0C\u6574\u6570 0-999\uFF08\u9009\u586B\uFF09").action(async (opts) => {
|
|
864
|
+
const token = requireToken();
|
|
865
|
+
try {
|
|
866
|
+
const body = taxonomyDimensionCreateSchema.parse(toDimensionBody(opts));
|
|
867
|
+
const data = await apiRequest("/api/taxonomy-dimensions", {
|
|
868
|
+
method: "POST",
|
|
869
|
+
body,
|
|
870
|
+
token,
|
|
871
|
+
apiUrl: opts.apiUrl
|
|
872
|
+
});
|
|
873
|
+
console.log(JSON.stringify(data, null, 2));
|
|
874
|
+
} catch (error) {
|
|
875
|
+
handleCommandError(error, DIM_CREATE_EXAMPLES);
|
|
876
|
+
}
|
|
877
|
+
}),
|
|
878
|
+
{ permission: PERMISSION, examples: DIM_CREATE_EXAMPLES }
|
|
879
|
+
);
|
|
880
|
+
attachMeta(
|
|
881
|
+
withApiUrl(dimension.command("update <key>").description("\u66F4\u65B0\u5206\u7C7B\u7EF4\u5EA6\u7684\u5C55\u793A\u5C5E\u6027\uFF08key \u672C\u8EAB\u4E0D\u53EF\u6539\uFF09")).option("--label <label>", "\u7EF4\u5EA6\u4E2D\u6587\u540D").option("--description <text>", "\u7EF4\u5EA6\u8BF4\u660E").option("--sort-order <n>", "\u5C55\u793A\u6392\u5E8F\uFF0C\u6574\u6570 0-999").action(async (key, opts) => {
|
|
882
|
+
const token = requireToken();
|
|
883
|
+
try {
|
|
884
|
+
const body = taxonomyDimensionUpdateSchema.parse(toDimensionBody(opts));
|
|
885
|
+
const data = await apiRequest(`/api/taxonomy-dimensions/${key}`, {
|
|
886
|
+
method: "PATCH",
|
|
887
|
+
body,
|
|
888
|
+
token,
|
|
889
|
+
apiUrl: opts.apiUrl
|
|
890
|
+
});
|
|
891
|
+
console.log(JSON.stringify(data, null, 2));
|
|
892
|
+
} catch (error) {
|
|
893
|
+
handleCommandError(error, DIM_UPDATE_EXAMPLES);
|
|
894
|
+
}
|
|
895
|
+
}),
|
|
896
|
+
{ permission: PERMISSION, examples: DIM_UPDATE_EXAMPLES }
|
|
897
|
+
);
|
|
898
|
+
attachMeta(
|
|
899
|
+
withApiUrl(
|
|
900
|
+
dimension.command("delete <key>").description("\u5220\u9664\u5206\u7C7B\u7EF4\u5EA6\uFF08\u5185\u7F6E\u7EF4\u5EA6\u4E0D\u53EF\u5220\uFF1B\u7EF4\u5EA6\u4E0B\u8FD8\u6709\u6807\u7B7E\u65F6\u4F1A 409\uFF09")
|
|
901
|
+
).action(async (key, opts) => {
|
|
902
|
+
const token = requireToken();
|
|
903
|
+
const data = await apiRequest(`/api/taxonomy-dimensions/${key}`, {
|
|
904
|
+
method: "DELETE",
|
|
905
|
+
token,
|
|
906
|
+
apiUrl: opts.apiUrl
|
|
907
|
+
});
|
|
908
|
+
console.log(JSON.stringify(data, null, 2));
|
|
909
|
+
}),
|
|
910
|
+
{ permission: PERMISSION, examples: DIM_DELETE_EXAMPLES }
|
|
911
|
+
);
|
|
912
|
+
attachMeta(
|
|
913
|
+
withApiUrl(taxonomy.command("list").description("\u5217\u51FA\u5168\u90E8\u5206\u7C7B\u6807\u7B7E\uFF08\u516C\u5F00\u53EA\u8BFB\uFF0C\u4E0D\u767B\u5F55\u4E5F\u80FD\u7528\uFF09")).action(
|
|
914
|
+
async (opts) => {
|
|
915
|
+
const data = await apiRequest("/api/taxonomies", { token: optionalToken(), apiUrl: opts.apiUrl });
|
|
916
|
+
console.log(JSON.stringify(data, null, 2));
|
|
917
|
+
}
|
|
918
|
+
),
|
|
919
|
+
{ examples: LIST_EXAMPLES3 }
|
|
920
|
+
);
|
|
921
|
+
attachMeta(
|
|
922
|
+
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) => {
|
|
923
|
+
const token = requireToken();
|
|
924
|
+
try {
|
|
925
|
+
const body = taxonomyCreateSchema.parse(toTaxonomyBody(opts));
|
|
926
|
+
const data = await apiRequest("/api/taxonomies", { method: "POST", body, token, apiUrl: opts.apiUrl });
|
|
927
|
+
console.log(JSON.stringify(data, null, 2));
|
|
928
|
+
} catch (error) {
|
|
929
|
+
handleCommandError(error, CREATE_EXAMPLES3);
|
|
930
|
+
}
|
|
931
|
+
}),
|
|
932
|
+
{ permission: PERMISSION, examples: CREATE_EXAMPLES3 }
|
|
933
|
+
);
|
|
934
|
+
attachMeta(
|
|
935
|
+
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) => {
|
|
936
|
+
const token = requireToken();
|
|
937
|
+
try {
|
|
938
|
+
const body = taxonomyUpdateSchema.parse(toTaxonomyBody(opts));
|
|
939
|
+
const data = await apiRequest(`/api/taxonomies/${id}`, { method: "PATCH", body, token, apiUrl: opts.apiUrl });
|
|
940
|
+
console.log(JSON.stringify(data, null, 2));
|
|
941
|
+
} catch (error) {
|
|
942
|
+
handleCommandError(error, UPDATE_EXAMPLES3);
|
|
943
|
+
}
|
|
944
|
+
}),
|
|
945
|
+
{ permission: PERMISSION, examples: UPDATE_EXAMPLES3 }
|
|
946
|
+
);
|
|
947
|
+
attachMeta(
|
|
948
|
+
withApiUrl(taxonomy.command("delete <id>").description("\u5220\u9664\u5206\u7C7B\u6807\u7B7E")).action(
|
|
949
|
+
async (id, opts) => {
|
|
950
|
+
const token = requireToken();
|
|
951
|
+
const data = await apiRequest(`/api/taxonomies/${id}`, { method: "DELETE", token, apiUrl: opts.apiUrl });
|
|
952
|
+
console.log(JSON.stringify(data, null, 2));
|
|
953
|
+
}
|
|
954
|
+
),
|
|
955
|
+
{ permission: PERMISSION, examples: DELETE_EXAMPLES3 }
|
|
956
|
+
);
|
|
957
|
+
}
|
|
958
|
+
|
|
752
959
|
// src/commands/schema.ts
|
|
753
960
|
var CODE_DESCRIPTION = {
|
|
754
961
|
ok: "\u6210\u529F",
|
|
@@ -768,6 +975,9 @@ function exitCodeTable() {
|
|
|
768
975
|
}
|
|
769
976
|
return table;
|
|
770
977
|
}
|
|
978
|
+
function isInternalCommand(command) {
|
|
979
|
+
return command.name().startsWith("__");
|
|
980
|
+
}
|
|
771
981
|
function serialize(command) {
|
|
772
982
|
const meta = getMeta(command);
|
|
773
983
|
return {
|
|
@@ -777,7 +987,7 @@ function serialize(command) {
|
|
|
777
987
|
arguments: command.registeredArguments.map((a) => ({ name: a.name(), required: a.required })),
|
|
778
988
|
options: command.options.map((o) => ({ flags: o.flags, description: o.description, required: o.mandatory })),
|
|
779
989
|
examples: meta.examples ?? [],
|
|
780
|
-
subcommands: command.commands.map(serialize)
|
|
990
|
+
subcommands: command.commands.filter((c) => !isInternalCommand(c)).map(serialize)
|
|
781
991
|
};
|
|
782
992
|
}
|
|
783
993
|
function registerSchemaCommand(program2) {
|
|
@@ -786,7 +996,7 @@ function registerSchemaCommand(program2) {
|
|
|
786
996
|
JSON.stringify(
|
|
787
997
|
{
|
|
788
998
|
exitCodes: exitCodeTable(),
|
|
789
|
-
commands: program2.commands.map(serialize)
|
|
999
|
+
commands: program2.commands.filter((c) => !isInternalCommand(c)).map(serialize)
|
|
790
1000
|
},
|
|
791
1001
|
null,
|
|
792
1002
|
2
|
|
@@ -795,8 +1005,96 @@ function registerSchemaCommand(program2) {
|
|
|
795
1005
|
});
|
|
796
1006
|
}
|
|
797
1007
|
|
|
1008
|
+
// src/update-check.ts
|
|
1009
|
+
var import_fs2 = require("fs");
|
|
1010
|
+
var import_child_process = require("child_process");
|
|
1011
|
+
var import_path2 = require("path");
|
|
1012
|
+
var CACHE_FILE = (0, import_path2.join)(CONFIG_DIR, "update-check.json");
|
|
1013
|
+
var CHECK_INTERVAL_MS = 24 * 60 * 60 * 1e3;
|
|
1014
|
+
var FETCH_TIMEOUT_MS = 3e3;
|
|
1015
|
+
function readUpdateCache() {
|
|
1016
|
+
if (!(0, import_fs2.existsSync)(CACHE_FILE)) return { lastCheckedAt: 0 };
|
|
1017
|
+
try {
|
|
1018
|
+
return JSON.parse((0, import_fs2.readFileSync)(CACHE_FILE, "utf8"));
|
|
1019
|
+
} catch {
|
|
1020
|
+
return { lastCheckedAt: 0 };
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
function writeUpdateCache(cache) {
|
|
1024
|
+
if (!(0, import_fs2.existsSync)(CONFIG_DIR)) (0, import_fs2.mkdirSync)(CONFIG_DIR, { recursive: true, mode: 448 });
|
|
1025
|
+
(0, import_fs2.writeFileSync)(CACHE_FILE, JSON.stringify(cache, null, 2));
|
|
1026
|
+
}
|
|
1027
|
+
function parseVersion(version) {
|
|
1028
|
+
const match = /^(\d+)\.(\d+)\.(\d+)/.exec(version.trim());
|
|
1029
|
+
if (!match) return null;
|
|
1030
|
+
return [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
1031
|
+
}
|
|
1032
|
+
function isNewerVersion(candidate, current) {
|
|
1033
|
+
const a = parseVersion(candidate);
|
|
1034
|
+
const b = parseVersion(current);
|
|
1035
|
+
if (!a || !b) return false;
|
|
1036
|
+
for (let i = 0; i < 3; i++) {
|
|
1037
|
+
if (a[i] !== b[i]) return a[i] > b[i];
|
|
1038
|
+
}
|
|
1039
|
+
return false;
|
|
1040
|
+
}
|
|
1041
|
+
async function fetchLatestVersion(packageName) {
|
|
1042
|
+
const controller = new AbortController();
|
|
1043
|
+
const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
1044
|
+
try {
|
|
1045
|
+
const res = await fetch(`https://registry.npmjs.org/-/package/${packageName}/dist-tags`, {
|
|
1046
|
+
signal: controller.signal
|
|
1047
|
+
});
|
|
1048
|
+
if (!res.ok) return null;
|
|
1049
|
+
const data = await res.json();
|
|
1050
|
+
return data.latest ?? null;
|
|
1051
|
+
} catch {
|
|
1052
|
+
return null;
|
|
1053
|
+
} finally {
|
|
1054
|
+
clearTimeout(timer);
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
async function refreshUpdateCache(packageName) {
|
|
1058
|
+
const latestVersion = await fetchLatestVersion(packageName);
|
|
1059
|
+
const previous = readUpdateCache();
|
|
1060
|
+
writeUpdateCache({
|
|
1061
|
+
lastCheckedAt: Date.now(),
|
|
1062
|
+
latestVersion: latestVersion ?? previous.latestVersion
|
|
1063
|
+
});
|
|
1064
|
+
}
|
|
1065
|
+
function spawnBackgroundRefresh(packageName) {
|
|
1066
|
+
try {
|
|
1067
|
+
const entry = process.argv[1];
|
|
1068
|
+
if (!entry) return;
|
|
1069
|
+
const child = (0, import_child_process.spawn)(process.execPath, [entry, "__update-check-worker", packageName], {
|
|
1070
|
+
detached: true,
|
|
1071
|
+
stdio: "ignore"
|
|
1072
|
+
});
|
|
1073
|
+
child.unref();
|
|
1074
|
+
} catch {
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
function notifyIfUpdateAvailable(currentVersion, packageName) {
|
|
1078
|
+
if (process.env.PDLAB_NO_UPDATE_CHECK) return;
|
|
1079
|
+
try {
|
|
1080
|
+
const cache = readUpdateCache();
|
|
1081
|
+
if (cache.latestVersion && isNewerVersion(cache.latestVersion, currentVersion)) {
|
|
1082
|
+
console.error(
|
|
1083
|
+
`
|
|
1084
|
+
\u203B ${packageName} \u6709\u65B0\u7248\u672C\u53EF\u7528\uFF1A${currentVersion} \u2192 ${cache.latestVersion}
|
|
1085
|
+
\u8FD0\u884C npm install -g ${packageName}@latest \u5347\u7EA7\uFF08\u53EF\u7528 PDLAB_NO_UPDATE_CHECK=1 \u5173\u95ED\u6B64\u63D0\u793A\uFF09
|
|
1086
|
+
`
|
|
1087
|
+
);
|
|
1088
|
+
}
|
|
1089
|
+
if (Date.now() - cache.lastCheckedAt > CHECK_INTERVAL_MS) {
|
|
1090
|
+
spawnBackgroundRefresh(packageName);
|
|
1091
|
+
}
|
|
1092
|
+
} catch {
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
|
|
798
1096
|
// src/index.ts
|
|
799
|
-
var pkg = JSON.parse((0,
|
|
1097
|
+
var pkg = JSON.parse((0, import_fs3.readFileSync)((0, import_path3.join)(__dirname, "../package.json"), "utf8"));
|
|
800
1098
|
var program = new import_commander2.Command();
|
|
801
1099
|
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);
|
|
802
1100
|
program.exitOverride();
|
|
@@ -809,7 +1107,13 @@ registerWhoamiCommand(program);
|
|
|
809
1107
|
registerConfigCommand(program);
|
|
810
1108
|
registerProjectCommand(program);
|
|
811
1109
|
registerPostCommand(program);
|
|
1110
|
+
registerTaxonomyCommand(program);
|
|
812
1111
|
registerSchemaCommand(program);
|
|
1112
|
+
program.command("__update-check-worker <packageName>", { hidden: true }).action(async (packageName) => {
|
|
1113
|
+
await refreshUpdateCache(packageName);
|
|
1114
|
+
process.exit(0);
|
|
1115
|
+
});
|
|
1116
|
+
notifyIfUpdateAvailable(pkg.version, "pdlab-cli");
|
|
813
1117
|
program.parseAsync(process.argv).catch((error) => {
|
|
814
1118
|
if (error instanceof import_commander2.CommanderError && error.exitCode === 0) {
|
|
815
1119
|
process.exit(0);
|