@jayfong/x-server 2.22.5 → 2.24.0
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/build_util.js +4 -7
- package/lib/_cjs/cli/cli.js +22 -16
- package/lib/_cjs/cli/env_util.js +24 -100
- package/lib/cli/build_util.d.ts +1 -2
- package/lib/cli/build_util.js +3 -6
- package/lib/cli/cli.js +22 -16
- package/lib/cli/env_util.d.ts +5 -6
- package/lib/cli/env_util.js +25 -101
- package/package.json +1 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
4
3
|
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
|
|
4
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
5
5
|
exports.__esModule = true;
|
|
6
6
|
exports.BuildUtil = void 0;
|
|
7
|
-
var esbuild = _interopRequireWildcard(require("esbuild"));
|
|
8
7
|
var _compressing = _interopRequireDefault(require("compressing"));
|
|
8
|
+
var esbuild = _interopRequireWildcard(require("esbuild"));
|
|
9
9
|
var _execa = _interopRequireDefault(require("execa"));
|
|
10
10
|
var _fsExtra = _interopRequireDefault(require("fs-extra"));
|
|
11
11
|
var _globby = _interopRequireDefault(require("globby"));
|
|
@@ -13,7 +13,7 @@ var _nodePath = _interopRequireDefault(require("node:path"));
|
|
|
13
13
|
var _vtils = require("vtils");
|
|
14
14
|
class BuildUtil {
|
|
15
15
|
static async build(options) {
|
|
16
|
-
var _options$minify
|
|
16
|
+
var _options$minify;
|
|
17
17
|
const mainFile = _nodePath.default.join(options.cwd, 'src/main.ts');
|
|
18
18
|
const pkgFile = _nodePath.default.join(options.cwd, 'package.json');
|
|
19
19
|
const pkgContent = await _fsExtra.default.readJson(pkgFile);
|
|
@@ -74,10 +74,7 @@ class BuildUtil {
|
|
|
74
74
|
sourcemap: false,
|
|
75
75
|
treeShaking: true,
|
|
76
76
|
banner: {
|
|
77
|
-
js: `${`;${(
|
|
78
|
-
res[item.key] = item.value;
|
|
79
|
-
return res;
|
|
80
|
-
}, {})))};`
|
|
77
|
+
js: `${`;${Object.keys(options.inlineEnvs || {}).map(key => `process.env[${JSON.stringify(key)}]=${JSON.stringify(options.inlineEnvs[key])}`).join(';')}`};process.env.X_SERVER_ENVS=${JSON.stringify(JSON.stringify(options.inlineEnvs || {}))};`
|
|
81
78
|
},
|
|
82
79
|
plugins: [{
|
|
83
80
|
name: 'extract-assets',
|
package/lib/_cjs/cli/cli.js
CHANGED
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
|
|
5
5
|
var _chokidar = _interopRequireDefault(require("chokidar"));
|
|
6
6
|
var _execa = _interopRequireDefault(require("execa"));
|
|
7
|
+
var _vscodeGenerateIndexStandalone = require("vscode-generate-index-standalone");
|
|
8
|
+
var _vtils = require("vtils");
|
|
7
9
|
var _yargs = _interopRequireDefault(require("yargs"));
|
|
8
10
|
var _api_generator = require("./api_generator");
|
|
9
11
|
var _build_util = require("./build_util");
|
|
10
|
-
var _vtils = require("vtils");
|
|
11
12
|
var _deploy_util = require("./deploy_util");
|
|
12
13
|
var _dev_util = require("./dev_util");
|
|
13
14
|
var _env_util = require("./env_util");
|
|
14
|
-
var _vscodeGenerateIndexStandalone = require("vscode-generate-index-standalone");
|
|
15
15
|
var _template_util = require("./template_util");
|
|
16
16
|
_yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
17
17
|
alias: 'i',
|
|
@@ -24,6 +24,11 @@ _yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
24
24
|
}).positional('tsx', {
|
|
25
25
|
describe: '使用 tsx 运行',
|
|
26
26
|
type: 'boolean'
|
|
27
|
+
}).positional('env', {
|
|
28
|
+
alias: 'e',
|
|
29
|
+
describe: '环境变量文件',
|
|
30
|
+
type: 'string',
|
|
31
|
+
default: 'development'
|
|
27
32
|
}), async argv => {
|
|
28
33
|
process.env.NODE_ENV = 'development';
|
|
29
34
|
let lastRun;
|
|
@@ -49,11 +54,11 @@ _yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
49
54
|
watcher.on('all', (0, _vtils.debounce)(async () => {
|
|
50
55
|
await _env_util.EnvUtil.importFile({
|
|
51
56
|
cwd: process.cwd(),
|
|
52
|
-
file: '.env'
|
|
57
|
+
file: ['.env', `.env.${argv.env}`]
|
|
53
58
|
});
|
|
54
59
|
_env_util.EnvUtil.outputTypes({
|
|
55
60
|
cwd: process.cwd(),
|
|
56
|
-
file: '.env',
|
|
61
|
+
file: ['.env'],
|
|
57
62
|
outFile: 'env.d.ts'
|
|
58
63
|
});
|
|
59
64
|
(0, _vscodeGenerateIndexStandalone.generateManyIndex)({
|
|
@@ -88,18 +93,19 @@ _yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
88
93
|
describe: '是否不本地安装外部依赖',
|
|
89
94
|
type: 'boolean',
|
|
90
95
|
default: false
|
|
96
|
+
}).positional('env', {
|
|
97
|
+
alias: 'e',
|
|
98
|
+
describe: '环境变量文件',
|
|
99
|
+
type: 'string',
|
|
100
|
+
default: 'production'
|
|
91
101
|
}), async argv => {
|
|
92
102
|
process.env.NODE_ENV = 'production';
|
|
93
103
|
const externals = (0, _vtils.castArray)(argv.external || []).map(item => item.split(',')).flat().filter(Boolean);
|
|
94
|
-
const
|
|
104
|
+
const envMap = await _env_util.EnvUtil.parseFileAsMap({
|
|
95
105
|
cwd: process.cwd(),
|
|
96
|
-
file: '.env'
|
|
97
|
-
});
|
|
98
|
-
envs.unshift({
|
|
99
|
-
key: 'NODE_ENV',
|
|
100
|
-
value: 'production',
|
|
101
|
-
comment: ''
|
|
106
|
+
file: ['.env', `.env.${argv.env}`]
|
|
102
107
|
});
|
|
108
|
+
envMap.NODE_ENV = 'production';
|
|
103
109
|
await _template_util.TemplateUtil.init(process.cwd());
|
|
104
110
|
await (0, _vscodeGenerateIndexStandalone.generateManyIndex)({
|
|
105
111
|
cwd: process.cwd(),
|
|
@@ -112,7 +118,7 @@ _yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
112
118
|
await _build_util.BuildUtil.build({
|
|
113
119
|
cwd: process.cwd(),
|
|
114
120
|
external: externals,
|
|
115
|
-
inlineEnvs:
|
|
121
|
+
inlineEnvs: envMap,
|
|
116
122
|
minify: argv.minify,
|
|
117
123
|
noInstall: argv['no-install']
|
|
118
124
|
});
|
|
@@ -128,7 +134,7 @@ _yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
128
134
|
process.env.NODE_ENV = argv.production ? 'production' : 'development';
|
|
129
135
|
await _env_util.EnvUtil.importFile({
|
|
130
136
|
cwd: process.cwd(),
|
|
131
|
-
file: '.env'
|
|
137
|
+
file: ['.env', `.env.${process.env.NODE_ENV}`]
|
|
132
138
|
});
|
|
133
139
|
// 之所以能成功是因为 Prisma 用的 dotenv 默认不会覆盖已经设置的环境变量
|
|
134
140
|
// https://github.com/motdotla/dotenv#override
|
|
@@ -155,7 +161,7 @@ _yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
155
161
|
process.env.NODE_ENV = argv.production ? 'production' : 'development';
|
|
156
162
|
await _env_util.EnvUtil.importFile({
|
|
157
163
|
cwd: process.cwd(),
|
|
158
|
-
file: '.env'
|
|
164
|
+
file: ['.env', `.env.${process.env.NODE_ENV}`]
|
|
159
165
|
});
|
|
160
166
|
process.env.DATABASE_URL = process.env.DATABASE_ACTION_URL || process.env.DATABASE_URL;
|
|
161
167
|
if (!argv.script) {
|
|
@@ -177,12 +183,12 @@ _yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
177
183
|
}), async argv => {
|
|
178
184
|
const deployEnv = await _env_util.EnvUtil.parseFileAsMap({
|
|
179
185
|
cwd: process.cwd(),
|
|
180
|
-
file: '.env.deploy'
|
|
186
|
+
file: ['.env.deploy']
|
|
181
187
|
});
|
|
182
188
|
if (argv.type === 'env') {
|
|
183
189
|
const appEnv = await _env_util.EnvUtil.parseFileAsMap({
|
|
184
190
|
cwd: process.cwd(),
|
|
185
|
-
file: '.env'
|
|
191
|
+
file: ['.env', '.env.production']
|
|
186
192
|
});
|
|
187
193
|
await _deploy_util.DeployUtil.deployEnv({
|
|
188
194
|
host: deployEnv.HOST,
|
package/lib/_cjs/cli/env_util.js
CHANGED
|
@@ -8,122 +8,46 @@ var _nodePath = _interopRequireDefault(require("node:path"));
|
|
|
8
8
|
var _vtils = require("vtils");
|
|
9
9
|
var _yaml = require("yaml");
|
|
10
10
|
class EnvUtil {
|
|
11
|
-
static
|
|
12
|
-
if (typeof value === 'string') {
|
|
13
|
-
if (value.includes(' || ')) {
|
|
14
|
-
const [devValue, prodValue] = value.split(/\s+\|\|\s+/);
|
|
15
|
-
return (0, _vtils.devOrProd)(() => EnvUtil.normalizeValue(devValue), () => EnvUtil.normalizeValue(prodValue));
|
|
16
|
-
}
|
|
17
|
-
return value === 'true' ? true : value === 'false' ? false : value.startsWith('[') && value.endsWith(']') || value.startsWith('{') && value.endsWith('}') ? JSON.parse(value) : (0, _vtils.isNumeric)(value) ? Number(value) : value;
|
|
18
|
-
} else if (value && typeof value === 'object') {
|
|
19
|
-
if (value.dev != null && value.prod != null) {
|
|
20
|
-
return (0, _vtils.devOrProd)(() => value.dev, () => value.prod);
|
|
21
|
-
}
|
|
22
|
-
return value;
|
|
23
|
-
}
|
|
24
|
-
return value;
|
|
25
|
-
}
|
|
26
|
-
static parseContent(src, isYaml = false) {
|
|
11
|
+
static parseContent(src) {
|
|
27
12
|
const envs = [];
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
comment: ((_src$match = src.match(new RegExp(`((#\\s*(.+?)\\s*[\\r\\n]+)+)\\s*${(0, _vtils.escapeRegExp)(key)}:`))) == null ? void 0 : _src$match[1].replace(/^#/gm, '').trim()) || ''
|
|
36
|
-
});
|
|
13
|
+
const envObj = (0, _yaml.parse)(src);
|
|
14
|
+
Object.keys(envObj).forEach(key => {
|
|
15
|
+
var _src$match;
|
|
16
|
+
envs.push({
|
|
17
|
+
key: key,
|
|
18
|
+
value: envObj[key],
|
|
19
|
+
comment: ((_src$match = src.match(new RegExp(`((#\\s*(.+?)\\s*[\\r\\n]+)+)\\s*${(0, _vtils.escapeRegExp)(key)}:`))) == null ? void 0 : _src$match[1].replace(/^#/gm, '').trim()) || ''
|
|
37
20
|
});
|
|
38
|
-
}
|
|
39
|
-
// https://github.com/andreialecu/dotenv/blob/feat-multiline/lib/main.js
|
|
40
|
-
const multilineLineBreaks = true;
|
|
41
|
-
|
|
42
|
-
// convert Buffers before splitting into lines and processing
|
|
43
|
-
const lines = src.split(EnvUtil.NEWLINES_MATCH);
|
|
44
|
-
let lastComment = '';
|
|
45
|
-
for (let idx = 0; idx < lines.length; idx++) {
|
|
46
|
-
let line = lines[idx];
|
|
47
|
-
|
|
48
|
-
// matching "KEY' and 'VAL' in 'KEY=VAL'
|
|
49
|
-
const keyValueArr = line.match(EnvUtil.RE_INI_KEY_VAL);
|
|
50
|
-
// matched?
|
|
51
|
-
if (keyValueArr != null) {
|
|
52
|
-
const key = keyValueArr[1];
|
|
53
|
-
// default undefined or missing values to empty string
|
|
54
|
-
let val = keyValueArr[2] || '';
|
|
55
|
-
let end = val.length - 1;
|
|
56
|
-
const isDoubleQuoted = val[0] === '"' && val[end] === '"';
|
|
57
|
-
const isSingleQuoted = val[0] === "'" && val[end] === "'";
|
|
58
|
-
const isMultilineDoubleQuoted = val[0] === '"' && (val.length === 1 || val[end] !== '"');
|
|
59
|
-
const isMultilineSingleQuoted = val[0] === "'" && (val.length === 1 || val[end] !== "'");
|
|
60
|
-
|
|
61
|
-
// if parsing line breaks and the value starts with a quote
|
|
62
|
-
if (multilineLineBreaks && (isMultilineDoubleQuoted || isMultilineSingleQuoted)) {
|
|
63
|
-
const quoteChar = isMultilineDoubleQuoted ? '"' : "'";
|
|
64
|
-
val = val.substring(1);
|
|
65
|
-
while (idx++ < lines.length - 1) {
|
|
66
|
-
line = lines[idx];
|
|
67
|
-
end = line.length - 1;
|
|
68
|
-
if (line[end] === quoteChar) {
|
|
69
|
-
val += EnvUtil.NEWLINE + line.substring(0, end);
|
|
70
|
-
break;
|
|
71
|
-
}
|
|
72
|
-
val += EnvUtil.NEWLINE + line;
|
|
73
|
-
}
|
|
74
|
-
val = (0, _vtils.dedent)(val);
|
|
75
|
-
// if single or double quoted, remove quotes
|
|
76
|
-
} else if (isSingleQuoted || isDoubleQuoted) {
|
|
77
|
-
val = val.substring(1, end);
|
|
78
|
-
|
|
79
|
-
// if double quoted, expand newlines
|
|
80
|
-
if (isDoubleQuoted) {
|
|
81
|
-
val = val.replace(EnvUtil.RE_NEWLINES, EnvUtil.NEWLINE);
|
|
82
|
-
}
|
|
83
|
-
val = (0, _vtils.dedent)(val);
|
|
84
|
-
} else {
|
|
85
|
-
// remove surrounding whitespace
|
|
86
|
-
val = (0, _vtils.dedent)(val).trim();
|
|
87
|
-
}
|
|
88
|
-
envs.push({
|
|
89
|
-
key: key,
|
|
90
|
-
value: EnvUtil.normalizeValue(val),
|
|
91
|
-
comment: lastComment
|
|
92
|
-
});
|
|
93
|
-
lastComment = '';
|
|
94
|
-
} else {
|
|
95
|
-
const commentArr = line.match(EnvUtil.COMMENT_MATCH);
|
|
96
|
-
if (commentArr) {
|
|
97
|
-
lastComment = commentArr[1];
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
21
|
+
});
|
|
102
22
|
return envs;
|
|
103
23
|
}
|
|
104
24
|
static async parseFile(options) {
|
|
105
|
-
const
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
25
|
+
const envMap = {};
|
|
26
|
+
for (const file of options.file) {
|
|
27
|
+
const envYmlFile = _nodePath.default.join(options.cwd, `${file}.yml`);
|
|
28
|
+
const envYamlFile = _nodePath.default.join(options.cwd, `${file}.yaml`);
|
|
29
|
+
const envFile = (await _fsExtra.default.pathExists(envYmlFile)) ? envYmlFile : (await _fsExtra.default.pathExists(envYamlFile)) ? envYamlFile : '';
|
|
30
|
+
if (envFile) {
|
|
31
|
+
const envContent = await _fsExtra.default.readFile(envFile, 'utf-8');
|
|
32
|
+
const envs = EnvUtil.parseContent(envContent);
|
|
33
|
+
envs.forEach(env => {
|
|
34
|
+
envMap[env.key] = env;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
113
37
|
}
|
|
114
|
-
return
|
|
38
|
+
return Object.values(envMap);
|
|
115
39
|
}
|
|
116
40
|
static async parseFileAsMap(options) {
|
|
117
|
-
const envs = await EnvUtil.parseFile(options);
|
|
118
41
|
const envsObj = {};
|
|
42
|
+
const envs = await EnvUtil.parseFile(options);
|
|
119
43
|
for (const env of envs) {
|
|
120
44
|
envsObj[env.key] = env.value;
|
|
121
45
|
}
|
|
122
46
|
return envsObj;
|
|
123
47
|
}
|
|
124
48
|
static async importFile(options) {
|
|
125
|
-
const envs = await EnvUtil.parseFile(options);
|
|
126
49
|
const envsObj = {};
|
|
50
|
+
const envs = await EnvUtil.parseFile(options);
|
|
127
51
|
for (const env of envs) {
|
|
128
52
|
envsObj[env.key] = env.value;
|
|
129
53
|
process.env[env.key] = env.value;
|
package/lib/cli/build_util.d.ts
CHANGED
package/lib/cli/build_util.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as esbuild from 'esbuild';
|
|
2
1
|
import compressing from 'compressing';
|
|
2
|
+
import * as esbuild from 'esbuild';
|
|
3
3
|
import exec from 'execa';
|
|
4
4
|
import fs from 'fs-extra';
|
|
5
5
|
import globby from 'globby';
|
|
@@ -7,7 +7,7 @@ import path from 'node:path';
|
|
|
7
7
|
import { dedent, uniq } from 'vtils';
|
|
8
8
|
export class BuildUtil {
|
|
9
9
|
static async build(options) {
|
|
10
|
-
var _options$minify
|
|
10
|
+
var _options$minify;
|
|
11
11
|
const mainFile = path.join(options.cwd, 'src/main.ts');
|
|
12
12
|
const pkgFile = path.join(options.cwd, 'package.json');
|
|
13
13
|
const pkgContent = await fs.readJson(pkgFile);
|
|
@@ -68,10 +68,7 @@ export class BuildUtil {
|
|
|
68
68
|
sourcemap: false,
|
|
69
69
|
treeShaking: true,
|
|
70
70
|
banner: {
|
|
71
|
-
js: `${`;${(
|
|
72
|
-
res[item.key] = item.value;
|
|
73
|
-
return res;
|
|
74
|
-
}, {})))};`
|
|
71
|
+
js: `${`;${Object.keys(options.inlineEnvs || {}).map(key => `process.env[${JSON.stringify(key)}]=${JSON.stringify(options.inlineEnvs[key])}`).join(';')}`};process.env.X_SERVER_ENVS=${JSON.stringify(JSON.stringify(options.inlineEnvs || {}))};`
|
|
75
72
|
},
|
|
76
73
|
plugins: [{
|
|
77
74
|
name: 'extract-assets',
|
package/lib/cli/cli.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import chokidar from 'chokidar';
|
|
3
3
|
import execa from 'execa';
|
|
4
|
+
import { generateManyIndex } from 'vscode-generate-index-standalone';
|
|
5
|
+
import { castArray, debounce } from 'vtils';
|
|
4
6
|
import yargs from 'yargs';
|
|
5
7
|
import { ApiGenerator } from "./api_generator";
|
|
6
8
|
import { BuildUtil } from "./build_util";
|
|
7
|
-
import { castArray, debounce } from 'vtils';
|
|
8
9
|
import { DeployUtil } from "./deploy_util";
|
|
9
10
|
import { DevUtil } from "./dev_util";
|
|
10
11
|
import { EnvUtil } from "./env_util";
|
|
11
|
-
import { generateManyIndex } from 'vscode-generate-index-standalone';
|
|
12
12
|
import { TemplateUtil } from "./template_util";
|
|
13
13
|
yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
14
14
|
alias: 'i',
|
|
@@ -21,6 +21,11 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
21
21
|
}).positional('tsx', {
|
|
22
22
|
describe: '使用 tsx 运行',
|
|
23
23
|
type: 'boolean'
|
|
24
|
+
}).positional('env', {
|
|
25
|
+
alias: 'e',
|
|
26
|
+
describe: '环境变量文件',
|
|
27
|
+
type: 'string',
|
|
28
|
+
default: 'development'
|
|
24
29
|
}), async argv => {
|
|
25
30
|
process.env.NODE_ENV = 'development';
|
|
26
31
|
let lastRun;
|
|
@@ -46,11 +51,11 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
46
51
|
watcher.on('all', debounce(async () => {
|
|
47
52
|
await EnvUtil.importFile({
|
|
48
53
|
cwd: process.cwd(),
|
|
49
|
-
file: '.env'
|
|
54
|
+
file: ['.env', `.env.${argv.env}`]
|
|
50
55
|
});
|
|
51
56
|
EnvUtil.outputTypes({
|
|
52
57
|
cwd: process.cwd(),
|
|
53
|
-
file: '.env',
|
|
58
|
+
file: ['.env'],
|
|
54
59
|
outFile: 'env.d.ts'
|
|
55
60
|
});
|
|
56
61
|
generateManyIndex({
|
|
@@ -85,18 +90,19 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
85
90
|
describe: '是否不本地安装外部依赖',
|
|
86
91
|
type: 'boolean',
|
|
87
92
|
default: false
|
|
93
|
+
}).positional('env', {
|
|
94
|
+
alias: 'e',
|
|
95
|
+
describe: '环境变量文件',
|
|
96
|
+
type: 'string',
|
|
97
|
+
default: 'production'
|
|
88
98
|
}), async argv => {
|
|
89
99
|
process.env.NODE_ENV = 'production';
|
|
90
100
|
const externals = castArray(argv.external || []).map(item => item.split(',')).flat().filter(Boolean);
|
|
91
|
-
const
|
|
101
|
+
const envMap = await EnvUtil.parseFileAsMap({
|
|
92
102
|
cwd: process.cwd(),
|
|
93
|
-
file: '.env'
|
|
94
|
-
});
|
|
95
|
-
envs.unshift({
|
|
96
|
-
key: 'NODE_ENV',
|
|
97
|
-
value: 'production',
|
|
98
|
-
comment: ''
|
|
103
|
+
file: ['.env', `.env.${argv.env}`]
|
|
99
104
|
});
|
|
105
|
+
envMap.NODE_ENV = 'production';
|
|
100
106
|
await TemplateUtil.init(process.cwd());
|
|
101
107
|
await generateManyIndex({
|
|
102
108
|
cwd: process.cwd(),
|
|
@@ -109,7 +115,7 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
109
115
|
await BuildUtil.build({
|
|
110
116
|
cwd: process.cwd(),
|
|
111
117
|
external: externals,
|
|
112
|
-
inlineEnvs:
|
|
118
|
+
inlineEnvs: envMap,
|
|
113
119
|
minify: argv.minify,
|
|
114
120
|
noInstall: argv['no-install']
|
|
115
121
|
});
|
|
@@ -125,7 +131,7 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
125
131
|
process.env.NODE_ENV = argv.production ? 'production' : 'development';
|
|
126
132
|
await EnvUtil.importFile({
|
|
127
133
|
cwd: process.cwd(),
|
|
128
|
-
file: '.env'
|
|
134
|
+
file: ['.env', `.env.${process.env.NODE_ENV}`]
|
|
129
135
|
});
|
|
130
136
|
// 之所以能成功是因为 Prisma 用的 dotenv 默认不会覆盖已经设置的环境变量
|
|
131
137
|
// https://github.com/motdotla/dotenv#override
|
|
@@ -152,7 +158,7 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
152
158
|
process.env.NODE_ENV = argv.production ? 'production' : 'development';
|
|
153
159
|
await EnvUtil.importFile({
|
|
154
160
|
cwd: process.cwd(),
|
|
155
|
-
file: '.env'
|
|
161
|
+
file: ['.env', `.env.${process.env.NODE_ENV}`]
|
|
156
162
|
});
|
|
157
163
|
process.env.DATABASE_URL = process.env.DATABASE_ACTION_URL || process.env.DATABASE_URL;
|
|
158
164
|
if (!argv.script) {
|
|
@@ -174,12 +180,12 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
174
180
|
}), async argv => {
|
|
175
181
|
const deployEnv = await EnvUtil.parseFileAsMap({
|
|
176
182
|
cwd: process.cwd(),
|
|
177
|
-
file: '.env.deploy'
|
|
183
|
+
file: ['.env.deploy']
|
|
178
184
|
});
|
|
179
185
|
if (argv.type === 'env') {
|
|
180
186
|
const appEnv = await EnvUtil.parseFileAsMap({
|
|
181
187
|
cwd: process.cwd(),
|
|
182
|
-
file: '.env'
|
|
188
|
+
file: ['.env', '.env.production']
|
|
183
189
|
});
|
|
184
190
|
await DeployUtil.deployEnv({
|
|
185
191
|
host: deployEnv.HOST,
|
package/lib/cli/env_util.d.ts
CHANGED
|
@@ -9,24 +9,23 @@ export declare class EnvUtil {
|
|
|
9
9
|
static RE_NEWLINES: RegExp;
|
|
10
10
|
static NEWLINES_MATCH: RegExp;
|
|
11
11
|
static COMMENT_MATCH: RegExp;
|
|
12
|
-
static
|
|
13
|
-
static parseContent(src: string, isYaml?: boolean): ParsedEnv[];
|
|
12
|
+
static parseContent(src: string): ParsedEnv[];
|
|
14
13
|
static parseFile(options: {
|
|
15
14
|
cwd: string;
|
|
16
|
-
file: string;
|
|
15
|
+
file: string[];
|
|
17
16
|
}): Promise<ParsedEnv[]>;
|
|
18
17
|
static parseFileAsMap(options: {
|
|
19
18
|
cwd: string;
|
|
20
|
-
file: string;
|
|
19
|
+
file: string[];
|
|
21
20
|
}): Promise<Record<string, any>>;
|
|
22
21
|
static importFile(options: {
|
|
23
22
|
cwd: string;
|
|
24
|
-
file: string;
|
|
23
|
+
file: string[];
|
|
25
24
|
}): Promise<void>;
|
|
26
25
|
static makeTypes(envs: ParsedEnv[]): string;
|
|
27
26
|
static outputTypes(options: {
|
|
28
27
|
cwd: string;
|
|
29
|
-
file: string;
|
|
28
|
+
file: string[];
|
|
30
29
|
outFile: string;
|
|
31
30
|
}): Promise<void>;
|
|
32
31
|
private static getTypesFromValue;
|
package/lib/cli/env_util.js
CHANGED
|
@@ -1,124 +1,48 @@
|
|
|
1
1
|
import fs from 'fs-extra';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { dedent,
|
|
3
|
+
import { dedent, escapeRegExp, isPlainObject } from 'vtils';
|
|
4
4
|
import { parse as yamlParse } from 'yaml';
|
|
5
5
|
export class EnvUtil {
|
|
6
|
-
static
|
|
7
|
-
if (typeof value === 'string') {
|
|
8
|
-
if (value.includes(' || ')) {
|
|
9
|
-
const [devValue, prodValue] = value.split(/\s+\|\|\s+/);
|
|
10
|
-
return devOrProd(() => EnvUtil.normalizeValue(devValue), () => EnvUtil.normalizeValue(prodValue));
|
|
11
|
-
}
|
|
12
|
-
return value === 'true' ? true : value === 'false' ? false : value.startsWith('[') && value.endsWith(']') || value.startsWith('{') && value.endsWith('}') ? JSON.parse(value) : isNumeric(value) ? Number(value) : value;
|
|
13
|
-
} else if (value && typeof value === 'object') {
|
|
14
|
-
if (value.dev != null && value.prod != null) {
|
|
15
|
-
return devOrProd(() => value.dev, () => value.prod);
|
|
16
|
-
}
|
|
17
|
-
return value;
|
|
18
|
-
}
|
|
19
|
-
return value;
|
|
20
|
-
}
|
|
21
|
-
static parseContent(src, isYaml = false) {
|
|
6
|
+
static parseContent(src) {
|
|
22
7
|
const envs = [];
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
comment: ((_src$match = src.match(new RegExp(`((#\\s*(.+?)\\s*[\\r\\n]+)+)\\s*${escapeRegExp(key)}:`))) == null ? void 0 : _src$match[1].replace(/^#/gm, '').trim()) || ''
|
|
31
|
-
});
|
|
8
|
+
const envObj = yamlParse(src);
|
|
9
|
+
Object.keys(envObj).forEach(key => {
|
|
10
|
+
var _src$match;
|
|
11
|
+
envs.push({
|
|
12
|
+
key: key,
|
|
13
|
+
value: envObj[key],
|
|
14
|
+
comment: ((_src$match = src.match(new RegExp(`((#\\s*(.+?)\\s*[\\r\\n]+)+)\\s*${escapeRegExp(key)}:`))) == null ? void 0 : _src$match[1].replace(/^#/gm, '').trim()) || ''
|
|
32
15
|
});
|
|
33
|
-
}
|
|
34
|
-
// https://github.com/andreialecu/dotenv/blob/feat-multiline/lib/main.js
|
|
35
|
-
const multilineLineBreaks = true;
|
|
36
|
-
|
|
37
|
-
// convert Buffers before splitting into lines and processing
|
|
38
|
-
const lines = src.split(EnvUtil.NEWLINES_MATCH);
|
|
39
|
-
let lastComment = '';
|
|
40
|
-
for (let idx = 0; idx < lines.length; idx++) {
|
|
41
|
-
let line = lines[idx];
|
|
42
|
-
|
|
43
|
-
// matching "KEY' and 'VAL' in 'KEY=VAL'
|
|
44
|
-
const keyValueArr = line.match(EnvUtil.RE_INI_KEY_VAL);
|
|
45
|
-
// matched?
|
|
46
|
-
if (keyValueArr != null) {
|
|
47
|
-
const key = keyValueArr[1];
|
|
48
|
-
// default undefined or missing values to empty string
|
|
49
|
-
let val = keyValueArr[2] || '';
|
|
50
|
-
let end = val.length - 1;
|
|
51
|
-
const isDoubleQuoted = val[0] === '"' && val[end] === '"';
|
|
52
|
-
const isSingleQuoted = val[0] === "'" && val[end] === "'";
|
|
53
|
-
const isMultilineDoubleQuoted = val[0] === '"' && (val.length === 1 || val[end] !== '"');
|
|
54
|
-
const isMultilineSingleQuoted = val[0] === "'" && (val.length === 1 || val[end] !== "'");
|
|
55
|
-
|
|
56
|
-
// if parsing line breaks and the value starts with a quote
|
|
57
|
-
if (multilineLineBreaks && (isMultilineDoubleQuoted || isMultilineSingleQuoted)) {
|
|
58
|
-
const quoteChar = isMultilineDoubleQuoted ? '"' : "'";
|
|
59
|
-
val = val.substring(1);
|
|
60
|
-
while (idx++ < lines.length - 1) {
|
|
61
|
-
line = lines[idx];
|
|
62
|
-
end = line.length - 1;
|
|
63
|
-
if (line[end] === quoteChar) {
|
|
64
|
-
val += EnvUtil.NEWLINE + line.substring(0, end);
|
|
65
|
-
break;
|
|
66
|
-
}
|
|
67
|
-
val += EnvUtil.NEWLINE + line;
|
|
68
|
-
}
|
|
69
|
-
val = dedent(val);
|
|
70
|
-
// if single or double quoted, remove quotes
|
|
71
|
-
} else if (isSingleQuoted || isDoubleQuoted) {
|
|
72
|
-
val = val.substring(1, end);
|
|
73
|
-
|
|
74
|
-
// if double quoted, expand newlines
|
|
75
|
-
if (isDoubleQuoted) {
|
|
76
|
-
val = val.replace(EnvUtil.RE_NEWLINES, EnvUtil.NEWLINE);
|
|
77
|
-
}
|
|
78
|
-
val = dedent(val);
|
|
79
|
-
} else {
|
|
80
|
-
// remove surrounding whitespace
|
|
81
|
-
val = dedent(val).trim();
|
|
82
|
-
}
|
|
83
|
-
envs.push({
|
|
84
|
-
key: key,
|
|
85
|
-
value: EnvUtil.normalizeValue(val),
|
|
86
|
-
comment: lastComment
|
|
87
|
-
});
|
|
88
|
-
lastComment = '';
|
|
89
|
-
} else {
|
|
90
|
-
const commentArr = line.match(EnvUtil.COMMENT_MATCH);
|
|
91
|
-
if (commentArr) {
|
|
92
|
-
lastComment = commentArr[1];
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
16
|
+
});
|
|
97
17
|
return envs;
|
|
98
18
|
}
|
|
99
19
|
static async parseFile(options) {
|
|
100
|
-
const
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
20
|
+
const envMap = {};
|
|
21
|
+
for (const file of options.file) {
|
|
22
|
+
const envYmlFile = path.join(options.cwd, `${file}.yml`);
|
|
23
|
+
const envYamlFile = path.join(options.cwd, `${file}.yaml`);
|
|
24
|
+
const envFile = (await fs.pathExists(envYmlFile)) ? envYmlFile : (await fs.pathExists(envYamlFile)) ? envYamlFile : '';
|
|
25
|
+
if (envFile) {
|
|
26
|
+
const envContent = await fs.readFile(envFile, 'utf-8');
|
|
27
|
+
const envs = EnvUtil.parseContent(envContent);
|
|
28
|
+
envs.forEach(env => {
|
|
29
|
+
envMap[env.key] = env;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
108
32
|
}
|
|
109
|
-
return
|
|
33
|
+
return Object.values(envMap);
|
|
110
34
|
}
|
|
111
35
|
static async parseFileAsMap(options) {
|
|
112
|
-
const envs = await EnvUtil.parseFile(options);
|
|
113
36
|
const envsObj = {};
|
|
37
|
+
const envs = await EnvUtil.parseFile(options);
|
|
114
38
|
for (const env of envs) {
|
|
115
39
|
envsObj[env.key] = env.value;
|
|
116
40
|
}
|
|
117
41
|
return envsObj;
|
|
118
42
|
}
|
|
119
43
|
static async importFile(options) {
|
|
120
|
-
const envs = await EnvUtil.parseFile(options);
|
|
121
44
|
const envsObj = {};
|
|
45
|
+
const envs = await EnvUtil.parseFile(options);
|
|
122
46
|
for (const env of envs) {
|
|
123
47
|
envsObj[env.key] = env.value;
|
|
124
48
|
process.env[env.key] = env.value;
|