@jayfong/x-server 2.23.0 → 2.24.1
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 +13 -14
- package/lib/_cjs/cli/env_util.js +27 -108
- package/lib/cli/build_util.d.ts +1 -2
- package/lib/cli/build_util.js +3 -6
- package/lib/cli/cli.js +13 -14
- package/lib/cli/env_util.d.ts +5 -6
- package/lib/cli/env_util.js +28 -109
- 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])};`), `process.env["X_SERVER_ENVS"]=${JSON.stringify(JSON.stringify(options.inlineEnvs || {}))};`].join('\n')
|
|
81
78
|
},
|
|
82
79
|
plugins: [{
|
|
83
80
|
name: 'extract-assets',
|
package/lib/_cjs/cli/cli.js
CHANGED
|
@@ -25,7 +25,6 @@ _yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
25
25
|
describe: '使用 tsx 运行',
|
|
26
26
|
type: 'boolean'
|
|
27
27
|
}).positional('env', {
|
|
28
|
-
alias: 'e',
|
|
29
28
|
describe: '环境变量文件',
|
|
30
29
|
type: 'string',
|
|
31
30
|
default: 'development'
|
|
@@ -58,7 +57,7 @@ _yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
58
57
|
});
|
|
59
58
|
_env_util.EnvUtil.outputTypes({
|
|
60
59
|
cwd: process.cwd(),
|
|
61
|
-
file: '.env',
|
|
60
|
+
file: ['.env'],
|
|
62
61
|
outFile: 'env.d.ts'
|
|
63
62
|
});
|
|
64
63
|
(0, _vscodeGenerateIndexStandalone.generateManyIndex)({
|
|
@@ -93,18 +92,18 @@ _yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
93
92
|
describe: '是否不本地安装外部依赖',
|
|
94
93
|
type: 'boolean',
|
|
95
94
|
default: false
|
|
95
|
+
}).positional('env', {
|
|
96
|
+
describe: '环境变量文件',
|
|
97
|
+
type: 'string',
|
|
98
|
+
default: 'production'
|
|
96
99
|
}), async argv => {
|
|
97
100
|
process.env.NODE_ENV = 'production';
|
|
98
101
|
const externals = (0, _vtils.castArray)(argv.external || []).map(item => item.split(',')).flat().filter(Boolean);
|
|
99
|
-
const
|
|
102
|
+
const envMap = await _env_util.EnvUtil.parseFileAsMap({
|
|
100
103
|
cwd: process.cwd(),
|
|
101
|
-
file: '.env'
|
|
102
|
-
});
|
|
103
|
-
envs.unshift({
|
|
104
|
-
key: 'NODE_ENV',
|
|
105
|
-
value: 'production',
|
|
106
|
-
comment: ''
|
|
104
|
+
file: ['.env', `.env.${argv.env}`]
|
|
107
105
|
});
|
|
106
|
+
envMap.NODE_ENV = 'production';
|
|
108
107
|
await _template_util.TemplateUtil.init(process.cwd());
|
|
109
108
|
await (0, _vscodeGenerateIndexStandalone.generateManyIndex)({
|
|
110
109
|
cwd: process.cwd(),
|
|
@@ -117,7 +116,7 @@ _yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
117
116
|
await _build_util.BuildUtil.build({
|
|
118
117
|
cwd: process.cwd(),
|
|
119
118
|
external: externals,
|
|
120
|
-
inlineEnvs:
|
|
119
|
+
inlineEnvs: envMap,
|
|
121
120
|
minify: argv.minify,
|
|
122
121
|
noInstall: argv['no-install']
|
|
123
122
|
});
|
|
@@ -133,7 +132,7 @@ _yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
133
132
|
process.env.NODE_ENV = argv.production ? 'production' : 'development';
|
|
134
133
|
await _env_util.EnvUtil.importFile({
|
|
135
134
|
cwd: process.cwd(),
|
|
136
|
-
file: '.env'
|
|
135
|
+
file: ['.env', `.env.${process.env.NODE_ENV}`]
|
|
137
136
|
});
|
|
138
137
|
// 之所以能成功是因为 Prisma 用的 dotenv 默认不会覆盖已经设置的环境变量
|
|
139
138
|
// https://github.com/motdotla/dotenv#override
|
|
@@ -160,7 +159,7 @@ _yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
160
159
|
process.env.NODE_ENV = argv.production ? 'production' : 'development';
|
|
161
160
|
await _env_util.EnvUtil.importFile({
|
|
162
161
|
cwd: process.cwd(),
|
|
163
|
-
file: '.env'
|
|
162
|
+
file: ['.env', `.env.${process.env.NODE_ENV}`]
|
|
164
163
|
});
|
|
165
164
|
process.env.DATABASE_URL = process.env.DATABASE_ACTION_URL || process.env.DATABASE_URL;
|
|
166
165
|
if (!argv.script) {
|
|
@@ -182,12 +181,12 @@ _yargs.default.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
182
181
|
}), async argv => {
|
|
183
182
|
const deployEnv = await _env_util.EnvUtil.parseFileAsMap({
|
|
184
183
|
cwd: process.cwd(),
|
|
185
|
-
file: '.env.deploy'
|
|
184
|
+
file: ['.env.deploy']
|
|
186
185
|
});
|
|
187
186
|
if (argv.type === 'env') {
|
|
188
187
|
const appEnv = await _env_util.EnvUtil.parseFileAsMap({
|
|
189
188
|
cwd: process.cwd(),
|
|
190
|
-
file: '.env'
|
|
189
|
+
file: ['.env', '.env.production']
|
|
191
190
|
});
|
|
192
191
|
await _deploy_util.DeployUtil.deployEnv({
|
|
193
192
|
host: deployEnv.HOST,
|
package/lib/_cjs/cli/env_util.js
CHANGED
|
@@ -8,114 +8,38 @@ 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
|
}
|
|
@@ -123,15 +47,10 @@ class EnvUtil {
|
|
|
123
47
|
}
|
|
124
48
|
static async importFile(options) {
|
|
125
49
|
const envsObj = {};
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
});
|
|
131
|
-
for (const env of envs) {
|
|
132
|
-
envsObj[env.key] = env.value;
|
|
133
|
-
process.env[env.key] = env.value;
|
|
134
|
-
}
|
|
50
|
+
const envs = await EnvUtil.parseFile(options);
|
|
51
|
+
for (const env of envs) {
|
|
52
|
+
envsObj[env.key] = env.value;
|
|
53
|
+
process.env[env.key] = env.value;
|
|
135
54
|
}
|
|
136
55
|
process.env.X_SERVER_ENVS = JSON.stringify({
|
|
137
56
|
// @ts-ignore
|
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])};`), `process.env["X_SERVER_ENVS"]=${JSON.stringify(JSON.stringify(options.inlineEnvs || {}))};`].join('\n')
|
|
75
72
|
},
|
|
76
73
|
plugins: [{
|
|
77
74
|
name: 'extract-assets',
|
package/lib/cli/cli.js
CHANGED
|
@@ -22,7 +22,6 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
22
22
|
describe: '使用 tsx 运行',
|
|
23
23
|
type: 'boolean'
|
|
24
24
|
}).positional('env', {
|
|
25
|
-
alias: 'e',
|
|
26
25
|
describe: '环境变量文件',
|
|
27
26
|
type: 'string',
|
|
28
27
|
default: 'development'
|
|
@@ -55,7 +54,7 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
55
54
|
});
|
|
56
55
|
EnvUtil.outputTypes({
|
|
57
56
|
cwd: process.cwd(),
|
|
58
|
-
file: '.env',
|
|
57
|
+
file: ['.env'],
|
|
59
58
|
outFile: 'env.d.ts'
|
|
60
59
|
});
|
|
61
60
|
generateManyIndex({
|
|
@@ -90,18 +89,18 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
90
89
|
describe: '是否不本地安装外部依赖',
|
|
91
90
|
type: 'boolean',
|
|
92
91
|
default: false
|
|
92
|
+
}).positional('env', {
|
|
93
|
+
describe: '环境变量文件',
|
|
94
|
+
type: 'string',
|
|
95
|
+
default: 'production'
|
|
93
96
|
}), async argv => {
|
|
94
97
|
process.env.NODE_ENV = 'production';
|
|
95
98
|
const externals = castArray(argv.external || []).map(item => item.split(',')).flat().filter(Boolean);
|
|
96
|
-
const
|
|
99
|
+
const envMap = await EnvUtil.parseFileAsMap({
|
|
97
100
|
cwd: process.cwd(),
|
|
98
|
-
file: '.env'
|
|
99
|
-
});
|
|
100
|
-
envs.unshift({
|
|
101
|
-
key: 'NODE_ENV',
|
|
102
|
-
value: 'production',
|
|
103
|
-
comment: ''
|
|
101
|
+
file: ['.env', `.env.${argv.env}`]
|
|
104
102
|
});
|
|
103
|
+
envMap.NODE_ENV = 'production';
|
|
105
104
|
await TemplateUtil.init(process.cwd());
|
|
106
105
|
await generateManyIndex({
|
|
107
106
|
cwd: process.cwd(),
|
|
@@ -114,7 +113,7 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
114
113
|
await BuildUtil.build({
|
|
115
114
|
cwd: process.cwd(),
|
|
116
115
|
external: externals,
|
|
117
|
-
inlineEnvs:
|
|
116
|
+
inlineEnvs: envMap,
|
|
118
117
|
minify: argv.minify,
|
|
119
118
|
noInstall: argv['no-install']
|
|
120
119
|
});
|
|
@@ -130,7 +129,7 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
130
129
|
process.env.NODE_ENV = argv.production ? 'production' : 'development';
|
|
131
130
|
await EnvUtil.importFile({
|
|
132
131
|
cwd: process.cwd(),
|
|
133
|
-
file: '.env'
|
|
132
|
+
file: ['.env', `.env.${process.env.NODE_ENV}`]
|
|
134
133
|
});
|
|
135
134
|
// 之所以能成功是因为 Prisma 用的 dotenv 默认不会覆盖已经设置的环境变量
|
|
136
135
|
// https://github.com/motdotla/dotenv#override
|
|
@@ -157,7 +156,7 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
157
156
|
process.env.NODE_ENV = argv.production ? 'production' : 'development';
|
|
158
157
|
await EnvUtil.importFile({
|
|
159
158
|
cwd: process.cwd(),
|
|
160
|
-
file: '.env'
|
|
159
|
+
file: ['.env', `.env.${process.env.NODE_ENV}`]
|
|
161
160
|
});
|
|
162
161
|
process.env.DATABASE_URL = process.env.DATABASE_ACTION_URL || process.env.DATABASE_URL;
|
|
163
162
|
if (!argv.script) {
|
|
@@ -179,12 +178,12 @@ yargs.command('dev', '开始开发', _ => _.positional('index', {
|
|
|
179
178
|
}), async argv => {
|
|
180
179
|
const deployEnv = await EnvUtil.parseFileAsMap({
|
|
181
180
|
cwd: process.cwd(),
|
|
182
|
-
file: '.env.deploy'
|
|
181
|
+
file: ['.env.deploy']
|
|
183
182
|
});
|
|
184
183
|
if (argv.type === 'env') {
|
|
185
184
|
const appEnv = await EnvUtil.parseFileAsMap({
|
|
186
185
|
cwd: process.cwd(),
|
|
187
|
-
file: '.env'
|
|
186
|
+
file: ['.env', '.env.production']
|
|
188
187
|
});
|
|
189
188
|
await DeployUtil.deployEnv({
|
|
190
189
|
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,116 +1,40 @@
|
|
|
1
1
|
import fs from 'fs-extra';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import {
|
|
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
|
}
|
|
@@ -118,15 +42,10 @@ export class EnvUtil {
|
|
|
118
42
|
}
|
|
119
43
|
static async importFile(options) {
|
|
120
44
|
const envsObj = {};
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
});
|
|
126
|
-
for (const env of envs) {
|
|
127
|
-
envsObj[env.key] = env.value;
|
|
128
|
-
process.env[env.key] = env.value;
|
|
129
|
-
}
|
|
45
|
+
const envs = await EnvUtil.parseFile(options);
|
|
46
|
+
for (const env of envs) {
|
|
47
|
+
envsObj[env.key] = env.value;
|
|
48
|
+
process.env[env.key] = env.value;
|
|
130
49
|
}
|
|
131
50
|
process.env.X_SERVER_ENVS = JSON.stringify({
|
|
132
51
|
// @ts-ignore
|