@jayfong/x-server 2.74.1 → 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 +131 -107
- package/lib/_cjs/cli/env_util.js +25 -2
- package/lib/cli/cli.js +131 -107
- 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
|
@@ -15,6 +15,48 @@ var _deploy_util = require("./deploy_util");
|
|
|
15
15
|
var _dev_util = require("./dev_util");
|
|
16
16
|
var _env_util = require("./env_util");
|
|
17
17
|
var _template_util = require("./template_util");
|
|
18
|
+
async function deploy(argv) {
|
|
19
|
+
await _env_util.EnvUtil.withChannel({
|
|
20
|
+
cwd: process.cwd(),
|
|
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
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
18
60
|
_yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
19
61
|
alias: 'i',
|
|
20
62
|
describe: '额外需要生成的索引文件',
|
|
@@ -104,36 +146,50 @@ _yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
104
146
|
alias: 'h',
|
|
105
147
|
describe: '渠道',
|
|
106
148
|
type: 'string'
|
|
149
|
+
}).positional('deploy', {
|
|
150
|
+
alias: 'd',
|
|
151
|
+
describe: '构建完是否部署',
|
|
152
|
+
type: 'boolean',
|
|
153
|
+
default: false
|
|
107
154
|
}), async argv => {
|
|
108
|
-
|
|
109
|
-
argv.channel = await _env_util.EnvUtil.chooseChannel(process.cwd());
|
|
110
|
-
}
|
|
111
|
-
process.env.NODE_ENV = 'production';
|
|
112
|
-
const externals = (0, _vtils.castArray)(argv.external || []).flatMap(item => item.split(',')).filter(Boolean);
|
|
113
|
-
const envFiles = _env_util.EnvUtil.getFile(process.env.NODE_ENV, argv.channel);
|
|
114
|
-
const envMap = await _env_util.EnvUtil.parseFileAsMap({
|
|
115
|
-
cwd: process.cwd(),
|
|
116
|
-
file: envFiles
|
|
117
|
-
});
|
|
118
|
-
envMap.NODE_ENV = 'production';
|
|
119
|
-
await _template_util.TemplateUtil.init(process.cwd());
|
|
120
|
-
await (0, _vscodeGenerateIndexStandalone.generateManyIndex)({
|
|
155
|
+
await _env_util.EnvUtil.withChannel({
|
|
121
156
|
cwd: process.cwd(),
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
+
}
|
|
126
191
|
}
|
|
127
192
|
});
|
|
128
|
-
await _build_util.BuildUtil.build({
|
|
129
|
-
cwd: process.cwd(),
|
|
130
|
-
external: externals,
|
|
131
|
-
inlineEnvs: envMap,
|
|
132
|
-
minify: argv.minify,
|
|
133
|
-
noInstall: argv['no-install'],
|
|
134
|
-
channel: argv.channel
|
|
135
|
-
});
|
|
136
|
-
console.log('构建成功');
|
|
137
193
|
}).command('api', '生成 API', _ => _.positional('channel', {
|
|
138
194
|
alias: 'h',
|
|
139
195
|
describe: '渠道',
|
|
@@ -159,31 +215,34 @@ _yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
159
215
|
describe: '渠道',
|
|
160
216
|
type: 'string'
|
|
161
217
|
}), async argv => {
|
|
162
|
-
|
|
163
|
-
argv.channel = await _env_util.EnvUtil.chooseChannel(process.cwd());
|
|
164
|
-
}
|
|
165
|
-
process.env.NODE_ENV = argv.production ? 'production' : 'development';
|
|
166
|
-
const envFiles = _env_util.EnvUtil.getFile(process.env.NODE_ENV, argv.channel);
|
|
167
|
-
await _env_util.EnvUtil.importFile({
|
|
218
|
+
await _env_util.EnvUtil.withChannel({
|
|
168
219
|
cwd: process.cwd(),
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
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;
|
|
174
231
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
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
|
+
}
|
|
183
245
|
});
|
|
184
|
-
if (!argv.production) {
|
|
185
|
-
await _template_util.TemplateUtil.initModels(process.cwd());
|
|
186
|
-
}
|
|
187
246
|
}).command('run [script]', '执行脚本', _ => _.positional('script', {
|
|
188
247
|
describe: '脚本',
|
|
189
248
|
type: 'string'
|
|
@@ -200,28 +259,31 @@ _yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
200
259
|
describe: '使用 tsx 运行',
|
|
201
260
|
type: 'boolean'
|
|
202
261
|
}), async argv => {
|
|
203
|
-
|
|
204
|
-
argv.channel = await _env_util.EnvUtil.chooseChannel(process.cwd());
|
|
205
|
-
}
|
|
206
|
-
process.env.NODE_ENV = argv.production ? 'production' : 'development';
|
|
207
|
-
const envFiles = _env_util.EnvUtil.getFile(process.env.NODE_ENV, argv.channel);
|
|
208
|
-
await _env_util.EnvUtil.importFile({
|
|
262
|
+
await _env_util.EnvUtil.withChannel({
|
|
209
263
|
cwd: process.cwd(),
|
|
210
|
-
|
|
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
|
+
}
|
|
211
286
|
});
|
|
212
|
-
process.env.DATABASE_URL = process.env.DATABASE_ACTION_URL || process.env.DATABASE_URL;
|
|
213
|
-
if (!argv.script) {
|
|
214
|
-
await (0, _execa.default)('tnpx', ['select-run'], {
|
|
215
|
-
cwd: process.cwd(),
|
|
216
|
-
stdio: 'inherit'
|
|
217
|
-
});
|
|
218
|
-
} else {
|
|
219
|
-
await _dev_util.DevUtil.runFile({
|
|
220
|
-
file: argv.script,
|
|
221
|
-
cwd: process.cwd(),
|
|
222
|
-
runner: argv.tsx ? 'tsx' : 'esbuild-register'
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
287
|
}).command('deploy [type]', '部署', _ => _.positional('type', {
|
|
226
288
|
describe: '类型',
|
|
227
289
|
type: 'string',
|
|
@@ -230,42 +292,4 @@ _yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
230
292
|
alias: 'h',
|
|
231
293
|
describe: '渠道',
|
|
232
294
|
type: 'string'
|
|
233
|
-
}),
|
|
234
|
-
if (argv.channel === '_') {
|
|
235
|
-
argv.channel = await _env_util.EnvUtil.chooseChannel(process.cwd());
|
|
236
|
-
}
|
|
237
|
-
const deployEnvFiles = _env_util.EnvUtil.getFile('deploy', argv.channel, true);
|
|
238
|
-
const deployEnv = await _env_util.EnvUtil.parseFileAsMap({
|
|
239
|
-
cwd: process.cwd(),
|
|
240
|
-
file: deployEnvFiles
|
|
241
|
-
});
|
|
242
|
-
if (argv.type === 'env') {
|
|
243
|
-
const appEnvFiles = _env_util.EnvUtil.getFile('production', argv.channel);
|
|
244
|
-
const appEnv = await _env_util.EnvUtil.parseFileAsMap({
|
|
245
|
-
cwd: process.cwd(),
|
|
246
|
-
file: appEnvFiles
|
|
247
|
-
});
|
|
248
|
-
await _deploy_util.DeployUtil.deployEnv({
|
|
249
|
-
host: deployEnv.HOST,
|
|
250
|
-
user: deployEnv.USER,
|
|
251
|
-
key: deployEnv.KEY,
|
|
252
|
-
pass: deployEnv.PASSWORD,
|
|
253
|
-
token: appEnv.APP_TOKEN,
|
|
254
|
-
port: appEnv.APP_PORT,
|
|
255
|
-
env: appEnv
|
|
256
|
-
});
|
|
257
|
-
} else {
|
|
258
|
-
await _deploy_util.DeployUtil.deploy({
|
|
259
|
-
cwd: process.cwd(),
|
|
260
|
-
host: deployEnv.HOST,
|
|
261
|
-
user: deployEnv.USER,
|
|
262
|
-
key: deployEnv.KEY,
|
|
263
|
-
pass: deployEnv.PASSWORD,
|
|
264
|
-
dir: deployEnv.DIR,
|
|
265
|
-
cmd: deployEnv.CMD,
|
|
266
|
-
memory: deployEnv.MEMORY,
|
|
267
|
-
cron: deployEnv.CRON,
|
|
268
|
-
channel: argv.channel
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
}).parse();
|
|
295
|
+
}), deploy).parse();
|
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
|
@@ -12,6 +12,48 @@ import { DeployUtil } from "./deploy_util";
|
|
|
12
12
|
import { DevUtil } from "./dev_util";
|
|
13
13
|
import { EnvUtil } from "./env_util";
|
|
14
14
|
import { TemplateUtil } from "./template_util";
|
|
15
|
+
async function deploy(argv) {
|
|
16
|
+
await EnvUtil.withChannel({
|
|
17
|
+
cwd: process.cwd(),
|
|
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
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
15
57
|
yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
16
58
|
alias: 'i',
|
|
17
59
|
describe: '额外需要生成的索引文件',
|
|
@@ -101,36 +143,50 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
101
143
|
alias: 'h',
|
|
102
144
|
describe: '渠道',
|
|
103
145
|
type: 'string'
|
|
146
|
+
}).positional('deploy', {
|
|
147
|
+
alias: 'd',
|
|
148
|
+
describe: '构建完是否部署',
|
|
149
|
+
type: 'boolean',
|
|
150
|
+
default: false
|
|
104
151
|
}), async argv => {
|
|
105
|
-
|
|
106
|
-
argv.channel = await EnvUtil.chooseChannel(process.cwd());
|
|
107
|
-
}
|
|
108
|
-
process.env.NODE_ENV = 'production';
|
|
109
|
-
const externals = castArray(argv.external || []).flatMap(item => item.split(',')).filter(Boolean);
|
|
110
|
-
const envFiles = EnvUtil.getFile(process.env.NODE_ENV, argv.channel);
|
|
111
|
-
const envMap = await EnvUtil.parseFileAsMap({
|
|
112
|
-
cwd: process.cwd(),
|
|
113
|
-
file: envFiles
|
|
114
|
-
});
|
|
115
|
-
envMap.NODE_ENV = 'production';
|
|
116
|
-
await TemplateUtil.init(process.cwd());
|
|
117
|
-
await generateManyIndex({
|
|
152
|
+
await EnvUtil.withChannel({
|
|
118
153
|
cwd: process.cwd(),
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
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
|
+
}
|
|
123
188
|
}
|
|
124
189
|
});
|
|
125
|
-
await BuildUtil.build({
|
|
126
|
-
cwd: process.cwd(),
|
|
127
|
-
external: externals,
|
|
128
|
-
inlineEnvs: envMap,
|
|
129
|
-
minify: argv.minify,
|
|
130
|
-
noInstall: argv['no-install'],
|
|
131
|
-
channel: argv.channel
|
|
132
|
-
});
|
|
133
|
-
console.log('构建成功');
|
|
134
190
|
}).command('api', '生成 API', _ => _.positional('channel', {
|
|
135
191
|
alias: 'h',
|
|
136
192
|
describe: '渠道',
|
|
@@ -156,31 +212,34 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
156
212
|
describe: '渠道',
|
|
157
213
|
type: 'string'
|
|
158
214
|
}), async argv => {
|
|
159
|
-
|
|
160
|
-
argv.channel = await EnvUtil.chooseChannel(process.cwd());
|
|
161
|
-
}
|
|
162
|
-
process.env.NODE_ENV = argv.production ? 'production' : 'development';
|
|
163
|
-
const envFiles = EnvUtil.getFile(process.env.NODE_ENV, argv.channel);
|
|
164
|
-
await EnvUtil.importFile({
|
|
215
|
+
await EnvUtil.withChannel({
|
|
165
216
|
cwd: process.cwd(),
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
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;
|
|
171
228
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
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
|
+
}
|
|
180
242
|
});
|
|
181
|
-
if (!argv.production) {
|
|
182
|
-
await TemplateUtil.initModels(process.cwd());
|
|
183
|
-
}
|
|
184
243
|
}).command('run [script]', '执行脚本', _ => _.positional('script', {
|
|
185
244
|
describe: '脚本',
|
|
186
245
|
type: 'string'
|
|
@@ -197,28 +256,31 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
197
256
|
describe: '使用 tsx 运行',
|
|
198
257
|
type: 'boolean'
|
|
199
258
|
}), async argv => {
|
|
200
|
-
|
|
201
|
-
argv.channel = await EnvUtil.chooseChannel(process.cwd());
|
|
202
|
-
}
|
|
203
|
-
process.env.NODE_ENV = argv.production ? 'production' : 'development';
|
|
204
|
-
const envFiles = EnvUtil.getFile(process.env.NODE_ENV, argv.channel);
|
|
205
|
-
await EnvUtil.importFile({
|
|
259
|
+
await EnvUtil.withChannel({
|
|
206
260
|
cwd: process.cwd(),
|
|
207
|
-
|
|
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
|
+
}
|
|
208
283
|
});
|
|
209
|
-
process.env.DATABASE_URL = process.env.DATABASE_ACTION_URL || process.env.DATABASE_URL;
|
|
210
|
-
if (!argv.script) {
|
|
211
|
-
await execa('tnpx', ['select-run'], {
|
|
212
|
-
cwd: process.cwd(),
|
|
213
|
-
stdio: 'inherit'
|
|
214
|
-
});
|
|
215
|
-
} else {
|
|
216
|
-
await DevUtil.runFile({
|
|
217
|
-
file: argv.script,
|
|
218
|
-
cwd: process.cwd(),
|
|
219
|
-
runner: argv.tsx ? 'tsx' : 'esbuild-register'
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
284
|
}).command('deploy [type]', '部署', _ => _.positional('type', {
|
|
223
285
|
describe: '类型',
|
|
224
286
|
type: 'string',
|
|
@@ -227,42 +289,4 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
227
289
|
alias: 'h',
|
|
228
290
|
describe: '渠道',
|
|
229
291
|
type: 'string'
|
|
230
|
-
}),
|
|
231
|
-
if (argv.channel === '_') {
|
|
232
|
-
argv.channel = await EnvUtil.chooseChannel(process.cwd());
|
|
233
|
-
}
|
|
234
|
-
const deployEnvFiles = EnvUtil.getFile('deploy', argv.channel, true);
|
|
235
|
-
const deployEnv = await EnvUtil.parseFileAsMap({
|
|
236
|
-
cwd: process.cwd(),
|
|
237
|
-
file: deployEnvFiles
|
|
238
|
-
});
|
|
239
|
-
if (argv.type === 'env') {
|
|
240
|
-
const appEnvFiles = EnvUtil.getFile('production', argv.channel);
|
|
241
|
-
const appEnv = await EnvUtil.parseFileAsMap({
|
|
242
|
-
cwd: process.cwd(),
|
|
243
|
-
file: appEnvFiles
|
|
244
|
-
});
|
|
245
|
-
await DeployUtil.deployEnv({
|
|
246
|
-
host: deployEnv.HOST,
|
|
247
|
-
user: deployEnv.USER,
|
|
248
|
-
key: deployEnv.KEY,
|
|
249
|
-
pass: deployEnv.PASSWORD,
|
|
250
|
-
token: appEnv.APP_TOKEN,
|
|
251
|
-
port: appEnv.APP_PORT,
|
|
252
|
-
env: appEnv
|
|
253
|
-
});
|
|
254
|
-
} else {
|
|
255
|
-
await DeployUtil.deploy({
|
|
256
|
-
cwd: process.cwd(),
|
|
257
|
-
host: deployEnv.HOST,
|
|
258
|
-
user: deployEnv.USER,
|
|
259
|
-
key: deployEnv.KEY,
|
|
260
|
-
pass: deployEnv.PASSWORD,
|
|
261
|
-
dir: deployEnv.DIR,
|
|
262
|
-
cmd: deployEnv.CMD,
|
|
263
|
-
memory: deployEnv.MEMORY,
|
|
264
|
-
cron: deployEnv.CRON,
|
|
265
|
-
channel: argv.channel
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
}).parse();
|
|
292
|
+
}), deploy).parse();
|
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) {
|