type-flash 1.1.3 → 1.1.4

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 (2) hide show
  1. package/bin/type-flash.js +130 -146
  2. package/package.json +1 -1
package/bin/type-flash.js CHANGED
@@ -1,26 +1,20 @@
1
1
  #!/usr/bin/env node
2
+
2
3
  /**
3
- * type-flash CLI - 命令行工具
4
+ * type-flash - CLI 命令行工具
4
5
  *
5
6
  * 用法:
6
- * type-flash <input.json> [options]
7
7
  * type-flash -i input.json -o output.ts
8
- * cat data.json | type-flash
9
- *
10
- * 示例:
11
- * type-flash user.json -n User
12
- * type-flash api.json --style type --no-export
13
- * curl https://api.example.com/users | type-flash -n UserList
8
+ * cat data.json | type-flash -n User
14
9
  */
15
10
 
16
- 'use strict';
17
-
18
11
  const fs = require('fs');
19
12
  const path = require('path');
20
13
 
21
14
  // 解析命令行参数
22
- function parseArgs(argv) {
23
- const args = {
15
+ function parseArgs() {
16
+ const args = process.argv.slice(2);
17
+ const options = {
24
18
  input: null,
25
19
  output: null,
26
20
  rootName: 'Root',
@@ -34,182 +28,139 @@ function parseArgs(argv) {
34
28
  indentSize: 2,
35
29
  typePrefix: '',
36
30
  typeSuffix: '',
31
+ typeNameMap: {},
37
32
  help: false,
38
33
  version: false,
39
34
  };
40
35
 
41
- let i = 2; // 跳过 node 和脚本路径
42
- while (i < argv.length) {
43
- const arg = argv[i];
44
-
36
+ for (let i = 0; i < args.length; i++) {
37
+ const arg = args[i];
38
+
45
39
  switch (arg) {
46
- case '-h':
47
- case '--help':
48
- args.help = true;
49
- break;
50
-
51
- case '-v':
52
- case '--version':
53
- args.version = true;
54
- break;
55
-
56
40
  case '-i':
57
41
  case '--input':
58
- args.input = argv[++i];
42
+ options.input = args[++i];
59
43
  break;
60
-
61
44
  case '-o':
62
45
  case '--output':
63
- args.output = argv[++i];
46
+ options.output = args[++i];
64
47
  break;
65
-
66
48
  case '-n':
67
49
  case '--name':
68
- case '--root-name':
69
- args.rootName = argv[++i];
50
+ options.rootName = args[++i];
70
51
  break;
71
-
72
52
  case '-s':
73
53
  case '--style':
74
- args.outputStyle = argv[++i];
54
+ options.outputStyle = args[++i];
75
55
  break;
76
-
77
56
  case '--naming-style':
78
- args.namingStyle = argv[++i];
57
+ options.namingStyle = args[++i];
79
58
  break;
80
-
81
59
  case '--sort':
82
- args.sortProperties = argv[++i];
60
+ options.sortProperties = args[++i];
83
61
  break;
84
-
85
62
  case '--no-export':
86
- args.addExport = false;
63
+ options.addExport = false;
87
64
  break;
88
-
89
65
  case '--strict-null':
90
- args.strictNullChecks = true;
66
+ options.strictNullChecks = true;
91
67
  break;
92
-
93
68
  case '--no-optional':
94
- args.markOptional = false;
69
+ options.markOptional = false;
95
70
  break;
96
-
97
71
  case '--no-generics':
98
- args.extractGenerics = false;
72
+ options.extractGenerics = false;
99
73
  break;
100
-
101
74
  case '--indent':
102
- args.indentSize = parseInt(argv[++i], 10);
75
+ options.indentSize = parseInt(args[++i], 10);
103
76
  break;
104
-
105
77
  case '--prefix':
106
- args.typePrefix = argv[++i];
78
+ options.typePrefix = args[++i];
107
79
  break;
108
-
109
80
  case '--suffix':
110
- args.typeSuffix = argv[++i];
81
+ options.typeSuffix = args[++i];
82
+ break;
83
+ case '-h':
84
+ case '--help':
85
+ options.help = true;
86
+ break;
87
+ case '-v':
88
+ case '--version':
89
+ options.version = true;
111
90
  break;
112
-
113
91
  default:
114
- // 第一个非选项参数作为输入文件
115
- if (!args.input && !arg.startsWith('-')) {
116
- args.input = arg;
117
- }
92
+ // 未知参数,忽略
118
93
  break;
119
94
  }
120
-
121
- i++;
122
95
  }
123
96
 
124
- return args;
97
+ return options;
125
98
  }
126
99
 
127
- // 显示帮助信息
100
+ // 显示帮助
128
101
  function showHelp() {
129
102
  console.log(`
130
103
  type-flash - JSON 智能生成 TypeScript 类型定义
131
104
 
132
105
  用法:
133
- type-flash <input.json> [options]
134
- type-flash -i input.json -o output.ts
135
- cat data.json | type-flash
106
+ type-flash -i <file> [选项]
107
+ cat data.json | type-flash [选项]
136
108
 
137
109
  选项:
138
- -i, --input <file> 输入 JSON 文件路径
139
- -o, --output <file> 输出 TypeScript 文件路径(默认输出到 stdout)
140
- -n, --name <name> 根类型名称(默认: Root
141
- -s, --style <style> 输出风格: interface | type(默认: interface
142
- --naming-style <s> 命名风格: PascalCase | camelCase(默认: PascalCase
143
- --sort <order> 属性排序: alpha | definition(默认: alpha
144
- --no-export 不添加 export 关键字
145
- --strict-null 严格空值模式(保留 null 类型)
146
- --no-optional 不标记可选属性
147
- --no-generics 不提取泛型类型
148
- --indent <n> 缩进空格数(默认: 2
149
- --prefix <prefix> 类型名前缀
150
- --suffix <suffix> 类型名后缀
151
- -h, --help 显示帮助信息
152
- -v, --version 显示版本号
110
+ -i, --input <file> 输入 JSON 文件路径
111
+ -o, --output <file> 输出 TS 文件路径
112
+ -n, --name <name> 根类型名称 (默认: Root)
113
+ -s, --style <style> 输出风格: interface | type (默认: interface)
114
+ --naming-style <s> 命名风格: PascalCase | camelCase (默认: PascalCase)
115
+ --sort <order> 属性排序: alpha | definition (默认: alpha)
116
+ --no-export 不添加 export 语句
117
+ --strict-null 严格空值模式
118
+ --no-optional 不标记可选属性
119
+ --no-generics 不提取泛型
120
+ --indent <n> 缩进空格数 (默认: 2)
121
+ --prefix <prefix> 类型名前缀
122
+ --suffix <suffix> 类型名后缀
123
+ -v, --version 显示版本号
124
+ -h, --help 显示帮助
153
125
 
154
126
  示例:
155
- # 从文件生成
156
- type-flash user.json -n User -o user.ts
157
-
158
- # 使用 type 风格输出
159
- type-flash data.json --style type
160
-
161
- # 从标准输入读取
162
- curl https://api.example.com/data | type-flash -n ApiResponse
163
-
164
- # 带前缀
165
- type-flash api.json --prefix Api -o api-types.ts
127
+ type-flash -i data.json -o types.ts
128
+ type-flash -i data.json -n User
129
+ cat data.json | type-flash -s type
166
130
  `);
167
131
  }
168
132
 
169
- // 显示版本号
133
+ // 显示版本
170
134
  function showVersion() {
171
135
  try {
172
136
  const pkgPath = path.join(__dirname, '..', 'package.json');
173
137
  const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
174
- console.log(`type-flash v${pkg.version}`);
138
+ console.log(pkg.version);
175
139
  } catch (e) {
176
- console.log('type-flash (unknown version)');
140
+ console.log('unknown');
177
141
  }
178
142
  }
179
143
 
180
- // 读取输入
181
- async function readInput(inputPath) {
182
- if (inputPath) {
183
- // 从文件读取
184
- const fullPath = path.resolve(inputPath);
185
- if (!fs.existsSync(fullPath)) {
186
- console.error(`错误: 文件不存在: ${fullPath}`);
187
- process.exit(1);
188
- }
189
- return fs.readFileSync(fullPath, 'utf-8');
190
- }
191
-
192
- // 从标准输入读取
144
+ // 读取标准输入
145
+ function readStdin() {
193
146
  return new Promise((resolve, reject) => {
194
147
  let data = '';
195
148
  process.stdin.setEncoding('utf-8');
196
-
149
+
197
150
  process.stdin.on('data', chunk => {
198
151
  data += chunk;
199
152
  });
200
-
153
+
201
154
  process.stdin.on('end', () => {
202
155
  resolve(data);
203
156
  });
204
-
157
+
205
158
  process.stdin.on('error', reject);
206
-
207
- // 检查是否有输入
159
+
160
+ // 如果没有输入,超时返回空
208
161
  setTimeout(() => {
209
162
  if (!data) {
210
- console.error('错误: 未提供输入数据。请指定输入文件或通过管道传入 JSON。');
211
- console.error('使用 --help 查看帮助信息。');
212
- process.exit(1);
163
+ resolve('');
213
164
  }
214
165
  }, 100);
215
166
  });
@@ -217,65 +168,98 @@ async function readInput(inputPath) {
217
168
 
218
169
  // 主函数
219
170
  async function main() {
220
- const args = parseArgs(process.argv);
171
+ const options = parseArgs();
221
172
 
222
- if (args.help) {
173
+ // 显示帮助
174
+ if (options.help) {
223
175
  showHelp();
224
176
  return;
225
177
  }
226
178
 
227
- if (args.version) {
179
+ // 显示版本
180
+ if (options.version) {
228
181
  showVersion();
229
182
  return;
230
183
  }
231
184
 
232
185
  try {
233
- // 读取输入
234
- const jsonStr = await readInput(args.input);
186
+ // 1. 获取 JSON 数据
187
+ let jsonString;
188
+
189
+ if (options.input) {
190
+ // 从文件读取
191
+ const inputPath = path.resolve(options.input);
192
+ if (!fs.existsSync(inputPath)) {
193
+ console.error(`错误: 文件不存在 - ${options.input}`);
194
+ process.exit(1);
195
+ }
196
+ jsonString = fs.readFileSync(inputPath, 'utf-8');
197
+ } else {
198
+ // 从标准输入读取
199
+ jsonString = await readStdin();
200
+ if (!jsonString.trim()) {
201
+ console.error('错误: 未提供输入数据。使用 -i 指定文件或通过管道输入');
202
+ console.error('使用 type-flash --help 查看帮助');
203
+ process.exit(1);
204
+ }
205
+ }
235
206
 
236
- // 解析 JSON
207
+ // 2. 解析 JSON
237
208
  let jsonData;
238
209
  try {
239
- jsonData = JSON.parse(jsonStr);
210
+ jsonData = JSON.parse(jsonString);
240
211
  } catch (e) {
241
212
  console.error(`错误: JSON 解析失败 - ${e.message}`);
242
213
  process.exit(1);
243
214
  }
244
215
 
245
- // 动态导入生成函数
246
- const { generate } = require('../dist/index.js');
216
+ // 3. 生成类型
217
+ // 动态导入生成的模块
218
+ const distPath = path.join(__dirname, '..', 'dist', 'index.js');
219
+ let generate;
220
+
221
+ try {
222
+ const mod = require(distPath);
223
+ generate = mod.generate || mod.default?.generate;
224
+ } catch (e) {
225
+ console.error(`错误: 加载模块失败 - ${e.message}`);
226
+ console.error('请先运行 npm run build 构建项目');
227
+ process.exit(1);
228
+ }
229
+
230
+ if (!generate) {
231
+ console.error('错误: 未找到 generate 函数');
232
+ process.exit(1);
233
+ }
247
234
 
248
- // 生成类型
235
+ // 生成类型(generate 直接返回字符串)
249
236
  const result = generate(jsonData, {
250
- rootName: args.rootName,
251
- outputStyle: args.outputStyle,
252
- namingStyle: args.namingStyle,
253
- sortProperties: args.sortProperties,
254
- addExport: args.addExport,
255
- strictNullChecks: args.strictNullChecks,
256
- markOptional: args.markOptional,
257
- extractGenerics: args.extractGenerics,
258
- indentSize: args.indentSize,
259
- typePrefix: args.typePrefix,
260
- typeSuffix: args.typeSuffix,
237
+ rootName: options.rootName,
238
+ outputStyle: options.outputStyle,
239
+ namingStyle: options.namingStyle,
240
+ sortProperties: options.sortProperties,
241
+ addExport: options.addExport,
242
+ strictNullChecks: options.strictNullChecks,
243
+ markOptional: options.markOptional,
244
+ extractGenerics: options.extractGenerics,
245
+ indentSize: options.indentSize,
246
+ typePrefix: options.typePrefix,
247
+ typeSuffix: options.typeSuffix,
261
248
  });
262
249
 
263
- // 输出结果
264
- if (args.output) {
265
- const outputPath = path.resolve(args.output);
266
- fs.writeFileSync(outputPath, result.code, 'utf-8');
267
- console.log(`✓ 已生成: ${outputPath}`);
268
- console.log(` 共生成 ${result.types.length} 个类型定义`);
250
+ // 4. 输出结果
251
+ if (options.output) {
252
+ const outputPath = path.resolve(options.output);
253
+ fs.writeFileSync(outputPath, result, 'utf-8');
254
+ console.log(`✅ 已生成: ${options.output}`);
269
255
  } else {
270
- console.log(result.code);
256
+ console.log(result);
271
257
  }
258
+
272
259
  } catch (e) {
273
260
  console.error(`错误: ${e.message}`);
274
- if (process.env.DEBUG) {
275
- console.error(e.stack);
276
- }
277
261
  process.exit(1);
278
262
  }
279
263
  }
280
264
 
281
- main();
265
+ main();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "type-flash",
3
- "version": "1.1.3",
3
+ "version": "1.1.4",
4
4
  "description": "JSON 智能生成 TypeScript 类型定义 - 一键从 JSON 数据生成 Interface / Type 定义",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",