pdlab-cli 0.1.0 → 0.1.1

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.
Files changed (3) hide show
  1. package/README.md +5 -0
  2. package/dist/index.js +51 -27
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -72,6 +72,11 @@ pdlab post list --project-id <项目 id>
72
72
  ```
73
73
 
74
74
  API 地址的解析顺序:`--api-url` 参数 > `PDLAB_API_URL` 环境变量 > 配置文件。
75
+ 所有命令都支持 `--api-url`,包括 `project` / `post` 这些资源命令。
76
+
77
+ 读命令(`project list` / `get`、`post list` / `get`)会在**已登录时带上凭证**,
78
+ 可见范围因此按你的身份走:有审核权限才能 `post list --status pending`,
79
+ 作者也才能 `post get` 到自己那篇还没过审的稿子。没登录则匿名读公开内容,照常可用。
75
80
  在 CI 里可以只给环境变量,不落配置文件。
76
81
 
77
82
  ## 凭证与安全
package/dist/index.js CHANGED
@@ -35,7 +35,7 @@ var import_open = __toESM(require("open"));
35
35
  var import_fs = require("fs");
36
36
  var import_os = require("os");
37
37
  var import_path = require("path");
38
- var CONFIG_DIR = (0, import_path.join)((0, import_os.homedir)(), ".pdlab");
38
+ var CONFIG_DIR = process.env.PDLAB_CONFIG_DIR ?? (0, import_path.join)((0, import_os.homedir)(), ".pdlab");
39
39
  var CONFIG_FILE = (0, import_path.join)(CONFIG_DIR, "config.json");
40
40
  function readConfig() {
41
41
  if (!(0, import_fs.existsSync)(CONFIG_FILE)) return {};
@@ -62,6 +62,9 @@ function resolveApiUrl(flagValue) {
62
62
  }
63
63
  return apiUrl.replace(/\/+$/, "");
64
64
  }
65
+ function optionalToken() {
66
+ return readConfig().token;
67
+ }
65
68
  function requireToken() {
66
69
  const token = readConfig().token;
67
70
  if (!token) {
@@ -330,6 +333,11 @@ function handleCommandError(error, examples) {
330
333
  process.exit(1);
331
334
  }
332
335
 
336
+ // src/commands/options.ts
337
+ function withApiUrl(cmd) {
338
+ return cmd.option("--api-url <url>", "API \u670D\u52A1\u5668\u5730\u5740\uFF0C\u8986\u76D6 PDLAB_API_URL \u4E0E\u914D\u7F6E\u6587\u4EF6");
339
+ }
340
+
333
341
  // src/commands/project.ts
334
342
  var CREATE_EXAMPLES = [
335
343
  {
@@ -354,24 +362,30 @@ function toBody(opts) {
354
362
  return body;
355
363
  }
356
364
  function withProjectFlags(cmd) {
357
- return cmd.option("--title <title>", "\u9879\u76EE\u6807\u9898").option("--description <description>", "\u9879\u76EE\u63CF\u8FF0").option("--cover-image <url>", "\u5C01\u9762\u56FE http/https \u94FE\u63A5").option("--commercial-type <type>", "\u5546\u4E1A\u5C5E\u6027").option("--status <status>", "planning | active | review | completed").option("--progress <percent>", "\u8FDB\u5EA6 0-100").option("--taxonomy-ids <ids>", "\u9017\u53F7\u5206\u9694\u7684\u5206\u7C7B\u6807\u7B7E id \u5217\u8868");
365
+ return withApiUrl(cmd).option("--title <title>", "\u9879\u76EE\u6807\u9898").option("--description <description>", "\u9879\u76EE\u63CF\u8FF0").option("--cover-image <url>", "\u5C01\u9762\u56FE http/https \u94FE\u63A5").option("--commercial-type <type>", "\u5546\u4E1A\u5C5E\u6027").option("--status <status>", "planning | active | review | completed").option("--progress <percent>", "\u8FDB\u5EA6 0-100").option("--taxonomy-ids <ids>", "\u9017\u53F7\u5206\u9694\u7684\u5206\u7C7B\u6807\u7B7E id \u5217\u8868");
358
366
  }
359
367
  function registerProjectCommand(program2) {
360
368
  const project = program2.command("project").description("\u9879\u76EE\u7684\u589E\u5220\u6539\u67E5");
361
- project.command("list").description("\u5217\u51FA\u9879\u76EE").option("--status <status>", "\u6309\u72B6\u6001\u7B5B\u9009\uFF1Aplanning | active | review | completed").action(async (opts) => {
362
- const data = await apiRequest("/api/projects", { query: { status: opts.status } });
363
- console.log(JSON.stringify(data, null, 2));
364
- });
365
- project.command("get <id>").description("\u67E5\u770B\u9879\u76EE\u8BE6\u60C5").action(async (id) => {
366
- const data = await apiRequest(`/api/projects/${id}`);
369
+ withApiUrl(project.command("list").description("\u5217\u51FA\u9879\u76EE")).option("--status <status>", "\u6309\u72B6\u6001\u7B5B\u9009\uFF1Aplanning | active | review | completed").action(async (opts) => {
370
+ const data = await apiRequest("/api/projects", {
371
+ query: { status: opts.status },
372
+ token: optionalToken(),
373
+ apiUrl: opts.apiUrl
374
+ });
367
375
  console.log(JSON.stringify(data, null, 2));
368
376
  });
377
+ withApiUrl(project.command("get <id>").description("\u67E5\u770B\u9879\u76EE\u8BE6\u60C5")).action(
378
+ async (id, opts) => {
379
+ const data = await apiRequest(`/api/projects/${id}`, { token: optionalToken(), apiUrl: opts.apiUrl });
380
+ console.log(JSON.stringify(data, null, 2));
381
+ }
382
+ );
369
383
  withProjectFlags(project.command("create").description("\u521B\u5EFA\u9879\u76EE\uFF08\u9700\u8981\u9879\u76EE\u521B\u5EFA\u6743\u9650\uFF09")).action(
370
384
  async (opts) => {
371
385
  const token = requireToken();
372
386
  try {
373
387
  const body = projectCreateSchema.parse(toBody(opts));
374
- const data = await apiRequest("/api/projects", { method: "POST", body, token });
388
+ const data = await apiRequest("/api/projects", { method: "POST", body, token, apiUrl: opts.apiUrl });
375
389
  console.log(JSON.stringify(data, null, 2));
376
390
  } catch (error) {
377
391
  handleCommandError(error, CREATE_EXAMPLES);
@@ -383,16 +397,18 @@ function registerProjectCommand(program2) {
383
397
  const token = requireToken();
384
398
  try {
385
399
  const body = projectUpdateSchema.parse(toBody(opts));
386
- const data = await apiRequest(`/api/projects/${id}`, { method: "PATCH", body, token });
400
+ const data = await apiRequest(`/api/projects/${id}`, { method: "PATCH", body, token, apiUrl: opts.apiUrl });
387
401
  console.log(JSON.stringify(data, null, 2));
388
402
  } catch (error) {
389
403
  handleCommandError(error, UPDATE_EXAMPLES);
390
404
  }
391
405
  }
392
406
  );
393
- project.command("delete <id>").description("\u5220\u9664\u9879\u76EE\uFF08\u9700\u8981\u662F\u9879\u76EE\u53D1\u8D77\u4EBA\uFF0C\u4E14\u9879\u76EE\u4E0B\u6CA1\u6709\u5185\u5BB9/\u79EF\u5206\u8BB0\u5F55\uFF09").action(async (id) => {
407
+ withApiUrl(
408
+ project.command("delete <id>").description("\u5220\u9664\u9879\u76EE\uFF08\u9700\u8981\u662F\u9879\u76EE\u53D1\u8D77\u4EBA\uFF0C\u4E14\u9879\u76EE\u4E0B\u6CA1\u6709\u5185\u5BB9/\u79EF\u5206\u8BB0\u5F55\uFF09")
409
+ ).action(async (id, opts) => {
394
410
  const token = requireToken();
395
- const data = await apiRequest(`/api/projects/${id}`, { method: "DELETE", token });
411
+ const data = await apiRequest(`/api/projects/${id}`, { method: "DELETE", token, apiUrl: opts.apiUrl });
396
412
  console.log(JSON.stringify(data, null, 2));
397
413
  });
398
414
  }
@@ -411,15 +427,21 @@ function toMediaLinks(value) {
411
427
  }
412
428
  function registerPostCommand(program2) {
413
429
  const post = program2.command("post").description("\u5185\u5BB9\uFF08\u5E16\u5B50\uFF09\u7684\u589E\u5220\u6539\u67E5");
414
- post.command("list").description("\u5217\u51FA\u5185\u5BB9").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").action(async (opts) => {
415
- const data = await apiRequest("/api/posts", { query: { projectId: opts.projectId, status: opts.status } });
416
- console.log(JSON.stringify(data, null, 2));
417
- });
418
- post.command("get <id>").description("\u67E5\u770B\u5185\u5BB9\u8BE6\u60C5").action(async (id) => {
419
- const data = await apiRequest(`/api/posts/${id}`);
430
+ withApiUrl(post.command("list").description("\u5217\u51FA\u5185\u5BB9")).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").action(async (opts) => {
431
+ const data = await apiRequest("/api/posts", {
432
+ query: { projectId: opts.projectId, status: opts.status },
433
+ token: optionalToken(),
434
+ apiUrl: opts.apiUrl
435
+ });
420
436
  console.log(JSON.stringify(data, null, 2));
421
437
  });
422
- post.command("create").description("\u53D1\u5E03\u5185\u5BB9\uFF08\u9700\u8981\u5185\u5BB9\u521B\u5EFA\u6743\u9650\uFF0C\u4E14\u662F\u9879\u76EE\u53D1\u8D77\u4EBA\u6216\u5DF2\u62A5\u540D\u5171\u5EFA\uFF09").option("--title <title>", "\u5185\u5BB9\u6807\u9898").option("--body <body>", "\u5185\u5BB9\u6B63\u6587").option("--project-id <id>", "\u6240\u5C5E\u9879\u76EE id").option("--media-links <urls>", "\u9017\u53F7\u5206\u9694\u7684\u5A92\u4F53\u94FE\u63A5").action(async (opts) => {
438
+ withApiUrl(post.command("get <id>").description("\u67E5\u770B\u5185\u5BB9\u8BE6\u60C5")).action(
439
+ async (id, opts) => {
440
+ const data = await apiRequest(`/api/posts/${id}`, { token: optionalToken(), apiUrl: opts.apiUrl });
441
+ console.log(JSON.stringify(data, null, 2));
442
+ }
443
+ );
444
+ withApiUrl(post.command("create").description("\u53D1\u5E03\u5185\u5BB9\uFF08\u9700\u8981\u5185\u5BB9\u521B\u5EFA\u6743\u9650\uFF0C\u4E14\u662F\u9879\u76EE\u53D1\u8D77\u4EBA\u6216\u5DF2\u62A5\u540D\u5171\u5EFA\uFF09")).option("--title <title>", "\u5185\u5BB9\u6807\u9898").option("--body <body>", "\u5185\u5BB9\u6B63\u6587").option("--project-id <id>", "\u6240\u5C5E\u9879\u76EE id").option("--media-links <urls>", "\u9017\u53F7\u5206\u9694\u7684\u5A92\u4F53\u94FE\u63A5").action(async (opts) => {
423
445
  const token = requireToken();
424
446
  try {
425
447
  const body = postCreateSchema.parse({
@@ -428,13 +450,13 @@ function registerPostCommand(program2) {
428
450
  projectId: opts.projectId,
429
451
  mediaLinks: toMediaLinks(opts.mediaLinks)
430
452
  });
431
- const data = await apiRequest("/api/posts", { method: "POST", body, token });
453
+ const data = await apiRequest("/api/posts", { method: "POST", body, token, apiUrl: opts.apiUrl });
432
454
  console.log(JSON.stringify(data, null, 2));
433
455
  } catch (error) {
434
456
  handleCommandError(error, CREATE_EXAMPLES2);
435
457
  }
436
458
  });
437
- 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").option("--body <body>", "\u5185\u5BB9\u6B63\u6587").option("--media-links <urls>", "\u9017\u53F7\u5206\u9694\u7684\u5A92\u4F53\u94FE\u63A5").action(async (id, opts) => {
459
+ 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").option("--body <body>", "\u5185\u5BB9\u6B63\u6587").option("--media-links <urls>", "\u9017\u53F7\u5206\u9694\u7684\u5A92\u4F53\u94FE\u63A5").action(async (id, opts) => {
438
460
  const token = requireToken();
439
461
  try {
440
462
  const body = postUpdateSchema.parse({
@@ -442,17 +464,19 @@ function registerPostCommand(program2) {
442
464
  body: opts.body,
443
465
  mediaLinks: toMediaLinks(opts.mediaLinks)
444
466
  });
445
- const data = await apiRequest(`/api/posts/${id}`, { method: "PATCH", body, token });
467
+ const data = await apiRequest(`/api/posts/${id}`, { method: "PATCH", body, token, apiUrl: opts.apiUrl });
446
468
  console.log(JSON.stringify(data, null, 2));
447
469
  } catch (error) {
448
470
  handleCommandError(error, UPDATE_EXAMPLES2);
449
471
  }
450
472
  });
451
- 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(async (id) => {
452
- const token = requireToken();
453
- const data = await apiRequest(`/api/posts/${id}`, { method: "DELETE", token });
454
- console.log(JSON.stringify(data, null, 2));
455
- });
473
+ 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(
474
+ async (id, opts) => {
475
+ const token = requireToken();
476
+ const data = await apiRequest(`/api/posts/${id}`, { method: "DELETE", token, apiUrl: opts.apiUrl });
477
+ console.log(JSON.stringify(data, null, 2));
478
+ }
479
+ );
456
480
  }
457
481
 
458
482
  // src/index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pdlab-cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "private": false,
5
5
  "description": "1836 开源共建平台(problem-driven-lab)的命令行工具:项目、内容的增删改查,浏览器授权登录",
6
6
  "keywords": [