@dbcube/cli 5.2.3 → 5.2.5
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/package.json +3 -3
- package/src/commands/doctor.js +5 -4
- package/src/commands/help.js +1 -1
- package/src/commands/init.js +5 -4
- package/src/commands/run/database/create/addDatabaseConfig.js +1 -2
- package/src/commands/run/download.js +2 -4
- package/src/commands/update.js +3 -5
- package/src/commands/version.js +1 -1
- package/src/utils/ConfigFileUtils.js +121 -56
- package/src/utils/EnvLoader.js +94 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dbcube/cli",
|
|
3
|
-
"version": "5.2.
|
|
3
|
+
"version": "5.2.5",
|
|
4
4
|
"main": "src/index.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dbcube": "node src/index.js"
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
"access": "public"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@dbcube/schema-builder": "^5.2.
|
|
31
|
+
"@dbcube/schema-builder": "^5.2.5",
|
|
32
32
|
"@inquirer/prompts": "^8.5.2",
|
|
33
33
|
"alwait": "^1.0.0",
|
|
34
34
|
"chalk": "4.1.2",
|
|
35
|
-
"dbcube": "^5.2.
|
|
35
|
+
"dbcube": "^5.2.5",
|
|
36
36
|
"dotenv": "^17.4.2",
|
|
37
37
|
"fs-extra": "^11.3.5",
|
|
38
38
|
"glob": "^13.0.6",
|
package/src/commands/doctor.js
CHANGED
|
@@ -21,13 +21,14 @@ async function main() {
|
|
|
21
21
|
if (major >= 16) ok(`Node.js ${process.versions.node}`);
|
|
22
22
|
else { fail(`Node.js ${process.versions.node} — DBCube requires >= 16`); problems++; }
|
|
23
23
|
|
|
24
|
-
// 2. Config file
|
|
25
|
-
const configPath =
|
|
24
|
+
// 2. Config file (.js o .cjs — getConfigPath prefiere .cjs en proyectos ESM)
|
|
25
|
+
const configPath = ConfigFileUtils.getConfigPath();
|
|
26
|
+
const configName = path.basename(configPath);
|
|
26
27
|
if (!fs.existsSync(configPath)) {
|
|
27
|
-
fail(
|
|
28
|
+
fail(`${configName} not found — run: npx dbcube init`);
|
|
28
29
|
problems++;
|
|
29
30
|
} else {
|
|
30
|
-
ok(
|
|
31
|
+
ok(`${configName} found`);
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
// 3. Configured databases
|
package/src/commands/help.js
CHANGED
|
@@ -46,7 +46,7 @@ async function showHelp() {
|
|
|
46
46
|
console.log(` ${chalk.yellow('run download')} ${chalk.white('Download binaries interactively')}`);
|
|
47
47
|
console.log(` ${chalk.yellow('run download <engine>')} ${chalk.white('Download specific engine (latest version)')}`);
|
|
48
48
|
console.log(` ${chalk.yellow('run download <engine> <ver>')} ${chalk.white('Download specific engine version')}`);
|
|
49
|
-
console.log(` ${chalk.gray(' Engines:')} query-engine, schema-engine
|
|
49
|
+
console.log(` ${chalk.gray(' Engines:')} query-engine, schema-engine\n`);
|
|
50
50
|
|
|
51
51
|
console.log(`${chalk.cyan.bold('UTILITY COMMANDS:')}`);
|
|
52
52
|
console.log(` ${chalk.yellow('version, --version, -v')} ${chalk.white('Show CLI version information')}`);
|
package/src/commands/init.js
CHANGED
|
@@ -11,13 +11,14 @@ async function main() {
|
|
|
11
11
|
const root = process.cwd();
|
|
12
12
|
console.log(`\n💚 ${chalk.green('Initializing DBCube project...')}\n`);
|
|
13
13
|
|
|
14
|
-
// 1. dbcube.config.js
|
|
15
|
-
const configPath =
|
|
14
|
+
// 1. dbcube.config.(js|cjs) — getConfigPath elige .cjs en proyectos ESM
|
|
15
|
+
const configPath = ConfigFileUtils.getConfigPath();
|
|
16
|
+
const configName = path.basename(configPath);
|
|
16
17
|
if (fs.existsSync(configPath)) {
|
|
17
|
-
console.log(` ${chalk.yellow('•')}
|
|
18
|
+
console.log(` ${chalk.yellow('•')} ${configName} already exists — skipped`);
|
|
18
19
|
} else {
|
|
19
20
|
ConfigFileUtils.crearArchivoConfig(configPath);
|
|
20
|
-
console.log(` ${chalk.green('✓')}
|
|
21
|
+
console.log(` ${chalk.green('✓')} ${configName} created`);
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
// 2. dbcube/ directory
|
|
@@ -21,8 +21,7 @@ async function addDatabaseConfiguration(databaseName = null, motor = null) {
|
|
|
21
21
|
databaseName = await input({
|
|
22
22
|
message: 'Nombre de referencia a la base de datos:',
|
|
23
23
|
validate: (value) => {
|
|
24
|
-
const
|
|
25
|
-
const configPath = path.join(rootPath, 'dbcube.config.js');
|
|
24
|
+
const configPath = ConfigFileUtils.getConfigPath();
|
|
26
25
|
const getconfig = require(configPath);
|
|
27
26
|
const config = new Config();
|
|
28
27
|
getconfig(config);
|
|
@@ -14,8 +14,7 @@ const args = process.argv.slice(2);
|
|
|
14
14
|
|
|
15
15
|
const SUPPORTED_BINARIES = {
|
|
16
16
|
'query-engine': 'query',
|
|
17
|
-
'schema-engine': 'schema'
|
|
18
|
-
'sqlite-engine': 'sqlite'
|
|
17
|
+
'schema-engine': 'schema'
|
|
19
18
|
};
|
|
20
19
|
|
|
21
20
|
const PLATFORM_MAP = {
|
|
@@ -234,8 +233,7 @@ async function interactiveMode() {
|
|
|
234
233
|
message: 'Selecciona el binario a descargar:',
|
|
235
234
|
choices: [
|
|
236
235
|
{ name: 'Query Engine', value: 'query-engine' },
|
|
237
|
-
{ name: 'Schema Engine', value: 'schema-engine' }
|
|
238
|
-
{ name: 'SQLite Engine', value: 'sqlite-engine' }
|
|
236
|
+
{ name: 'Schema Engine', value: 'schema-engine' }
|
|
239
237
|
]
|
|
240
238
|
});
|
|
241
239
|
|
package/src/commands/update.js
CHANGED
|
@@ -9,14 +9,12 @@ const unzipper = require('unzipper');
|
|
|
9
9
|
|
|
10
10
|
const VERSION_URLS = {
|
|
11
11
|
'query-engine': 'https://raw.githubusercontent.com/Dbcube/binaries/main/query-engines.json',
|
|
12
|
-
'schema-engine': 'https://raw.githubusercontent.com/Dbcube/binaries/main/schema-engines.json'
|
|
13
|
-
'sqlite-engine': 'https://raw.githubusercontent.com/Dbcube/binaries/main/sqlite-engines.json'
|
|
12
|
+
'schema-engine': 'https://raw.githubusercontent.com/Dbcube/binaries/main/schema-engines.json'
|
|
14
13
|
};
|
|
15
14
|
|
|
16
15
|
const BINARY_PREFIX_MAP = {
|
|
17
16
|
'query-engine': 'query',
|
|
18
|
-
'schema-engine': 'schema'
|
|
19
|
-
'sqlite-engine': 'sqlite'
|
|
17
|
+
'schema-engine': 'schema'
|
|
20
18
|
};
|
|
21
19
|
|
|
22
20
|
const PLATFORM_MAP = {
|
|
@@ -332,7 +330,7 @@ async function main() {
|
|
|
332
330
|
console.log(chalk.blue('\n🔄 Dbcube Update - Check and Update Binaries\n'));
|
|
333
331
|
|
|
334
332
|
const binDir = getBinDir();
|
|
335
|
-
const binaries = ['query-engine', 'schema-engine'
|
|
333
|
+
const binaries = ['query-engine', 'schema-engine'];
|
|
336
334
|
|
|
337
335
|
const spinner = ora('Checking versions...').start();
|
|
338
336
|
|
package/src/commands/version.js
CHANGED
|
@@ -18,7 +18,7 @@ function findEngineVersions() {
|
|
|
18
18
|
const engines = {};
|
|
19
19
|
try {
|
|
20
20
|
for (const f of fs.readdirSync(binDir)) {
|
|
21
|
-
const m = f.match(/^(query-engine|schema-engine
|
|
21
|
+
const m = f.match(/^(query-engine|schema-engine)-v([\d.]+)-/);
|
|
22
22
|
if (m) engines[m[1]] = `v${m[2]}`;
|
|
23
23
|
}
|
|
24
24
|
} catch { /* no binaries downloaded yet */ }
|
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
+
const EnvLoader = require('./EnvLoader');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Detecta si el proyecto está marcado como ESM ("type": "module" en
|
|
7
|
+
* package.json), lo que hace que dbcube.config.js (CommonJS) no se pueda
|
|
8
|
+
* cargar con require(). Devuelve true si es ESM.
|
|
9
|
+
*/
|
|
10
|
+
function projectIsESM() {
|
|
11
|
+
try {
|
|
12
|
+
const pkgPath = path.resolve(process.cwd(), 'package.json');
|
|
13
|
+
if (!fs.existsSync(pkgPath)) return false;
|
|
14
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
15
|
+
return pkg.type === 'module';
|
|
16
|
+
} catch {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
3
20
|
|
|
4
21
|
/**
|
|
5
22
|
* Clase para manejar operaciones sobre el archivo de configuración
|
|
@@ -10,10 +27,15 @@ class ConfigFileUtils {
|
|
|
10
27
|
* @returns {string} - Ruta al archivo de configuración
|
|
11
28
|
*/
|
|
12
29
|
static getConfigPath() {
|
|
13
|
-
// Usar la ruta raíz del proyecto
|
|
14
30
|
const rootPath = path.resolve(process.cwd());
|
|
15
|
-
const
|
|
16
|
-
|
|
31
|
+
const cjsPath = path.join(rootPath, 'dbcube.config.cjs');
|
|
32
|
+
const jsPath = path.join(rootPath, 'dbcube.config.js');
|
|
33
|
+
// Si ya existe alguno, ese manda (preferimos .cjs).
|
|
34
|
+
if (fs.existsSync(cjsPath)) return cjsPath;
|
|
35
|
+
if (fs.existsSync(jsPath)) return jsPath;
|
|
36
|
+
// Si no existe ninguno (se va a crear): en proyectos ESM
|
|
37
|
+
// ("type": "module") debe ser .cjs para poder cargarse con require().
|
|
38
|
+
return projectIsESM() ? cjsPath : jsPath;
|
|
17
39
|
}
|
|
18
40
|
|
|
19
41
|
/**
|
|
@@ -21,19 +43,16 @@ class ConfigFileUtils {
|
|
|
21
43
|
* @returns {Promise<Array<string>>} - Array con los nombres de las bases de datos
|
|
22
44
|
*/
|
|
23
45
|
static async getConfiguredDatabases() {
|
|
24
|
-
try
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return this.loadDatabasesFromPath(configPath);
|
|
34
|
-
} catch (error) {
|
|
35
|
-
throw new Error('Error al obtener las bases de datos configuradas:', error);
|
|
46
|
+
// Sin try/catch que oculte el error: loadDatabasesFromPath ya lanza
|
|
47
|
+
// mensajes explícitos y accionables. (Antes, `new Error('msg', error)`
|
|
48
|
+
// descartaba el segundo argumento y se perdía la causa real.)
|
|
49
|
+
const configPath = this.getConfigPath();
|
|
50
|
+
|
|
51
|
+
if (!fs.existsSync(configPath)) {
|
|
52
|
+
ConfigFileUtils.crearArchivoConfig(configPath);
|
|
36
53
|
}
|
|
54
|
+
|
|
55
|
+
return this.loadDatabasesFromPath(configPath);
|
|
37
56
|
}
|
|
38
57
|
|
|
39
58
|
/**
|
|
@@ -42,46 +61,91 @@ class ConfigFileUtils {
|
|
|
42
61
|
* @returns {Array<string>} - Nombres de las bases de datos
|
|
43
62
|
*/
|
|
44
63
|
static loadDatabasesFromPath(configPath) {
|
|
64
|
+
// Carga automática de .env (cargador propio de DBCube): el usuario no
|
|
65
|
+
// necesita instalar dotenv ni escribir require("dotenv") en su config.
|
|
66
|
+
EnvLoader.load();
|
|
67
|
+
|
|
68
|
+
let config;
|
|
45
69
|
try {
|
|
46
70
|
// Borrar la caché del módulo para asegurarnos de cargar la versión más reciente
|
|
47
71
|
delete require.cache[require.resolve(configPath)];
|
|
48
|
-
|
|
49
72
|
// Cargar el archivo de configuración
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
73
|
+
config = require(configPath);
|
|
74
|
+
} catch (error) {
|
|
75
|
+
const missing = (error.message.match(/Cannot find module '([^']+)'/) || [])[1];
|
|
76
|
+
// ¿El módulo que no se encuentra es el PROPIO config? Entonces el
|
|
77
|
+
// problema es de carga (típicamente ESM). Si es OTRO módulo, es una
|
|
78
|
+
// dependencia del config que falta (p. ej. dotenv).
|
|
79
|
+
const missingIsConfig = missing && (configPath.includes(missing) || missing.includes('dbcube.config'));
|
|
80
|
+
|
|
81
|
+
// Caso 1: falta una dependencia que el config requiere.
|
|
82
|
+
if (error.code === 'MODULE_NOT_FOUND' && missing && !missingIsConfig) {
|
|
83
|
+
throw new Error(
|
|
84
|
+
`dbcube.config.js requiere un módulo que no está instalado: "${missing}".\n` +
|
|
85
|
+
` Instálalo (p. ej. npm install ${missing}).\n` +
|
|
86
|
+
` Nota: DBCube ya carga el .env automáticamente — puedes quitar require("dotenv") de tu config.`
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
// Caso 2: proyecto ESM ("type": "module") → require() del config falla
|
|
90
|
+
// o el .js se interpreta como módulo ES y `module.exports` no aplica.
|
|
91
|
+
if (projectIsESM() || error.code === 'ERR_REQUIRE_ESM') {
|
|
92
|
+
throw new Error(
|
|
93
|
+
`No se pudo cargar dbcube.config.js porque el proyecto está marcado como ESM ` +
|
|
94
|
+
`("type": "module" en package.json), pero la configuración usa CommonJS (module.exports).\n` +
|
|
95
|
+
` Solución: renombra el archivo a "dbcube.config.cjs", o quita "type": "module" de package.json.`
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
// Cualquier otro error de carga: mostrarlo tal cual.
|
|
99
|
+
throw new Error(`No se pudo cargar la configuración desde ${configPath}:\n ${error.message}`);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Validar que la config exporte una función (firma esperada).
|
|
103
|
+
if (typeof config !== 'function') {
|
|
104
|
+
const hint = projectIsESM()
|
|
105
|
+
? ` El proyecto es ESM ("type": "module"): renombra el archivo a "dbcube.config.cjs" o quita "type": "module".`
|
|
106
|
+
: ` Debe exportar una función: module.exports = function (config) { config.set({ databases: {...} }); }.`;
|
|
107
|
+
throw new Error(`dbcube.config.js no exporta una configuración válida.${hint}`);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Crear una instancia temporal de Config para obtener los datos
|
|
111
|
+
const tempConfig = {
|
|
112
|
+
databases: {},
|
|
113
|
+
data: {},
|
|
114
|
+
set: function(configData) {
|
|
115
|
+
this.data = configData;
|
|
116
|
+
if (configData.databases) {
|
|
117
|
+
this.databases = configData.databases;
|
|
64
118
|
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
config(tempConfig);
|
|
69
|
-
|
|
70
|
-
// Obtener los nombres de las bases de datos
|
|
71
|
-
const databaseNames = Object.keys(tempConfig.getAllDatabases());
|
|
72
|
-
const arrayDatabases = [];
|
|
73
|
-
for (const database of databaseNames) {
|
|
74
|
-
arrayDatabases.push({
|
|
75
|
-
name: database,
|
|
76
|
-
type: tempConfig.getAllDatabases()[database].type
|
|
77
|
-
});
|
|
119
|
+
},
|
|
120
|
+
getAllDatabases: function() {
|
|
121
|
+
return this.databases;
|
|
78
122
|
}
|
|
79
|
-
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
// Ejecutar la función de configuración
|
|
126
|
+
try {
|
|
127
|
+
config(tempConfig);
|
|
80
128
|
} catch (error) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
129
|
+
throw new Error(`dbcube.config.js lanzó un error al evaluarse:\n ${error.message}`);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const allDatabases = tempConfig.getAllDatabases();
|
|
133
|
+
if (!allDatabases || Object.keys(allDatabases).length === 0) {
|
|
134
|
+
throw new Error(
|
|
135
|
+
`dbcube.config.js no define ninguna base de datos.\n` +
|
|
136
|
+
` Añade al menos una en config.set({ databases: { miBase: { type, config } } }).`
|
|
137
|
+
);
|
|
84
138
|
}
|
|
139
|
+
|
|
140
|
+
const databaseNames = Object.keys(allDatabases);
|
|
141
|
+
const arrayDatabases = [];
|
|
142
|
+
for (const database of databaseNames) {
|
|
143
|
+
arrayDatabases.push({
|
|
144
|
+
name: database,
|
|
145
|
+
type: allDatabases[database].type
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
return arrayDatabases;
|
|
85
149
|
}
|
|
86
150
|
|
|
87
151
|
/**
|
|
@@ -271,15 +335,16 @@ class ConfigFileUtils {
|
|
|
271
335
|
* @param {string} rutaDestino - Ruta completa donde se debe crear el archivo.
|
|
272
336
|
*/
|
|
273
337
|
static crearArchivoConfig(rutaDestino) {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
}
|
|
281
|
-
};
|
|
282
|
-
|
|
338
|
+
// DBCube carga el .env automáticamente, así que el template ya NO
|
|
339
|
+
// necesita require('dotenv') (que además requeriría instalar el paquete).
|
|
340
|
+
const contenido = `// DBCube carga .env automáticamente — usa process.env.MI_VAR sin dotenv.
|
|
341
|
+
module.exports = function (config) {
|
|
342
|
+
config.set({
|
|
343
|
+
databases: {
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
};
|
|
347
|
+
`;
|
|
283
348
|
|
|
284
349
|
// Asegurarse de que el directorio existe
|
|
285
350
|
const dir = path.dirname(rutaDestino);
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Cargador de variables de entorno propio de DBCube.
|
|
6
|
+
*
|
|
7
|
+
* Evita que el usuario tenga que instalar `dotenv` y escribir
|
|
8
|
+
* `require("dotenv").config()` al inicio de su dbcube.config.js. DBCube carga
|
|
9
|
+
* el `.env` del proyecto automáticamente ANTES de evaluar la configuración.
|
|
10
|
+
*
|
|
11
|
+
* Estrategia:
|
|
12
|
+
* 1. `process.loadEnvFile()` — nativo de Node 20.6+ (cero dependencias).
|
|
13
|
+
* 2. Fallback: parser propio mínimo (KEY=VALUE, comillas, comentarios, export).
|
|
14
|
+
*
|
|
15
|
+
* No sobrescribe variables ya presentes en process.env (las del shell mandan).
|
|
16
|
+
*/
|
|
17
|
+
class EnvLoader {
|
|
18
|
+
/**
|
|
19
|
+
* Carga el archivo .env indicado (o ./.env del cwd) en process.env.
|
|
20
|
+
* Silencioso si el archivo no existe. Devuelve true si cargó algo.
|
|
21
|
+
* @param {string} [envPath]
|
|
22
|
+
* @returns {boolean}
|
|
23
|
+
*/
|
|
24
|
+
static load(envPath) {
|
|
25
|
+
const file = envPath || path.resolve(process.cwd(), '.env');
|
|
26
|
+
if (!fs.existsSync(file)) return false;
|
|
27
|
+
|
|
28
|
+
// Camino preferido: cargador nativo de Node (20.6+).
|
|
29
|
+
if (typeof process.loadEnvFile === 'function') {
|
|
30
|
+
try {
|
|
31
|
+
process.loadEnvFile(file);
|
|
32
|
+
return true;
|
|
33
|
+
} catch {
|
|
34
|
+
// Cae al parser propio si el nativo falla por algún motivo.
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
const content = fs.readFileSync(file, 'utf8');
|
|
40
|
+
const parsed = EnvLoader.parse(content);
|
|
41
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
42
|
+
if (process.env[key] === undefined) {
|
|
43
|
+
process.env[key] = value;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return true;
|
|
47
|
+
} catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Parser mínimo de formato .env. Soporta:
|
|
54
|
+
* KEY=value · KEY="value con espacios" · KEY='literal' · export KEY=value
|
|
55
|
+
* comentarios con # · líneas en blanco · \n \t en comillas dobles.
|
|
56
|
+
* @param {string} content
|
|
57
|
+
* @returns {Record<string,string>}
|
|
58
|
+
*/
|
|
59
|
+
static parse(content) {
|
|
60
|
+
const out = {};
|
|
61
|
+
for (let rawLine of content.split(/\r?\n/)) {
|
|
62
|
+
const line = rawLine.trim();
|
|
63
|
+
if (!line || line.startsWith('#')) continue;
|
|
64
|
+
|
|
65
|
+
// Permite el prefijo `export` (estilo shell).
|
|
66
|
+
const withoutExport = line.startsWith('export ') ? line.slice(7).trim() : line;
|
|
67
|
+
|
|
68
|
+
const eq = withoutExport.indexOf('=');
|
|
69
|
+
if (eq === -1) continue;
|
|
70
|
+
|
|
71
|
+
const key = withoutExport.slice(0, eq).trim();
|
|
72
|
+
if (!key) continue;
|
|
73
|
+
|
|
74
|
+
let value = withoutExport.slice(eq + 1).trim();
|
|
75
|
+
|
|
76
|
+
// Comillas dobles: interpreta escapes. Comillas simples: literal.
|
|
77
|
+
if (value.length >= 2 && value[0] === '"' && value[value.length - 1] === '"') {
|
|
78
|
+
value = value.slice(1, -1).replace(/\\n/g, '\n').replace(/\\t/g, '\t').replace(/\\"/g, '"');
|
|
79
|
+
} else if (value.length >= 2 && value[0] === "'" && value[value.length - 1] === "'") {
|
|
80
|
+
value = value.slice(1, -1);
|
|
81
|
+
} else {
|
|
82
|
+
// Sin comillas: corta un comentario en línea (espacio + #).
|
|
83
|
+
const hash = value.indexOf(' #');
|
|
84
|
+
if (hash !== -1) value = value.slice(0, hash).trim();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
out[key] = value;
|
|
88
|
+
}
|
|
89
|
+
return out;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
module.exports = EnvLoader;
|
|
94
|
+
module.exports.EnvLoader = EnvLoader;
|