@jayfong/x-server 2.12.7 → 2.12.15

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 (84) hide show
  1. package/lib/_cjs/cli/api_generator.js +20 -54
  2. package/lib/_cjs/cli/build_util.js +16 -45
  3. package/lib/_cjs/cli/cli.js +6 -27
  4. package/lib/_cjs/cli/deploy_util.js +0 -12
  5. package/lib/_cjs/cli/env_util.js +16 -49
  6. package/lib/_cjs/cli/template_util.js +26 -29
  7. package/lib/_cjs/core/define_bus.js +9 -6
  8. package/lib/_cjs/core/define_cron.js +0 -2
  9. package/lib/_cjs/core/define_handler.js +10 -12
  10. package/lib/_cjs/core/define_hook.js +0 -2
  11. package/lib/_cjs/core/define_server.js +0 -2
  12. package/lib/_cjs/core/define_task.js +7 -13
  13. package/lib/_cjs/core/get_handler_url.js +1 -2
  14. package/lib/_cjs/core/handler.js +8 -29
  15. package/lib/_cjs/core/http_error.js +0 -3
  16. package/lib/_cjs/core/http_header.js +8 -12
  17. package/lib/_cjs/core/server.js +8 -41
  18. package/lib/_cjs/core/types.js +0 -7
  19. package/lib/_cjs/index.js +0 -72
  20. package/lib/_cjs/plugins/cors.js +0 -7
  21. package/lib/_cjs/plugins/file_parser.js +2 -9
  22. package/lib/_cjs/plugins/form_body_parser.js +0 -6
  23. package/lib/_cjs/plugins/ws_parser.js +0 -6
  24. package/lib/_cjs/plugins/xml_parser.js +0 -12
  25. package/lib/_cjs/services/cache.js +18 -58
  26. package/lib/_cjs/services/captcha.js +0 -14
  27. package/lib/_cjs/services/dingtalk.js +0 -14
  28. package/lib/_cjs/services/dispose.js +0 -9
  29. package/lib/_cjs/services/emoji.js +2 -5
  30. package/lib/_cjs/services/jwt.js +0 -21
  31. package/lib/_cjs/services/log.js +0 -17
  32. package/lib/_cjs/services/mail.js +0 -9
  33. package/lib/_cjs/services/pay.js +9 -40
  34. package/lib/_cjs/services/rate_limit.js +0 -12
  35. package/lib/_cjs/services/redis.js +0 -4
  36. package/lib/_cjs/services/request.js +14 -299
  37. package/lib/_cjs/services/sensitive_words.js +13 -19
  38. package/lib/_cjs/x.js +0 -11
  39. package/lib/cli/api_generator.js +20 -42
  40. package/lib/cli/build_util.js +16 -19
  41. package/lib/cli/cli.js +6 -12
  42. package/lib/cli/deploy_util.js +0 -4
  43. package/lib/cli/env_util.js +16 -37
  44. package/lib/cli/template_util.d.ts +1 -0
  45. package/lib/cli/template_util.js +26 -14
  46. package/lib/core/define_bus.js +7 -5
  47. package/lib/core/define_handler.js +10 -9
  48. package/lib/core/define_task.js +7 -6
  49. package/lib/core/get_handler_url.js +2 -1
  50. package/lib/core/handler.js +9 -22
  51. package/lib/core/http_header.js +6 -9
  52. package/lib/core/server.js +8 -31
  53. package/lib/core/types.js +0 -7
  54. package/lib/index.js +4 -3
  55. package/lib/plugins/cors.js +0 -3
  56. package/lib/plugins/file_parser.js +2 -5
  57. package/lib/plugins/form_body_parser.js +0 -3
  58. package/lib/plugins/ws_parser.js +0 -3
  59. package/lib/plugins/xml_parser.js +0 -10
  60. package/lib/services/cache.js +18 -52
  61. package/lib/services/captcha.js +0 -7
  62. package/lib/services/dingtalk.js +0 -7
  63. package/lib/services/dispose.js +0 -5
  64. package/lib/services/emoji.js +2 -3
  65. package/lib/services/jwt.js +0 -13
  66. package/lib/services/log.js +0 -8
  67. package/lib/services/mail.js +0 -3
  68. package/lib/services/pay.js +9 -30
  69. package/lib/services/rate_limit.js +0 -8
  70. package/lib/services/redis.js +0 -1
  71. package/lib/services/request.d.ts +3 -130
  72. package/lib/services/request.js +5 -274
  73. package/lib/services/sensitive_words.js +13 -15
  74. package/package.json +4 -28
  75. package/README.md +0 -51
  76. package/lib/_cjs/cli/register.js +0 -8
  77. package/lib/_cjs/client_helper.js +0 -26
  78. package/lib/_cjs/types/_formstream.js +0 -1
  79. package/lib/cli/register.d.ts +0 -1
  80. package/lib/cli/register.js +0 -5
  81. package/lib/client_helper.d.ts +0 -1
  82. package/lib/client_helper.js +0 -16
  83. package/lib/types/_formstream.d.ts +0 -49
  84. package/lib/types/_formstream.js +0 -0
