@jayfong/x-server 2.74.2 → 2.74.3
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/lib/_cjs/cli/cli.js +121 -106
- package/lib/_cjs/cli/env_util.js +25 -2
- package/lib/cli/cli.js +121 -106
- package/lib/cli/env_util.d.ts +6 -0
- package/lib/cli/env_util.js +25 -2
- package/package.json +1 -1
package/lib/_cjs/cli/cli.js
CHANGED
|
@@ -16,43 +16,46 @@ var _dev_util = require("./dev_util");
|
|
|
16
16
|
var _env_util = require("./env_util");
|
|
17
17
|
var _template_util = require("./template_util");
|
|
18
18
|
async function deploy(argv) {
|
|
19
|
-
|
|
20
|
-
argv.channel = await _env_util.EnvUtil.chooseChannel(process.cwd());
|
|
21
|
-
}
|
|
22
|
-
const deployEnvFiles = _env_util.EnvUtil.getFile('deploy', argv.channel, true);
|
|
23
|
-
const deployEnv = await _env_util.EnvUtil.parseFileAsMap({
|
|
19
|
+
await _env_util.EnvUtil.withChannel({
|
|
24
20
|
cwd: process.cwd(),
|
|
25
|
-
|
|
21
|
+
channel: argv.channel,
|
|
22
|
+
cb: async channel => {
|
|
23
|
+
const deployEnvFiles = _env_util.EnvUtil.getFile('deploy', channel, true);
|
|
24
|
+
const deployEnv = await _env_util.EnvUtil.parseFileAsMap({
|
|
25
|
+
cwd: process.cwd(),
|
|
26
|
+
file: deployEnvFiles
|
|
27
|
+
});
|
|
28
|
+
if (argv.type === 'env') {
|
|
29
|
+
const appEnvFiles = _env_util.EnvUtil.getFile('production', channel);
|
|
30
|
+
const appEnv = await _env_util.EnvUtil.parseFileAsMap({
|
|
31
|
+
cwd: process.cwd(),
|
|
32
|
+
file: appEnvFiles
|
|
33
|
+
});
|
|
34
|
+
await _deploy_util.DeployUtil.deployEnv({
|
|
35
|
+
host: deployEnv.HOST,
|
|
36
|
+
user: deployEnv.USER,
|
|
37
|
+
key: deployEnv.KEY,
|
|
38
|
+
pass: deployEnv.PASSWORD,
|
|
39
|
+
token: appEnv.APP_TOKEN,
|
|
40
|
+
port: appEnv.APP_PORT,
|
|
41
|
+
env: appEnv
|
|
42
|
+
});
|
|
43
|
+
} else {
|
|
44
|
+
await _deploy_util.DeployUtil.deploy({
|
|
45
|
+
cwd: process.cwd(),
|
|
46
|
+
host: deployEnv.HOST,
|
|
47
|
+
user: deployEnv.USER,
|
|
48
|
+
key: deployEnv.KEY,
|
|
49
|
+
pass: deployEnv.PASSWORD,
|
|
50
|
+
dir: deployEnv.DIR,
|
|
51
|
+
cmd: deployEnv.CMD,
|
|
52
|
+
memory: deployEnv.MEMORY,
|
|
53
|
+
cron: deployEnv.CRON,
|
|
54
|
+
channel: channel
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
26
58
|
});
|
|
27
|
-
if (argv.type === 'env') {
|
|
28
|
-
const appEnvFiles = _env_util.EnvUtil.getFile('production', argv.channel);
|
|
29
|
-
const appEnv = await _env_util.EnvUtil.parseFileAsMap({
|
|
30
|
-
cwd: process.cwd(),
|
|
31
|
-
file: appEnvFiles
|
|
32
|
-
});
|
|
33
|
-
await _deploy_util.DeployUtil.deployEnv({
|
|
34
|
-
host: deployEnv.HOST,
|
|
35
|
-
user: deployEnv.USER,
|
|
36
|
-
key: deployEnv.KEY,
|
|
37
|
-
pass: deployEnv.PASSWORD,
|
|
38
|
-
token: appEnv.APP_TOKEN,
|
|
39
|
-
port: appEnv.APP_PORT,
|
|
40
|
-
env: appEnv
|
|
41
|
-
});
|
|
42
|
-
} else {
|
|
43
|
-
await _deploy_util.DeployUtil.deploy({
|
|
44
|
-
cwd: process.cwd(),
|
|
45
|
-
host: deployEnv.HOST,
|
|
46
|
-
user: deployEnv.USER,
|
|
47
|
-
key: deployEnv.KEY,
|
|
48
|
-
pass: deployEnv.PASSWORD,
|
|
49
|
-
dir: deployEnv.DIR,
|
|
50
|
-
cmd: deployEnv.CMD,
|
|
51
|
-
memory: deployEnv.MEMORY,
|
|
52
|
-
cron: deployEnv.CRON,
|
|
53
|
-
channel: argv.channel
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
59
|
}
|
|
57
60
|
_yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
58
61
|
alias: 'i',
|
|
@@ -149,38 +152,44 @@ _yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
149
152
|
type: 'boolean',
|
|
150
153
|
default: false
|
|
151
154
|
}), async argv => {
|
|
152
|
-
|
|
153
|
-
argv.channel = await _env_util.EnvUtil.chooseChannel(process.cwd());
|
|
154
|
-
}
|
|
155
|
-
process.env.NODE_ENV = 'production';
|
|
156
|
-
const externals = (0, _vtils.castArray)(argv.external || []).flatMap(item => item.split(',')).filter(Boolean);
|
|
157
|
-
const envFiles = _env_util.EnvUtil.getFile(process.env.NODE_ENV, argv.channel);
|
|
158
|
-
const envMap = await _env_util.EnvUtil.parseFileAsMap({
|
|
159
|
-
cwd: process.cwd(),
|
|
160
|
-
file: envFiles
|
|
161
|
-
});
|
|
162
|
-
envMap.NODE_ENV = 'production';
|
|
163
|
-
await _template_util.TemplateUtil.init(process.cwd());
|
|
164
|
-
await (0, _vscodeGenerateIndexStandalone.generateManyIndex)({
|
|
155
|
+
await _env_util.EnvUtil.withChannel({
|
|
165
156
|
cwd: process.cwd(),
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
157
|
+
channel: argv.channel,
|
|
158
|
+
cb: async channel => {
|
|
159
|
+
process.env.NODE_ENV = 'production';
|
|
160
|
+
const externals = (0, _vtils.castArray)(argv.external || []).flatMap(item => item.split(',')).filter(Boolean);
|
|
161
|
+
const envFiles = _env_util.EnvUtil.getFile(process.env.NODE_ENV, channel);
|
|
162
|
+
const envMap = await _env_util.EnvUtil.parseFileAsMap({
|
|
163
|
+
cwd: process.cwd(),
|
|
164
|
+
file: envFiles
|
|
165
|
+
});
|
|
166
|
+
envMap.NODE_ENV = 'production';
|
|
167
|
+
await _template_util.TemplateUtil.init(process.cwd());
|
|
168
|
+
await (0, _vscodeGenerateIndexStandalone.generateManyIndex)({
|
|
169
|
+
cwd: process.cwd(),
|
|
170
|
+
patterns: ['src/.x/*.ts'],
|
|
171
|
+
replaceFile: true,
|
|
172
|
+
onSuccess: filePath => {
|
|
173
|
+
console.log(`✔️ 索引文件已更新: ${filePath}`);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
await _build_util.BuildUtil.build({
|
|
177
|
+
cwd: process.cwd(),
|
|
178
|
+
external: externals,
|
|
179
|
+
inlineEnvs: envMap,
|
|
180
|
+
minify: argv.minify,
|
|
181
|
+
noInstall: argv['no-install'],
|
|
182
|
+
channel: channel
|
|
183
|
+
});
|
|
184
|
+
console.log('构建成功');
|
|
185
|
+
if (argv.deploy) {
|
|
186
|
+
await deploy({
|
|
187
|
+
...argv,
|
|
188
|
+
channel
|
|
189
|
+
});
|
|
190
|
+
}
|
|
170
191
|
}
|
|
171
192
|
});
|
|
172
|
-
await _build_util.BuildUtil.build({
|
|
173
|
-
cwd: process.cwd(),
|
|
174
|
-
external: externals,
|
|
175
|
-
inlineEnvs: envMap,
|
|
176
|
-
minify: argv.minify,
|
|
177
|
-
noInstall: argv['no-install'],
|
|
178
|
-
channel: argv.channel
|
|
179
|
-
});
|
|
180
|
-
console.log('构建成功');
|
|
181
|
-
if (argv.deploy) {
|
|
182
|
-
await deploy(argv);
|
|
183
|
-
}
|
|
184
193
|
}).command('api', '生成 API', _ => _.positional('channel', {
|
|
185
194
|
alias: 'h',
|
|
186
195
|
describe: '渠道',
|
|
@@ -206,31 +215,34 @@ _yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
206
215
|
describe: '渠道',
|
|
207
216
|
type: 'string'
|
|
208
217
|
}), async argv => {
|
|
209
|
-
|
|
210
|
-
argv.channel = await _env_util.EnvUtil.chooseChannel(process.cwd());
|
|
211
|
-
}
|
|
212
|
-
process.env.NODE_ENV = argv.production ? 'production' : 'development';
|
|
213
|
-
const envFiles = _env_util.EnvUtil.getFile(process.env.NODE_ENV, argv.channel);
|
|
214
|
-
await _env_util.EnvUtil.importFile({
|
|
218
|
+
await _env_util.EnvUtil.withChannel({
|
|
215
219
|
cwd: process.cwd(),
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
220
|
+
channel: argv.channel,
|
|
221
|
+
cb: async channel => {
|
|
222
|
+
process.env.NODE_ENV = argv.production ? 'production' : 'development';
|
|
223
|
+
const envFiles = _env_util.EnvUtil.getFile(process.env.NODE_ENV, channel);
|
|
224
|
+
await _env_util.EnvUtil.importFile({
|
|
225
|
+
cwd: process.cwd(),
|
|
226
|
+
file: envFiles
|
|
227
|
+
});
|
|
228
|
+
// 之所以能成功是因为 Prisma 用的 dotenv 默认不会覆盖已经设置的环境变量
|
|
229
|
+
// https://github.com/motdotla/dotenv#override
|
|
230
|
+
process.env.DATABASE_URL = process.env.DATABASE_ACTION_URL || process.env.DATABASE_URL;
|
|
221
231
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
232
|
+
// 多 schema 文件兼容
|
|
233
|
+
// https://www.prisma.io/docs/orm/prisma-schema/overview/location#how-to-use-existing-prisma-cli-commands-with-multiple-prisma-schema-files
|
|
234
|
+
const schemaDir = _path.default.join(process.cwd(), 'src/db/schema');
|
|
235
|
+
const isMultipleFiles = await _fsExtra.default.pathExists(schemaDir);
|
|
236
|
+
const schemaArg = isMultipleFiles ? 'src/db' : 'src/db/schema.prisma';
|
|
237
|
+
await (0, _execa.default)('tnpx', ['prisma', ...argv._.slice(1), '--schema', schemaArg], {
|
|
238
|
+
cwd: process.cwd(),
|
|
239
|
+
stdio: 'inherit'
|
|
240
|
+
});
|
|
241
|
+
if (!argv.production) {
|
|
242
|
+
await _template_util.TemplateUtil.initModels(process.cwd());
|
|
243
|
+
}
|
|
244
|
+
}
|
|
230
245
|
});
|
|
231
|
-
if (!argv.production) {
|
|
232
|
-
await _template_util.TemplateUtil.initModels(process.cwd());
|
|
233
|
-
}
|
|
234
246
|
}).command('run [script]', '执行脚本', _ => _.positional('script', {
|
|
235
247
|
describe: '脚本',
|
|
236
248
|
type: 'string'
|
|
@@ -247,28 +259,31 @@ _yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
247
259
|
describe: '使用 tsx 运行',
|
|
248
260
|
type: 'boolean'
|
|
249
261
|
}), async argv => {
|
|
250
|
-
|
|
251
|
-
argv.channel = await _env_util.EnvUtil.chooseChannel(process.cwd());
|
|
252
|
-
}
|
|
253
|
-
process.env.NODE_ENV = argv.production ? 'production' : 'development';
|
|
254
|
-
const envFiles = _env_util.EnvUtil.getFile(process.env.NODE_ENV, argv.channel);
|
|
255
|
-
await _env_util.EnvUtil.importFile({
|
|
262
|
+
await _env_util.EnvUtil.withChannel({
|
|
256
263
|
cwd: process.cwd(),
|
|
257
|
-
|
|
264
|
+
channel: argv.channel,
|
|
265
|
+
cb: async channel => {
|
|
266
|
+
process.env.NODE_ENV = argv.production ? 'production' : 'development';
|
|
267
|
+
const envFiles = _env_util.EnvUtil.getFile(process.env.NODE_ENV, channel);
|
|
268
|
+
await _env_util.EnvUtil.importFile({
|
|
269
|
+
cwd: process.cwd(),
|
|
270
|
+
file: envFiles
|
|
271
|
+
});
|
|
272
|
+
process.env.DATABASE_URL = process.env.DATABASE_ACTION_URL || process.env.DATABASE_URL;
|
|
273
|
+
if (!argv.script) {
|
|
274
|
+
await (0, _execa.default)('tnpx', ['select-run'], {
|
|
275
|
+
cwd: process.cwd(),
|
|
276
|
+
stdio: 'inherit'
|
|
277
|
+
});
|
|
278
|
+
} else {
|
|
279
|
+
await _dev_util.DevUtil.runFile({
|
|
280
|
+
file: argv.script,
|
|
281
|
+
cwd: process.cwd(),
|
|
282
|
+
runner: argv.tsx ? 'tsx' : 'esbuild-register'
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
}
|
|
258
286
|
});
|
|
259
|
-
process.env.DATABASE_URL = process.env.DATABASE_ACTION_URL || process.env.DATABASE_URL;
|
|
260
|
-
if (!argv.script) {
|
|
261
|
-
await (0, _execa.default)('tnpx', ['select-run'], {
|
|
262
|
-
cwd: process.cwd(),
|
|
263
|
-
stdio: 'inherit'
|
|
264
|
-
});
|
|
265
|
-
} else {
|
|
266
|
-
await _dev_util.DevUtil.runFile({
|
|
267
|
-
file: argv.script,
|
|
268
|
-
cwd: process.cwd(),
|
|
269
|
-
runner: argv.tsx ? 'tsx' : 'esbuild-register'
|
|
270
|
-
});
|
|
271
|
-
}
|
|
272
287
|
}).command('deploy [type]', '部署', _ => _.positional('type', {
|
|
273
288
|
describe: '类型',
|
|
274
289
|
type: 'string',
|
package/lib/_cjs/cli/env_util.js
CHANGED
|
@@ -10,16 +10,21 @@ var _inquirer = _interopRequireDefault(require("inquirer"));
|
|
|
10
10
|
var _vtils = require("vtils");
|
|
11
11
|
var _yaml = require("yaml");
|
|
12
12
|
class EnvUtil {
|
|
13
|
-
static async
|
|
13
|
+
static async getAllChannel(cwd) {
|
|
14
14
|
const channelFiles = await (0, _globby.default)(['.env@*'], {
|
|
15
15
|
cwd: cwd,
|
|
16
16
|
onlyFiles: true,
|
|
17
17
|
absolute: false
|
|
18
18
|
});
|
|
19
19
|
if (channelFiles.length === 0) {
|
|
20
|
-
return
|
|
20
|
+
return [];
|
|
21
21
|
}
|
|
22
22
|
const channels = (0, _vtils.uniq)(channelFiles.map(channel => channel.split('@').pop().split('.')[0]));
|
|
23
|
+
return channels;
|
|
24
|
+
}
|
|
25
|
+
static async chooseChannel(cwd) {
|
|
26
|
+
const channels = await EnvUtil.getAllChannel(cwd);
|
|
27
|
+
if (channels.length === 0) return undefined;
|
|
23
28
|
if (channels.length === 1) return channels[0];
|
|
24
29
|
const res = await _inquirer.default.prompt([{
|
|
25
30
|
name: 'channel',
|
|
@@ -29,6 +34,24 @@ class EnvUtil {
|
|
|
29
34
|
}]);
|
|
30
35
|
return res.channel || undefined;
|
|
31
36
|
}
|
|
37
|
+
static async withChannel(options) {
|
|
38
|
+
if (options.channel === '_') {
|
|
39
|
+
const channel = await EnvUtil.chooseChannel(options.cwd);
|
|
40
|
+
console.log(`========= ${channel} =========`);
|
|
41
|
+
await options.cb(channel);
|
|
42
|
+
} else if (options.channel === '@') {
|
|
43
|
+
const channels = await EnvUtil.getAllChannel(options.cwd);
|
|
44
|
+
for (const channel of channels) {
|
|
45
|
+
console.log(`========= ${channel} =========`);
|
|
46
|
+
await options.cb(channel);
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
if (options.channel) {
|
|
50
|
+
console.log(`========= ${options.channel} =========`);
|
|
51
|
+
}
|
|
52
|
+
await options.cb(options.channel);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
32
55
|
static getFile(env, channel, noBase) {
|
|
33
56
|
const file = noBase ? [] : ['.env'];
|
|
34
57
|
if (!noBase && channel) {
|
package/lib/cli/cli.js
CHANGED
|
@@ -13,43 +13,46 @@ import { DevUtil } from "./dev_util";
|
|
|
13
13
|
import { EnvUtil } from "./env_util";
|
|
14
14
|
import { TemplateUtil } from "./template_util";
|
|
15
15
|
async function deploy(argv) {
|
|
16
|
-
|
|
17
|
-
argv.channel = await EnvUtil.chooseChannel(process.cwd());
|
|
18
|
-
}
|
|
19
|
-
const deployEnvFiles = EnvUtil.getFile('deploy', argv.channel, true);
|
|
20
|
-
const deployEnv = await EnvUtil.parseFileAsMap({
|
|
16
|
+
await EnvUtil.withChannel({
|
|
21
17
|
cwd: process.cwd(),
|
|
22
|
-
|
|
18
|
+
channel: argv.channel,
|
|
19
|
+
cb: async channel => {
|
|
20
|
+
const deployEnvFiles = EnvUtil.getFile('deploy', channel, true);
|
|
21
|
+
const deployEnv = await EnvUtil.parseFileAsMap({
|
|
22
|
+
cwd: process.cwd(),
|
|
23
|
+
file: deployEnvFiles
|
|
24
|
+
});
|
|
25
|
+
if (argv.type === 'env') {
|
|
26
|
+
const appEnvFiles = EnvUtil.getFile('production', channel);
|
|
27
|
+
const appEnv = await EnvUtil.parseFileAsMap({
|
|
28
|
+
cwd: process.cwd(),
|
|
29
|
+
file: appEnvFiles
|
|
30
|
+
});
|
|
31
|
+
await DeployUtil.deployEnv({
|
|
32
|
+
host: deployEnv.HOST,
|
|
33
|
+
user: deployEnv.USER,
|
|
34
|
+
key: deployEnv.KEY,
|
|
35
|
+
pass: deployEnv.PASSWORD,
|
|
36
|
+
token: appEnv.APP_TOKEN,
|
|
37
|
+
port: appEnv.APP_PORT,
|
|
38
|
+
env: appEnv
|
|
39
|
+
});
|
|
40
|
+
} else {
|
|
41
|
+
await DeployUtil.deploy({
|
|
42
|
+
cwd: process.cwd(),
|
|
43
|
+
host: deployEnv.HOST,
|
|
44
|
+
user: deployEnv.USER,
|
|
45
|
+
key: deployEnv.KEY,
|
|
46
|
+
pass: deployEnv.PASSWORD,
|
|
47
|
+
dir: deployEnv.DIR,
|
|
48
|
+
cmd: deployEnv.CMD,
|
|
49
|
+
memory: deployEnv.MEMORY,
|
|
50
|
+
cron: deployEnv.CRON,
|
|
51
|
+
channel: channel
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
23
55
|
});
|
|
24
|
-
if (argv.type === 'env') {
|
|
25
|
-
const appEnvFiles = EnvUtil.getFile('production', argv.channel);
|
|
26
|
-
const appEnv = await EnvUtil.parseFileAsMap({
|
|
27
|
-
cwd: process.cwd(),
|
|
28
|
-
file: appEnvFiles
|
|
29
|
-
});
|
|
30
|
-
await DeployUtil.deployEnv({
|
|
31
|
-
host: deployEnv.HOST,
|
|
32
|
-
user: deployEnv.USER,
|
|
33
|
-
key: deployEnv.KEY,
|
|
34
|
-
pass: deployEnv.PASSWORD,
|
|
35
|
-
token: appEnv.APP_TOKEN,
|
|
36
|
-
port: appEnv.APP_PORT,
|
|
37
|
-
env: appEnv
|
|
38
|
-
});
|
|
39
|
-
} else {
|
|
40
|
-
await DeployUtil.deploy({
|
|
41
|
-
cwd: process.cwd(),
|
|
42
|
-
host: deployEnv.HOST,
|
|
43
|
-
user: deployEnv.USER,
|
|
44
|
-
key: deployEnv.KEY,
|
|
45
|
-
pass: deployEnv.PASSWORD,
|
|
46
|
-
dir: deployEnv.DIR,
|
|
47
|
-
cmd: deployEnv.CMD,
|
|
48
|
-
memory: deployEnv.MEMORY,
|
|
49
|
-
cron: deployEnv.CRON,
|
|
50
|
-
channel: argv.channel
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
56
|
}
|
|
54
57
|
yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
55
58
|
alias: 'i',
|
|
@@ -146,38 +149,44 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
146
149
|
type: 'boolean',
|
|
147
150
|
default: false
|
|
148
151
|
}), async argv => {
|
|
149
|
-
|
|
150
|
-
argv.channel = await EnvUtil.chooseChannel(process.cwd());
|
|
151
|
-
}
|
|
152
|
-
process.env.NODE_ENV = 'production';
|
|
153
|
-
const externals = castArray(argv.external || []).flatMap(item => item.split(',')).filter(Boolean);
|
|
154
|
-
const envFiles = EnvUtil.getFile(process.env.NODE_ENV, argv.channel);
|
|
155
|
-
const envMap = await EnvUtil.parseFileAsMap({
|
|
156
|
-
cwd: process.cwd(),
|
|
157
|
-
file: envFiles
|
|
158
|
-
});
|
|
159
|
-
envMap.NODE_ENV = 'production';
|
|
160
|
-
await TemplateUtil.init(process.cwd());
|
|
161
|
-
await generateManyIndex({
|
|
152
|
+
await EnvUtil.withChannel({
|
|
162
153
|
cwd: process.cwd(),
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
154
|
+
channel: argv.channel,
|
|
155
|
+
cb: async channel => {
|
|
156
|
+
process.env.NODE_ENV = 'production';
|
|
157
|
+
const externals = castArray(argv.external || []).flatMap(item => item.split(',')).filter(Boolean);
|
|
158
|
+
const envFiles = EnvUtil.getFile(process.env.NODE_ENV, channel);
|
|
159
|
+
const envMap = await EnvUtil.parseFileAsMap({
|
|
160
|
+
cwd: process.cwd(),
|
|
161
|
+
file: envFiles
|
|
162
|
+
});
|
|
163
|
+
envMap.NODE_ENV = 'production';
|
|
164
|
+
await TemplateUtil.init(process.cwd());
|
|
165
|
+
await generateManyIndex({
|
|
166
|
+
cwd: process.cwd(),
|
|
167
|
+
patterns: ['src/.x/*.ts'],
|
|
168
|
+
replaceFile: true,
|
|
169
|
+
onSuccess: filePath => {
|
|
170
|
+
console.log(`✔️ 索引文件已更新: ${filePath}`);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
await BuildUtil.build({
|
|
174
|
+
cwd: process.cwd(),
|
|
175
|
+
external: externals,
|
|
176
|
+
inlineEnvs: envMap,
|
|
177
|
+
minify: argv.minify,
|
|
178
|
+
noInstall: argv['no-install'],
|
|
179
|
+
channel: channel
|
|
180
|
+
});
|
|
181
|
+
console.log('构建成功');
|
|
182
|
+
if (argv.deploy) {
|
|
183
|
+
await deploy({
|
|
184
|
+
...argv,
|
|
185
|
+
channel
|
|
186
|
+
});
|
|
187
|
+
}
|
|
167
188
|
}
|
|
168
189
|
});
|
|
169
|
-
await BuildUtil.build({
|
|
170
|
-
cwd: process.cwd(),
|
|
171
|
-
external: externals,
|
|
172
|
-
inlineEnvs: envMap,
|
|
173
|
-
minify: argv.minify,
|
|
174
|
-
noInstall: argv['no-install'],
|
|
175
|
-
channel: argv.channel
|
|
176
|
-
});
|
|
177
|
-
console.log('构建成功');
|
|
178
|
-
if (argv.deploy) {
|
|
179
|
-
await deploy(argv);
|
|
180
|
-
}
|
|
181
190
|
}).command('api', '生成 API', _ => _.positional('channel', {
|
|
182
191
|
alias: 'h',
|
|
183
192
|
describe: '渠道',
|
|
@@ -203,31 +212,34 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
203
212
|
describe: '渠道',
|
|
204
213
|
type: 'string'
|
|
205
214
|
}), async argv => {
|
|
206
|
-
|
|
207
|
-
argv.channel = await EnvUtil.chooseChannel(process.cwd());
|
|
208
|
-
}
|
|
209
|
-
process.env.NODE_ENV = argv.production ? 'production' : 'development';
|
|
210
|
-
const envFiles = EnvUtil.getFile(process.env.NODE_ENV, argv.channel);
|
|
211
|
-
await EnvUtil.importFile({
|
|
215
|
+
await EnvUtil.withChannel({
|
|
212
216
|
cwd: process.cwd(),
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
217
|
+
channel: argv.channel,
|
|
218
|
+
cb: async channel => {
|
|
219
|
+
process.env.NODE_ENV = argv.production ? 'production' : 'development';
|
|
220
|
+
const envFiles = EnvUtil.getFile(process.env.NODE_ENV, channel);
|
|
221
|
+
await EnvUtil.importFile({
|
|
222
|
+
cwd: process.cwd(),
|
|
223
|
+
file: envFiles
|
|
224
|
+
});
|
|
225
|
+
// 之所以能成功是因为 Prisma 用的 dotenv 默认不会覆盖已经设置的环境变量
|
|
226
|
+
// https://github.com/motdotla/dotenv#override
|
|
227
|
+
process.env.DATABASE_URL = process.env.DATABASE_ACTION_URL || process.env.DATABASE_URL;
|
|
218
228
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
229
|
+
// 多 schema 文件兼容
|
|
230
|
+
// https://www.prisma.io/docs/orm/prisma-schema/overview/location#how-to-use-existing-prisma-cli-commands-with-multiple-prisma-schema-files
|
|
231
|
+
const schemaDir = path.join(process.cwd(), 'src/db/schema');
|
|
232
|
+
const isMultipleFiles = await fs.pathExists(schemaDir);
|
|
233
|
+
const schemaArg = isMultipleFiles ? 'src/db' : 'src/db/schema.prisma';
|
|
234
|
+
await execa('tnpx', ['prisma', ...argv._.slice(1), '--schema', schemaArg], {
|
|
235
|
+
cwd: process.cwd(),
|
|
236
|
+
stdio: 'inherit'
|
|
237
|
+
});
|
|
238
|
+
if (!argv.production) {
|
|
239
|
+
await TemplateUtil.initModels(process.cwd());
|
|
240
|
+
}
|
|
241
|
+
}
|
|
227
242
|
});
|
|
228
|
-
if (!argv.production) {
|
|
229
|
-
await TemplateUtil.initModels(process.cwd());
|
|
230
|
-
}
|
|
231
243
|
}).command('run [script]', '执行脚本', _ => _.positional('script', {
|
|
232
244
|
describe: '脚本',
|
|
233
245
|
type: 'string'
|
|
@@ -244,28 +256,31 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
244
256
|
describe: '使用 tsx 运行',
|
|
245
257
|
type: 'boolean'
|
|
246
258
|
}), async argv => {
|
|
247
|
-
|
|
248
|
-
argv.channel = await EnvUtil.chooseChannel(process.cwd());
|
|
249
|
-
}
|
|
250
|
-
process.env.NODE_ENV = argv.production ? 'production' : 'development';
|
|
251
|
-
const envFiles = EnvUtil.getFile(process.env.NODE_ENV, argv.channel);
|
|
252
|
-
await EnvUtil.importFile({
|
|
259
|
+
await EnvUtil.withChannel({
|
|
253
260
|
cwd: process.cwd(),
|
|
254
|
-
|
|
261
|
+
channel: argv.channel,
|
|
262
|
+
cb: async channel => {
|
|
263
|
+
process.env.NODE_ENV = argv.production ? 'production' : 'development';
|
|
264
|
+
const envFiles = EnvUtil.getFile(process.env.NODE_ENV, channel);
|
|
265
|
+
await EnvUtil.importFile({
|
|
266
|
+
cwd: process.cwd(),
|
|
267
|
+
file: envFiles
|
|
268
|
+
});
|
|
269
|
+
process.env.DATABASE_URL = process.env.DATABASE_ACTION_URL || process.env.DATABASE_URL;
|
|
270
|
+
if (!argv.script) {
|
|
271
|
+
await execa('tnpx', ['select-run'], {
|
|
272
|
+
cwd: process.cwd(),
|
|
273
|
+
stdio: 'inherit'
|
|
274
|
+
});
|
|
275
|
+
} else {
|
|
276
|
+
await DevUtil.runFile({
|
|
277
|
+
file: argv.script,
|
|
278
|
+
cwd: process.cwd(),
|
|
279
|
+
runner: argv.tsx ? 'tsx' : 'esbuild-register'
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
}
|
|
255
283
|
});
|
|
256
|
-
process.env.DATABASE_URL = process.env.DATABASE_ACTION_URL || process.env.DATABASE_URL;
|
|
257
|
-
if (!argv.script) {
|
|
258
|
-
await execa('tnpx', ['select-run'], {
|
|
259
|
-
cwd: process.cwd(),
|
|
260
|
-
stdio: 'inherit'
|
|
261
|
-
});
|
|
262
|
-
} else {
|
|
263
|
-
await DevUtil.runFile({
|
|
264
|
-
file: argv.script,
|
|
265
|
-
cwd: process.cwd(),
|
|
266
|
-
runner: argv.tsx ? 'tsx' : 'esbuild-register'
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
284
|
}).command('deploy [type]', '部署', _ => _.positional('type', {
|
|
270
285
|
describe: '类型',
|
|
271
286
|
type: 'string',
|
package/lib/cli/env_util.d.ts
CHANGED
|
@@ -9,7 +9,13 @@ export declare class EnvUtil {
|
|
|
9
9
|
static RE_NEWLINES: RegExp;
|
|
10
10
|
static NEWLINES_MATCH: RegExp;
|
|
11
11
|
static COMMENT_MATCH: RegExp;
|
|
12
|
+
static getAllChannel(cwd: string): Promise<string[]>;
|
|
12
13
|
static chooseChannel(cwd: string): Promise<string | undefined>;
|
|
14
|
+
static withChannel(options: {
|
|
15
|
+
cwd: string;
|
|
16
|
+
channel?: string;
|
|
17
|
+
cb: (channel: string | undefined) => any;
|
|
18
|
+
}): Promise<void>;
|
|
13
19
|
static getFile(env?: string, channel?: string, noBase?: boolean): string[];
|
|
14
20
|
static parseContent(src: string): ParsedEnv[];
|
|
15
21
|
static parseFile(options: {
|
package/lib/cli/env_util.js
CHANGED
|
@@ -5,16 +5,21 @@ import inquirer from 'inquirer';
|
|
|
5
5
|
import { dedent, escapeRegExp, isPlainObject, uniq } from 'vtils';
|
|
6
6
|
import { parse as yamlParse } from 'yaml';
|
|
7
7
|
export class EnvUtil {
|
|
8
|
-
static async
|
|
8
|
+
static async getAllChannel(cwd) {
|
|
9
9
|
const channelFiles = await globby(['.env@*'], {
|
|
10
10
|
cwd: cwd,
|
|
11
11
|
onlyFiles: true,
|
|
12
12
|
absolute: false
|
|
13
13
|
});
|
|
14
14
|
if (channelFiles.length === 0) {
|
|
15
|
-
return
|
|
15
|
+
return [];
|
|
16
16
|
}
|
|
17
17
|
const channels = uniq(channelFiles.map(channel => channel.split('@').pop().split('.')[0]));
|
|
18
|
+
return channels;
|
|
19
|
+
}
|
|
20
|
+
static async chooseChannel(cwd) {
|
|
21
|
+
const channels = await EnvUtil.getAllChannel(cwd);
|
|
22
|
+
if (channels.length === 0) return undefined;
|
|
18
23
|
if (channels.length === 1) return channels[0];
|
|
19
24
|
const res = await inquirer.prompt([{
|
|
20
25
|
name: 'channel',
|
|
@@ -24,6 +29,24 @@ export class EnvUtil {
|
|
|
24
29
|
}]);
|
|
25
30
|
return res.channel || undefined;
|
|
26
31
|
}
|
|
32
|
+
static async withChannel(options) {
|
|
33
|
+
if (options.channel === '_') {
|
|
34
|
+
const channel = await EnvUtil.chooseChannel(options.cwd);
|
|
35
|
+
console.log(`========= ${channel} =========`);
|
|
36
|
+
await options.cb(channel);
|
|
37
|
+
} else if (options.channel === '@') {
|
|
38
|
+
const channels = await EnvUtil.getAllChannel(options.cwd);
|
|
39
|
+
for (const channel of channels) {
|
|
40
|
+
console.log(`========= ${channel} =========`);
|
|
41
|
+
await options.cb(channel);
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
if (options.channel) {
|
|
45
|
+
console.log(`========= ${options.channel} =========`);
|
|
46
|
+
}
|
|
47
|
+
await options.cb(options.channel);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
27
50
|
static getFile(env, channel, noBase) {
|
|
28
51
|
const file = noBase ? [] : ['.env'];
|
|
29
52
|
if (!noBase && channel) {
|