@yizhuan-cli/cli 0.1.4 → 0.1.6-beta.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yizhuan-cli/cli",
3
- "version": "0.1.4",
3
+ "version": "0.1.6-beta.0",
4
4
  "description": "易撰命令行工具,用于通过 API Key 查询易撰真实数据。",
5
5
  "private": false,
6
6
  "type": "module",
@@ -11,13 +11,6 @@
11
11
  "src",
12
12
  "README.md"
13
13
  ],
14
- "scripts": {
15
- "start": "node src/index.js",
16
- "pack:dry-run": "npm pack --dry-run",
17
- "smoke": "node src/index.js --help && node --test src/version.test.js",
18
- "test:params": "node --test src/params.test.js",
19
- "test:version": "node --test src/version.test.js"
20
- },
21
14
  "engines": {
22
15
  "node": ">=22"
23
16
  },
@@ -29,5 +22,12 @@
29
22
  "license": "UNLICENSED",
30
23
  "publishConfig": {
31
24
  "access": "public"
25
+ },
26
+ "scripts": {
27
+ "start": "node src/index.js",
28
+ "pack:dry-run": "npm pack --dry-run",
29
+ "smoke": "node src/index.js --help && node --test src/version.test.js",
30
+ "test:params": "node --test src/params.test.js",
31
+ "test:version": "node --test src/version.test.js"
32
32
  }
33
- }
33
+ }
package/src/index.js CHANGED
@@ -6,7 +6,7 @@ import { fileURLToPath } from 'node:url'
6
6
 
7
7
  const CLI_DIR = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..')
8
8
  const PACKAGE_PATH = path.join(CLI_DIR, 'package.json')