@@ -9,17 +9,15 @@ export class ApiGenerator {
9
9
  constructor() {
10
10
  this.debug = createDebug('api');
11
11
  this.cwd = process.cwd();
12
+ // cwd = '/Users/admin/Documents/jfWorks/x-server-test'
12
13
  this.project = void 0;
13
14
  }
14
-
15
15
  getTypeBySymbol(symbol) {
16
16
  return symbol.getTypeAtLocation(symbol.getDeclarations()[0] || symbol.getValueDeclarationOrThrow());
17
17
  }
18
-
19
18
  getComment(declaration) {
20
19
  var _declaration$getLeadi;
21
-
22
- const text = ((declaration == null ? void 0 : (_declaration$getLeadi = declaration.getLeadingCommentRanges()[0]) == null ? void 0 : _declaration$getLeadi.getText()) || '').trim();
20
+ const text = ((declaration == null || (_declaration$getLeadi = declaration.getLeadingCommentRanges()[0]) == null ? void 0 : _declaration$getLeadi.getText()) || '').trim();
23
21
  const comment = parseComment.parse(text)[0];
24
22
  const description = (comment == null ? void 0 : comment.description) || '';
25
23
  const tags = new Map();
@@ -32,16 +30,12 @@ export class ApiGenerator {
32
30
  tags: tags
33
31
  };
34
32
  }
35
-
36
33
  getCommentBySymbol(symbol) {
37
34
  var _this$getComment;
38
-
39
35
  return ((_this$getComment = this.getComment(symbol.getDeclarations()[0])) == null ? void 0 : _this$getComment.description) || '';
40
36
  }
41
-
42
37
  typeToApiData(type, _symbol) {
43
38
  var _type$getSymbol, _type$getSymbol2, _type$getSymbol3;
44
-
45
39
  // ws
46
40
  if (((_type$getSymbol = type.getSymbol()) == null ? void 0 : _type$getSymbol.getName()) === 'SocketStream') {
47
41
  return {
@@ -52,12 +46,11 @@ export class ApiGenerator {
52
46
  children: [],
53
47
  enum: []
54
48
  };
55
- } // XFile
56
-
49
+ }
57
50
 
51
+ // XFile
58
52
  if (((_type$getSymbol2 = type.getSymbol()) == null ? void 0 : _type$getSymbol2.getName()) === 'MultipartFile') {
59
53
  const symbol = _symbol || type.getSymbol();
60
-
61
54
  return {
62
55
  name: 'file',
63
56
  desc: symbol && this.getCommentBySymbol(symbol) || '',
@@ -67,25 +60,22 @@ export class ApiGenerator {
67
60
  enum: []
68
61
  };
69
62
  }
70
-
71
63
  let isRequired = true;
72
64
  let isUnion = type.isUnion();
73
65
  const unionTypes = isUnion ? type.getUnionTypes().filter(item => !item.isBooleanLiteral() && !item.isNull() && !item.isUndefined()) : [];
74
66
  isUnion = !!unionTypes.length;
75
-
76
67
  if (isUnion) {
77
68
  if (unionTypes.length === 1 && !unionTypes[0].isLiteral()) {
78
69
  isUnion = false;
79
- } // 兼容 prisma 生成的类型用 null 表示可选
80
-
81
-
82
- isRequired = unionTypes.length === type.getUnionTypes().length; // 必须用 getBaseTypeOfLiteralType 获取枚举字面量的原始类型
83
-
70
+ }
71
+ // 兼容 prisma 生成的类型用 null 表示可选
72
+ isRequired = unionTypes.length === type.getUnionTypes().length;
73
+ // 必须用 getBaseTypeOfLiteralType 获取枚举字面量的原始类型
84
74
  type = unionTypes[0].getBaseTypeOfLiteralType();
85
75
  }
86
-
87
76
  const isEnum = type.isEnum();
88
- const enumData = isEnum ? // @ts-ignore
77
+ const enumData = isEnum ?
78
+ // @ts-ignore
89
79
  type.compilerType.types.reduce((res, item) => {
90
80
  res[item.getSymbol().getName()] = item.value;
91
81
  return res;
@@ -98,11 +88,10 @@ export class ApiGenerator {
98
88
  const isString = isEnum ? typeof enumValues[0] === 'string' : type.isString() || ['Date'].includes(((_type$getSymbol3 = type.getSymbol()) == null ? void 0 : _type$getSymbol3.getName()) || '');
99
89
  const isNumber = isEnum ? typeof enumValues[0] === 'number' : type.isNumber();
100
90
  const isBoolean = type.isBoolean() || type.isUnion() && type.getUnionTypes().some(item => item.isBooleanLiteral()) && type.getUnionTypes().every(item => item.isBooleanLiteral() || item.isNull() || item.isUndefined());
101
- const isObject = !isArray && !isString && !isNumber && !isBoolean && type.isObject() || // 将交集类型视为对象
91
+ const isObject = !isArray && !isString && !isNumber && !isBoolean && type.isObject() ||
92
+ // 将交集类型视为对象
102
93
  isIntersection;
103
-
104
94
  const symbol = _symbol || type.getSymbol();
105
-
106
95
  const apiName = (symbol == null ? void 0 : symbol.getName()) || '__type';
107
96
  const apiDesc = [symbol && this.getCommentBySymbol(symbol), isEnum && `枚举:${enumKeys.map((key, index) => `${key}->${enumValues[index]}`).join('; ')}`].filter(Boolean).join('\n');
108
97
  const apiEnum = isUnion ? unionTypes.map(t => t.getLiteralValue()) : isEnum ? enumValues : [];
@@ -113,20 +102,21 @@ export class ApiGenerator {
113
102
  const compilerFactory = context.compilerFactory;
114
103
  const rawChecker = type.compilerType.checker;
115
104
  let symbols = [];
116
-
117
105
  if (intersectionTypes) {
118
106
  // https://github.com/microsoft/TypeScript/issues/38184
119
- symbols = rawChecker.getAllPossiblePropertiesOfTypes(intersectionTypes.map(item => item.compilerType)) // https://github.com/dsherret/ts-morph/blob/a7072fcf6f9babb784b40f0326c80dea4563a4aa/packages/ts-morph/src/compiler/types/Type.ts#L296
107
+ symbols = rawChecker.getAllPossiblePropertiesOfTypes(intersectionTypes.map(item => item.compilerType))
108
+ // https://github.com/dsherret/ts-morph/blob/a7072fcf6f9babb784b40f0326c80dea4563a4aa/packages/ts-morph/src/compiler/types/Type.ts#L296
120
109
  .map(symbol => compilerFactory.getSymbol(symbol));
121
110
  } else {
122
111
  // symbols = type.getApparentProperties()
123
112
  // https://github.com/microsoft/TypeScript/issues/38184
124
- symbols = rawChecker.getAllPossiblePropertiesOfTypes([type.compilerType]) // https://github.com/dsherret/ts-morph/blob/a7072fcf6f9babb784b40f0326c80dea4563a4aa/packages/ts-morph/src/compiler/types/Type.ts#L296
113
+ symbols = rawChecker.getAllPossiblePropertiesOfTypes([type.compilerType])
114
+ // https://github.com/dsherret/ts-morph/blob/a7072fcf6f9babb784b40f0326c80dea4563a4aa/packages/ts-morph/src/compiler/types/Type.ts#L296
125
115
  .map(symbol => compilerFactory.getSymbol(symbol));
126
116
  }
127
-
128
117
  return symbols.map(symbol => {
129
- return this.typeToApiData(!symbol.compilerSymbol.declarations ? // 对于复杂对象,没有定义的,通过 type 直接获取(在前面通过 getText 预处理得到)
118
+ return this.typeToApiData(!symbol.compilerSymbol.declarations ?
119
+ // 对于复杂对象,没有定义的,通过 type 直接获取(在前面通过 getText 预处理得到)
130
120
  compilerFactory.getType(symbol.compilerSymbol.type) : this.getTypeBySymbol(symbol), symbol);
131
121
  });
132
122
  }) : [];
@@ -139,10 +129,8 @@ export class ApiGenerator {
139
129
  children: apiChildren
140
130
  };
141
131
  }
142
-
143
132
  apiDataToJsonSchema(apiData, jsonSchema = {}) {
144
133
  jsonSchema.description = apiData.desc;
145
-
146
134
  if (apiData.type === 'object') {
147
135
  jsonSchema.type = 'object';
148
136
  jsonSchema.properties = apiData.children.reduce((res, item) => {
@@ -156,18 +144,14 @@ export class ApiGenerator {
156
144
  jsonSchema.items = apiData.children.map(item => this.apiDataToJsonSchema(item))[0];
157
145
  } else {
158
146
  jsonSchema.type = apiData.type;
159
-
160
147
  if (apiData.enum.length) {
161
148
  jsonSchema.enum = apiData.enum;
162
149
  }
163
150
  }
164
-
165
151
  return jsonSchema;
166
152
  }
167
-
168
153
  genYApiData(handles) {
169
154
  const data = {};
170
-
171
155
  for (const handle of handles) {
172
156
  data[handle.category] = data[handle.category] || [];
173
157
  data[handle.category].push(handle.handlerMethod === 'GET' ? {
@@ -221,14 +205,12 @@ export class ApiGenerator {
221
205
  res_body: JSON.stringify(handle.responseDataJsonSchema)
222
206
  });
223
207
  }
224
-
225
208
  return Object.keys(data).map(cat => ({
226
209
  name: cat,
227
210
  desc: cat,
228
211
  list: data[cat]
229
212
  }));
230
213
  }
231
-
232
214
  async generate() {
233
215
  this.debug('启动项目...');
234
216
  this.project = new ts.Project({
@@ -240,11 +222,9 @@ export class ApiGenerator {
240
222
  const handlerGroup = sourceFile.getExportSymbols();
241
223
  const handles = [];
242
224
  this.debug('生成API文档...');
243
-
244
225
  for (const handlerList of handlerGroup) {
245
226
  const handlerListSourceFile = this.getTypeBySymbol(handlerList).getProperties()[0].getDeclarations()[0].getSourceFile();
246
227
  const basePath = `/${handlerListSourceFile.getFilePath().replace('.ts', '').split('/src/handlers/')[1].replace(/(^|\/)index$/, '/').split('/').map(v => snakeCase(v)).join('/')}/`.replace(/\/{2,}/g, '/');
247
-
248
228
  for (const handler of handlerListSourceFile.getVariableStatements().filter(item => item.isExported())) {
249
229
  // 重要:这一步必须,先调一遍 getText 获取看到的对象,后续对于复杂定义才不会报错
250
230
  handler.getDeclarations().forEach(exp => {
@@ -255,12 +235,10 @@ export class ApiGenerator {
255
235
  this.debug('生成接口: %s ...', handlerPath);
256
236
  const [requestType, responseType, methodType] = handlerExp.getType().getTypeArguments();
257
237
  const handlerComment = this.getComment(handlerExp.getParent().getParent());
258
-
259
238
  if (handlerComment.tags.has('private')) {
260
239
  this.debug('跳过生成接口: %s', `${handlerPath}`);
261
240
  continue;
262
241
  }
263
-
264
242
  const handlerCategory = pascalCase(basePath) || 'Index';
265
243
  const handlerName = handlerComment.description || handlerPath;
266
244
  const handlerMethod = methodType.getLiteralValueOrThrow();
@@ -282,7 +260,6 @@ export class ApiGenerator {
282
260
  });
283
261
  }
284
262
  }
285
-
286
263
  this.debug('写入文件...');
287
264
  await Promise.all([fs.outputJSON(path.join(this.cwd, 'temp/api.json'), handles, {
288
265
  spaces: 2
@@ -290,5 +267,6 @@ export class ApiGenerator {
290
267
  spaces: 2
291
268
  })]);
292
269
  }
270
+ }
293
271
 
294
- } // new ApiGenerator().generate()
272
+ // new ApiGenerator().generate()
@@ -8,7 +8,6 @@ import { dedent, uniq } from 'vtils';
8
8
  export class BuildUtil {
9
9
  static async build(options) {
10
10
  var _options$minify, _options$inlineEnvs;
11
-
12
11
  const mainFile = path.join(options.cwd, 'src/main.ts');
13
12
  const pkgFile = path.join(options.cwd, 'package.json');
14
13
  const pkgContent = await fs.readJson(pkgFile);
@@ -20,8 +19,9 @@ export class BuildUtil {
20
19
  const distNoInstallFile = path.join(distDir, 'no_install.lock');
21
20
  const distBundleFile = path.join(tempDir, `app.${pkgContent.version}.tgz`);
22
21
  await fs.ensureDir(distDir);
23
- await fs.ensureDir(tempDir); // 处理 external
22
+ await fs.ensureDir(tempDir);
24
23
 
24
+ // 处理 external
25
25
  const external = uniq(options.external || []);
26
26
  const externalWithVersions = (await Promise.all(external.map(async item => {
27
27
  try {
@@ -39,17 +39,17 @@ export class BuildUtil {
39
39
  version: ''
40
40
  };
41
41
  }
42
- }))).filter(item => !!item.version); // fix: hexoid 构建问题
42
+ }))).filter(item => !!item.version);
43
43
 
44
+ // fix: hexoid 构建问题
44
45
  try {
45
46
  const hexoidPackageJsonFile = require.resolve('hexoid/package.json');
46
-
47
47
  const pkg = await fs.readJson(hexoidPackageJsonFile);
48
48
  delete pkg.module;
49
49
  await fs.writeJson(hexoidPackageJsonFile, pkg);
50
- } catch {} // 构建
51
-
50
+ } catch {}
52
51
 
52
+ // 构建
53
53
  await fs.emptyDir(distDir);
54
54
  await esbuild.build({
55
55
  entryPoints: [mainFile],
@@ -75,7 +75,6 @@ export class BuildUtil {
75
75
  },
76
76
  plugins: [{
77
77
  name: 'extract-assets',
78
-
79
78
  setup(build) {
80
79
  build.onLoad({
81
80
  filter: /\/svg-captcha\/lib\/option-manager\.js$/
@@ -114,30 +113,29 @@ export class BuildUtil {
114
113
  };
115
114
  });
116
115
  }
117
-
118
116
  }]
119
- }); // 兼容 prisma
117
+ });
120
118
 
119
+ // 兼容 prisma
121
120
  const prismaSchemaFile = path.join(options.cwd, 'src/db/schema.prisma');
122
-
123
121
  if (await fs.pathExists(prismaSchemaFile)) {
124
122
  // 复制 schema.prisma
125
123
  const distPrismaSchemaFile = path.join(distDir, path.basename(prismaSchemaFile));
126
- await fs.copyFile(prismaSchemaFile, distPrismaSchemaFile); // 复制查询引擎
124
+ await fs.copyFile(prismaSchemaFile, distPrismaSchemaFile);
127
125
 
126
+ // 复制查询引擎
128
127
  const libqueryEngineFiles = await globby('libquery_engine-*', {
129
128
  cwd: path.join(options.cwd, 'node_modules/.prisma/client'),
130
129
  ignore: ['libquery_engine-{darwin,windows}*'],
131
130
  onlyFiles: true,
132
131
  absolute: true
133
132
  });
134
-
135
133
  for (const libqueryEngineFile of libqueryEngineFiles) {
136
134
  await fs.copyFile(libqueryEngineFile, path.join(distDir, path.basename(libqueryEngineFile)));
137
135
  }
138
- } // 写入 pkg
139
-
136
+ }
140
137
 
138
+ // 写入 pkg
141
139
  const deps = externalWithVersions.reduce((res, item) => {
142
140
  res[item.name] = item.version;
143
141
  return res;
@@ -147,8 +145,9 @@ export class BuildUtil {
147
145
  version: pkgContent.version,
148
146
  dependencies: deps
149
147
  };
150
- await fs.writeJSON(distPkgFile, distPkgContent); // 写入 pm2 配置
148
+ await fs.writeJSON(distPkgFile, distPkgContent);
151
149
 
150
+ // 写入 pm2 配置
152
151
  await fs.writeFile(distPm2File, dedent`
153
152
  module.exports = {
154
153
  apps: [
@@ -160,7 +159,6 @@ export class BuildUtil {
160
159
  ],
161
160
  }
162
161
  `);
163
-
164
162
  if (externalWithVersions.length) {
165
163
  if (options.noInstall) {
166
164
  await fs.writeFile(distNoInstallFile, '');
@@ -177,10 +175,9 @@ export class BuildUtil {
177
175
  }
178
176
  });
179
177
  }
180
- } // 打包为 tgz
181
-
178
+ }
182
179
 
180
+ // 打包为 tgz
183
181
  await compressing.tgz.compressDir(distDir, distBundleFile);
184
182
  }
185
-
186
183
  }
package/lib/cli/cli.js CHANGED
@@ -20,14 +20,12 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
20
20
  }), async argv => {
21
21
  process.env.NODE_ENV = 'development';
22
22
  let lastRun;
23
-
24
23
  const run = () => {
25
- lastRun = execa('node', ['-r', require.resolve("./register"), 'src/main.ts'], {
24
+ lastRun = execa('tsx', ['src/main.ts'], {
26
25
  cwd: process.cwd(),
27
26
  stdio: 'inherit'
28
27
  });
29
28
  };
30
-
31
29
  if (argv.npc) {
32
30
  const [server, vkey] = argv.npc.split('@');
33
31
  execa('docker', ['run', '--rm', 'ffdfgdfg/npc:v0.26.9', `-server=${server}`, `-vkey=${vkey}`, '-type=tcp'], {
@@ -35,10 +33,10 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
35
33
  stdio: 'inherit'
36
34
  });
37
35
  }
38
-
39
36
  await TemplateUtil.init(process.cwd());
40
37
  const watcher = chokidar.watch(['src', '.env', '.env.*'], {
41
- cwd: process.cwd()
38
+ cwd: process.cwd(),
39
+ ignored: '**/*.test.*'
42
40
  });
43
41
  watcher.on('all', debounce(async () => {
44
42
  await EnvUtil.importFile({
@@ -58,7 +56,6 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
58
56
  console.log(`✔️ 索引文件已更新: ${filePath}`);
59
57
  }
60
58
  });
61
-
62
59
  if (lastRun) {
63
60
  console.log('==== 重启服务中 ====');
64
61
  lastRun.kill();
@@ -124,15 +121,14 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
124
121
  await EnvUtil.importFile({
125
122
  cwd: process.cwd(),
126
123
  file: '.env'
127
- }); // 之所以能成功是因为 Prisma 用的 dotenv 默认不会覆盖已经设置的环境变量
124
+ });
125
+ // 之所以能成功是因为 Prisma 用的 dotenv 默认不会覆盖已经设置的环境变量
128
126
  // https://github.com/motdotla/dotenv#override
129
-
130
127
  process.env.DATABASE_URL = process.env.DATABASE_ACTION_URL || process.env.DATABASE_URL;
131
128
  await execa('tnpx', ['prisma', ...argv._.slice(1), '--schema', 'src/db/schema.prisma'], {
132
129
  cwd: process.cwd(),
133
130
  stdio: 'inherit'
134
131
  });
135
-
136
132
  if (!argv.production) {
137
133
  await TemplateUtil.initModels(process.cwd());
138
134
  }
@@ -151,14 +147,13 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
151
147
  file: '.env'
152
148
  });
153
149
  process.env.DATABASE_URL = process.env.DATABASE_ACTION_URL || process.env.DATABASE_URL;
154
-
155
150
  if (!argv.script) {
156
151
  await execa('tnpx', ['select-run'], {
157
152
  cwd: process.cwd(),
158
153
  stdio: 'inherit'
159
154
  });
160
155
  } else {
161
- await execa('node', ['-r', require.resolve("./register"), argv.script], {
156
+ await execa('tsx', [argv.script], {
162
157
  cwd: process.cwd(),
163
158
  stdio: 'inherit'
164
159
  });
@@ -172,7 +167,6 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
172
167
  cwd: process.cwd(),
173
168
  file: '.env.deploy'
174
169
  });
175
-
176
170
  if (argv.type === 'env') {
177
171
  const appEnv = await EnvUtil.parseFileAsMap({
178
172
  cwd: process.cwd(),
@@ -6,11 +6,9 @@ export class DeployUtil {
6
6
  static async deploy(options) {
7
7
  const pkgContent = await fs.readJson(path.join(options.cwd, 'package.json'));
8
8
  const appFile = path.join(options.cwd, `temp/app.${pkgContent.version}.tgz`);
9
-
10
9
  if (!(await fs.pathExists(appFile))) {
11
10
  throw new Error('请先构建');
12
11
  }
13
-
14
12
  const ssh = new NodeSSH();
15
13
  await ssh.connect({
16
14
  host: options.host,
@@ -44,7 +42,6 @@ export class DeployUtil {
44
42
  });
45
43
  ssh.dispose();
46
44
  }
47
-
48
45
  static async deployEnv(options) {
49
46
  const ssh = new NodeSSH();
50
47
  await ssh.connect({
@@ -68,5 +65,4 @@ export class DeployUtil {
68
65
  });
69
66
  ssh.dispose();
70
67
  }
71
-
72
68
  }
@@ -9,27 +9,21 @@ export class EnvUtil {
9
9
  const [devValue, prodValue] = value.split(/\s+\|\|\s+/);
10
10
  return devOrProd(() => EnvUtil.normalizeValue(devValue), () => EnvUtil.normalizeValue(prodValue));
11
11
  }
12
-
13
12
  return value === 'true' ? true : value === 'false' ? false : value.startsWith('[') && value.endsWith(']') || value.startsWith('{') && value.endsWith('}') ? JSON.parse(value) : isNumeric(value) ? Number(value) : value;
14
13
  } else if (value && typeof value === 'object') {
15
14
  if (value.dev != null && value.prod != null) {
16
15
  return devOrProd(() => value.dev, () => value.prod);
17
16
  }
18
-
19
17
  return value;
20
18
  }
21
-
22
19
  return value;
23
20
  }
24
-
25
21
  static parseContent(src, isYaml = false) {
26
22
  const envs = [];
27
-
28
23
  if (isYaml) {
29
24
  const envObj = yamlParse(src);
30
25
  Object.keys(envObj).forEach(key => {
31
26
  var _src$match;
32
-
33
27
  envs.push({
34
28
  key: key,
35
29
  value: this.normalizeValue(envObj[key]),
@@ -38,56 +32,54 @@ export class EnvUtil {
38
32
  });
39
33
  } else {
40
34
  // https://github.com/andreialecu/dotenv/blob/feat-multiline/lib/main.js
41
- const multilineLineBreaks = true; // convert Buffers before splitting into lines and processing
35
+ const multilineLineBreaks = true;
42
36
 
37
+ // convert Buffers before splitting into lines and processing
43
38
  const lines = src.split(EnvUtil.NEWLINES_MATCH);
44
39
  let lastComment = '';
45
-
46
40
  for (let idx = 0; idx < lines.length; idx++) {
47
- let line = lines[idx]; // matching "KEY' and 'VAL' in 'KEY=VAL'
48
-
49
- const keyValueArr = line.match(EnvUtil.RE_INI_KEY_VAL); // matched?
41
+ let line = lines[idx];
50
42
 
43
+ // matching "KEY' and 'VAL' in 'KEY=VAL'
44
+ const keyValueArr = line.match(EnvUtil.RE_INI_KEY_VAL);
45
+ // matched?
51
46
  if (keyValueArr != null) {
52
- const key = keyValueArr[1]; // default undefined or missing values to empty string
53
-
47
+ const key = keyValueArr[1];
48
+ // default undefined or missing values to empty string
54
49
  let val = keyValueArr[2] || '';
55
50
  let end = val.length - 1;
56
51
  const isDoubleQuoted = val[0] === '"' && val[end] === '"';
57
52
  const isSingleQuoted = val[0] === "'" && val[end] === "'";
58
53
  const isMultilineDoubleQuoted = val[0] === '"' && (val.length === 1 || val[end] !== '"');
59
- const isMultilineSingleQuoted = val[0] === "'" && (val.length === 1 || val[end] !== "'"); // if parsing line breaks and the value starts with a quote
54
+ const isMultilineSingleQuoted = val[0] === "'" && (val.length === 1 || val[end] !== "'");
60
55
 
56
+ // if parsing line breaks and the value starts with a quote
61
57
  if (multilineLineBreaks && (isMultilineDoubleQuoted || isMultilineSingleQuoted)) {
62
58
  const quoteChar = isMultilineDoubleQuoted ? '"' : "'";
63
59
  val = val.substring(1);
64
-
65
60
  while (idx++ < lines.length - 1) {
66
61
  line = lines[idx];
67
62
  end = line.length - 1;
68
-
69
63
  if (line[end] === quoteChar) {
70
64
  val += EnvUtil.NEWLINE + line.substring(0, end);
71
65
  break;
72
66
  }
73
-
74
67
  val += EnvUtil.NEWLINE + line;
75
68
  }
76
-
77
- val = dedent(val); // if single or double quoted, remove quotes
69
+ val = dedent(val);
70
+ // if single or double quoted, remove quotes
78
71
  } else if (isSingleQuoted || isDoubleQuoted) {
79
- val = val.substring(1, end); // if double quoted, expand newlines
72
+ val = val.substring(1, end);
80
73
 
74
+ // if double quoted, expand newlines
81
75
  if (isDoubleQuoted) {
82
76
  val = val.replace(EnvUtil.RE_NEWLINES, EnvUtil.NEWLINE);
83
77
  }
84
-
85
78
  val = dedent(val);
86
79
  } else {
87
80
  // remove surrounding whitespace
88
81
  val = dedent(val).trim();
89
82
  }
90
-
91
83
  envs.push({
92
84
  key: key,
93
85
  value: EnvUtil.normalizeValue(val),
@@ -96,58 +88,47 @@ export class EnvUtil {
96
88
  lastComment = '';
97
89
  } else {
98
90
  const commentArr = line.match(EnvUtil.COMMENT_MATCH);
99
-
100
91
  if (commentArr) {
101
92
  lastComment = commentArr[1];
102
93
  }
103
94
  }
104
95
  }
105
96
  }
106
-
107
97
  return envs;
108
98
  }
109
-
110
99
  static async parseFile(options) {
111
100
  const envFile = path.join(options.cwd, options.file);
112
101
  const envYmlFile = path.join(options.cwd, `${options.file}.yml`);
113
102
  const envYamlFile = path.join(options.cwd, `${options.file}.yaml`);
114
103
  const file = (await fs.pathExists(envYmlFile)) ? envYmlFile : (await fs.pathExists(envYamlFile)) ? envYamlFile : (await fs.pathExists(envFile)) ? envFile : '';
115
-
116
104
  if (file) {
117
105
  const envContent = await fs.readFile(file, 'utf-8');
118
106
  const envs = EnvUtil.parseContent(envContent, /\.ya?ml$/i.test(file));
119
107
  return envs;
120
108
  }
121
-
122
109
  return [];
123
110
  }
124
-
125
111
  static async parseFileAsMap(options) {
126
112
  const envs = await EnvUtil.parseFile(options);
127
113
  const envsObj = {};
128
-
129
114
  for (const env of envs) {
130
115
  envsObj[env.key] = env.value;
131
116
  }
132
-
133
117
  return envsObj;
134
118
  }
135
-
136
119
  static async importFile(options) {
137
120
  const envs = await EnvUtil.parseFile(options);
138
121
  const envsObj = {};
139
-
140
122
  for (const env of envs) {
141
123
  envsObj[env.key] = env.value;
142
124
  process.env[env.key] = env.value;
143
125
  }
144
-
145
- process.env.X_SERVER_ENVS = JSON.stringify({ // @ts-ignore
126
+ process.env.X_SERVER_ENVS = JSON.stringify({
127
+ // @ts-ignore
146
128
  ...JSON.parse(process.env.X_SERVER_ENVS || '{}'),
147
129
  ...envsObj
148
130
  });
149
131
  }
150
-
151
132
  static makeTypes(envs) {
152
133
  return dedent`
153
134
  declare namespace NodeJS {
@@ -168,14 +149,12 @@ export class EnvUtil {
168
149
  }
169
150
  `;
170
151
  }
171
-
172
152
  static async outputTypes(options) {
173
153
  const envs = await EnvUtil.parseFile(options);
174
154
  const outFile = path.join(options.cwd, options.outFile);
175
155
  const types = EnvUtil.makeTypes(envs);
176
156
  await fs.outputFile(outFile, types);
177
157
  }
178
-
179
158
  }
180
159
  EnvUtil.NEWLINE = '\n';
181
160
  EnvUtil.RE_INI_KEY_VAL = /^\s*([\w.-]+)\s*=\s*(.*)?\s*$/;
@@ -15,4 +15,5 @@ export declare class TemplateUtil {
15
15
  * 初始化模型。
16
16
  */
17
17
  static initModels(cwd: string): Promise<void>;
18
+ static getPrismaClientTypeFile(): string;
18
19
  }