@helixlife-ai/xiantao 0.1.18 → 0.1.19

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.
@@ -20,6 +20,12 @@ export default class HistoryDownload extends XtzCommand {
20
20
  device: Flags.string({
21
21
  description: 'Preferred device/format, e.g. pdf, xlsx, zip',
22
22
  }),
23
+ item: Flags.integer({
24
+ description: 'Select a download item by its 1-based index from the listed results',
25
+ }),
26
+ label: Flags.string({
27
+ description: 'Select a download item by its label',
28
+ }),
23
29
  output: Flags.string({
24
30
  char: 'o',
25
31
  description: 'Destination path; defaults to ~/Downloads/<file name>',
@@ -33,13 +39,21 @@ export default class HistoryDownload extends XtzCommand {
33
39
  const agent = await this.getProfile(flags.profile);
34
40
  const auth = await getAuthContext(agent, flags.token);
35
41
  const record = await findXiantaoHistoryRecordByFuid(auth, args.fuid);
42
+ if (flags.item !== undefined && flags.label) {
43
+ throw new XtzError('`--item` 与 `--label` 不能同时使用。');
44
+ }
36
45
  if (!record?.module_id?.trim()) {
37
46
  throw new XtzError(`未找到 fuid 为 ${args.fuid} 的历史记录。`);
38
47
  }
39
48
  const result = await fetchXiantaoHistoryDownloadButtons(auth, { fuid: args.fuid });
40
- const item = this.pickDownloadItem(result.downloads, flags.device, flags.output);
49
+ const item = this.pickDownloadItem(result.downloads, {
50
+ device: flags.device,
51
+ item: flags.item,
52
+ label: flags.label,
53
+ outputPath: flags.output,
54
+ });
41
55
  if (!item) {
42
- throw new XtzError('当前历史记录返回多个可下载结果,请传入 `--device`,或将 `--output` 改为带目标扩展名的文件名。');
56
+ throw new XtzError(this.buildMultipleDownloadsMessage(result.downloads));
43
57
  }
44
58
  const resolved = await resolveXiantaoDownload(auth, {
45
59
  item,
@@ -62,8 +76,14 @@ export default class HistoryDownload extends XtzCommand {
62
76
  profile: agent,
63
77
  });
64
78
  }
65
- pickDownloadItem(downloads, expectedDevice, outputPath) {
66
- const normalizedExpectedDevice = this.normalizeDevice(expectedDevice ?? this.inferDeviceFromOutputPath(outputPath));
79
+ pickDownloadItem(downloads, input) {
80
+ if (input.item !== undefined) {
81
+ return this.pickDownloadItemByIndex(downloads, input.item);
82
+ }
83
+ if (input.label) {
84
+ return this.pickDownloadItemByLabel(downloads, input.label);
85
+ }
86
+ const normalizedExpectedDevice = this.normalizeDevice(input.device ?? this.inferDeviceFromOutputPath(input.outputPath));
67
87
  if (normalizedExpectedDevice) {
68
88
  const matched = downloads.filter((item) => this.normalizeDevice(item.device) === normalizedExpectedDevice);
69
89
  if (matched.length === 1) {
@@ -79,6 +99,26 @@ export default class HistoryDownload extends XtzCommand {
79
99
  }
80
100
  return undefined;
81
101
  }
102
+ pickDownloadItemByIndex(downloads, itemIndex) {
103
+ if (!Number.isInteger(itemIndex) || itemIndex < 1 || itemIndex > downloads.length) {
104
+ throw new XtzError(`下载项序号 ${itemIndex} 无效,可选范围为 1-${downloads.length}。\n${this.buildMultipleDownloadsMessage(downloads)}`);
105
+ }
106
+ return downloads[itemIndex - 1];
107
+ }
108
+ pickDownloadItemByLabel(downloads, expectedLabel) {
109
+ const normalizedExpectedLabel = expectedLabel.trim().toLowerCase();
110
+ if (!normalizedExpectedLabel) {
111
+ return undefined;
112
+ }
113
+ const matched = downloads.filter((item) => item.label.trim().toLowerCase() === normalizedExpectedLabel);
114
+ if (matched.length === 1) {
115
+ return matched[0];
116
+ }
117
+ if (matched.length > 1) {
118
+ throw new XtzError(`下载项名称 ${expectedLabel} 匹配到多个结果,请改用 \`--item\` 精确选择。\n${this.buildMultipleDownloadsMessage(downloads)}`);
119
+ }
120
+ return undefined;
121
+ }
82
122
  inferDeviceFromOutputPath(outputPath) {
83
123
  const extension = outputPath?.trim().split('.').pop()?.toLowerCase();
84
124
  return extension ? this.normalizeDevice(extension) : undefined;
@@ -96,4 +136,14 @@ export default class HistoryDownload extends XtzCommand {
96
136
  }
97
137
  return normalized;
98
138
  }
139
+ buildMultipleDownloadsMessage(downloads) {
140
+ const lines = [
141
+ '当前历史记录返回多个可下载结果,请传入 `--item`、`--label`、`--device`,或将 `--output` 改为带目标扩展名的文件名。',
142
+ '可选下载项:',
143
+ ];
144
+ downloads.forEach((item, index) => {
145
+ lines.push(`${index + 1}. ${item.label} (device=${item.device}, endpoint=${item.endpoint})`);
146
+ });
147
+ return lines.join('\n');
148
+ }
99
149
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@helixlife-ai/xiantao",
3
- "version": "0.1.18",
3
+ "version": "0.1.19",
4
4
  "description": "CLI for Xiantao bioinformatics tools",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",