9
- const CONFIG_PATH = path.join(os.homedir(), '.config', 'yizhuan', 'config.json')
9
+ const CONFIG_PATH = process.env.YIZHUAN_CONFIG_PATH || path.join(os.homedir(), '.config', 'yizhuan', 'config.json')
10
10
  const ABILITIES = new Set([
11
11
  'works',
12
12
  'accounts',
@@ -50,6 +50,7 @@ Usage:
50
50
  yizhuan --version
51
51
  yizhuan execute --ability <ability> [--query <text>] [--params <json>] [--platform <name>]
52
52
  yizhuan query --json '<request JSON>' [--format json|table|markdown]
53
+ yizhuan query --json-file <path> [--format json|table|markdown]
53
54
  yizhuan config path
54
55
  yizhuan config show
55
56
 
@@ -64,6 +65,7 @@ Examples:
64
65
 
65
66
  Notes:
66
67
  - PowerShell 推荐优先使用 --platform / --mode 等独立参数,或单引号 JSON:--params '{"platform":"douyin"}'
68
+ - 所有 Shell 都可用 --json-file request.json,避免 JSON 引号被终端改写
67
69
  - bash/zsh 也可用:--params '{"platform":"douyin"}' 或 --platform douyin
68
70
  - 兼容 key=value:--params platform=douyin
69
71
 
@@ -78,6 +80,7 @@ Abilities:
78
80
 
79
81
  Config:
80
82
  ${CONFIG_PATH}
83
+ 可通过环境变量 YIZHUAN_CONFIG_PATH 指定独立配置文件
81
84
  `)
82
85
  }
83
86
 
@@ -128,7 +131,7 @@ function readFlagValue(argv, startIndex, key) {
128
131
  let raw = argv[index]
129
132
  if (raw == null) return { value: true, nextIndex: startIndex - 1 }
130
133
 
131
- if (key === 'params' && /[{\[]/.test(raw)) {
134
+ if ((key === 'params' || key === 'json') && /[{\[]/.test(raw)) {
132
135
  let joined = raw
133
136
  while (!isBalancedJsonLike(joined) && index + 1 < argv.length && !String(argv[index + 1]).startsWith('--')) {
134
137
  index += 1
@@ -140,7 +143,7 @@ function readFlagValue(argv, startIndex, key) {
140
143
  return { value: raw, nextIndex: index }
141
144
  }
142
145
 
143
- function parseArgs(argv) {
146
+ export function parseArgs(argv) {
144
147
  const args = { _: [] }
145
148
  for (let index = 0; index < argv.length; index += 1) {
146
149
  const value = argv[index]
@@ -152,13 +155,13 @@ function parseArgs(argv) {
152
155
  const body = value.slice(2)
153
156
  const eqIndex = body.indexOf('=')
154
157
  if (eqIndex > 0) {
155
- const key = body.slice(0, eqIndex)
158
+ const key = body.slice(0, eqIndex).replace(/-([a-z])/g, (_, letter) => letter.toUpperCase())
156
159
  const raw = body.slice(eqIndex + 1)
157
160
  args[key] = raw
158
161
  continue
159
162
  }
160
163
 
161
- const key = body
164
+ const key = body.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase())
162
165
  const next = argv[index + 1]
163
166
  if (!next || next.startsWith('--')) {
164
167
  args[key] = true
@@ -333,7 +336,12 @@ function renderQuery(payload, format) {
333
336
  }
334
337
 
335
338
  async function query(args) {
336
- const request = parseParams(args.json || args.params)
339
+ const jsonText = args.jsonFile
340
+ ? fs.readFileSync(path.resolve(String(args.jsonFile)), 'utf8')
341
+ : args.json === '-'
342
+ ? fs.readFileSync(0, 'utf8')
343
+ : args.json || args.params
344
+ const request = parseParams(jsonText)
337
345
  if (!request) throw new Error('query 必须提供 --json 请求对象')
338
346
  const config = readConfig()
339
347
  const response = await fetch(`${config.apiBaseUrl}/api/agent.query`, {
@@ -386,7 +394,7 @@ const isDirectRun = (() => {
386
394
  const entry = process.argv[1]
387
395
  if (!entry) return false
388
396
  try {
389
- return path.resolve(entry) === fileURLToPath(import.meta.url)
397
+ return fs.realpathSync(path.resolve(entry)) === fs.realpathSync(fileURLToPath(import.meta.url))
390
398
  } catch {
391
399
  return false
392
400
  }
@@ -1,6 +1,6 @@
1
1
  import test from 'node:test'
2
2
  import assert from 'node:assert/strict'
3
- import { buildExecuteParams, parseParams } from './index.js'
3
+ import { buildExecuteParams, parseArgs, parseParams } from './index.js'
4
4
 
5
5
  test('parseParams accepts standard JSON', () => {
6
6
  assert.deepEqual(parseParams('{"platform":"douyin"}'), { platform: 'douyin' })
@@ -45,3 +45,24 @@ test('buildExecuteParams prefers explicit params keys over flags', () => {
45
45
  { platform: 'weibo' }
46
46
  )
47
47
  })
48
+
49
+ test('parseArgs preserves query JSON supplied after --json', () => {
50
+ assert.deepEqual(
51
+ parseArgs(['query', '--json', '{"intent":"author_search","platform":"douyin"}']),
52
+ { _: ['query'], json: '{"intent":"author_search","platform":"douyin"}' }
53
+ )
54
+ })
55
+
56
+ test('parseArgs maps --json-file to the property used by query', () => {
57
+ assert.deepEqual(
58
+ parseArgs(['query', '--json-file', 'request.json']),
59
+ { _: ['query'], jsonFile: 'request.json' }
60
+ )
61
+ })
62
+
63
+ test('parseArgs preserves query JSON split into multiple argv fragments', () => {
64
+ assert.deepEqual(
65
+ parseArgs(['query', '--json', '{"intent":', '"author_search",', '"platform":"douyin"}']),
66
+ { _: ['query'], json: '{"intent":"author_search","platform":"douyin"}' }
67
+ )
68
+ })