@meltstudio/config-loader 1.0.4 → 2.0.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/README.md +330 -175
- package/dist/index.d.ts +135 -84
- package/dist/index.js +605 -283
- package/package.json +39 -28
package/dist/index.js
CHANGED
|
@@ -5,7 +5,6 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
8
|
var __export = (target, all) => {
|
|
10
9
|
for (var name in all)
|
|
11
10
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -27,18 +26,70 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
27
26
|
mod
|
|
28
27
|
));
|
|
29
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
-
var __publicField = (obj, key, value) => {
|
|
31
|
-
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
32
|
-
return value;
|
|
33
|
-
};
|
|
34
29
|
|
|
35
30
|
// src/index.ts
|
|
36
|
-
var
|
|
37
|
-
__export(
|
|
38
|
-
|
|
39
|
-
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
ConfigFileError: () => ConfigFileError,
|
|
34
|
+
ConfigLoadError: () => ConfigLoadError,
|
|
35
|
+
default: () => index_default
|
|
40
36
|
});
|
|
41
|
-
module.exports = __toCommonJS(
|
|
37
|
+
module.exports = __toCommonJS(index_exports);
|
|
38
|
+
|
|
39
|
+
// src/settings.ts
|
|
40
|
+
var import_commander = require("commander");
|
|
41
|
+
|
|
42
|
+
// src/errors.ts
|
|
43
|
+
var ConfigLoadError = class extends Error {
|
|
44
|
+
errors;
|
|
45
|
+
warnings;
|
|
46
|
+
constructor(errors, warnings) {
|
|
47
|
+
const message = `Configuration loading failed with ${errors.length} error${errors.length === 1 ? "" : "s"}`;
|
|
48
|
+
super(message);
|
|
49
|
+
this.name = "ConfigLoadError";
|
|
50
|
+
this.errors = errors;
|
|
51
|
+
this.warnings = warnings;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
var ConfigFileError = class extends ConfigLoadError {
|
|
55
|
+
constructor(message) {
|
|
56
|
+
super([{ message, kind: "file_validation" }], []);
|
|
57
|
+
this.name = "ConfigFileError";
|
|
58
|
+
this.message = message;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// src/nodes/configNode.ts
|
|
63
|
+
var ConfigNode = class {
|
|
64
|
+
value;
|
|
65
|
+
path;
|
|
66
|
+
sourceType;
|
|
67
|
+
file;
|
|
68
|
+
variableName;
|
|
69
|
+
argName;
|
|
70
|
+
line;
|
|
71
|
+
column;
|
|
72
|
+
constructor(value, path2, sourceType, file, variableName, argName, line = null, column = null) {
|
|
73
|
+
this.value = value;
|
|
74
|
+
this.path = path2;
|
|
75
|
+
this.sourceType = sourceType;
|
|
76
|
+
this.file = file;
|
|
77
|
+
this.variableName = variableName;
|
|
78
|
+
this.argName = argName;
|
|
79
|
+
this.line = line;
|
|
80
|
+
this.column = column;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
var configNode_default = ConfigNode;
|
|
84
|
+
|
|
85
|
+
// src/nodes/configNodeArray.ts
|
|
86
|
+
var ConfigNodeArray = class {
|
|
87
|
+
arrayValues;
|
|
88
|
+
constructor(arrayValues) {
|
|
89
|
+
this.arrayValues = arrayValues;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
var configNodeArray_default = ConfigNodeArray;
|
|
42
93
|
|
|
43
94
|
// src/types.ts
|
|
44
95
|
var InvalidValue = class {
|
|
@@ -55,57 +106,175 @@ var ArrayValueContainer = class {
|
|
|
55
106
|
};
|
|
56
107
|
var arrayOption_default = ArrayValueContainer;
|
|
57
108
|
|
|
58
|
-
// src/
|
|
109
|
+
// src/fileLoader.ts
|
|
59
110
|
var fs = __toESM(require("fs"));
|
|
60
111
|
var import_js_yaml = __toESM(require("js-yaml"));
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
var
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
112
|
+
var import_js_yaml_source_map = __toESM(require("js-yaml-source-map"));
|
|
113
|
+
var path = __toESM(require("path"));
|
|
114
|
+
var fileCache = /* @__PURE__ */ new Map();
|
|
115
|
+
var JsonSourceMap = class {
|
|
116
|
+
locations = /* @__PURE__ */ new Map();
|
|
117
|
+
constructor(content) {
|
|
118
|
+
this.buildMap(content);
|
|
119
|
+
}
|
|
120
|
+
buildMap(content, prefix = []) {
|
|
121
|
+
const lines = content.split("\n");
|
|
122
|
+
for (let i = 0; i < lines.length; i++) {
|
|
123
|
+
const line = lines[i];
|
|
124
|
+
const keyRegex = /^(\s*)"([^"]+)"\s*:/g;
|
|
125
|
+
let match;
|
|
126
|
+
while ((match = keyRegex.exec(line)) !== null) {
|
|
127
|
+
const key = match[2];
|
|
128
|
+
const column = match[1].length + 1;
|
|
129
|
+
this.locations.set(key, {
|
|
130
|
+
line: i + 1,
|
|
131
|
+
column,
|
|
132
|
+
position: 0
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
const data = JSON.parse(content);
|
|
138
|
+
this.walkObject(data, prefix, lines);
|
|
139
|
+
} catch {
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
walkObject(obj, prefix, lines) {
|
|
143
|
+
for (const key of Object.keys(obj)) {
|
|
144
|
+
const fullPath = [...prefix, key].join(".");
|
|
145
|
+
for (let i = 0; i < lines.length; i++) {
|
|
146
|
+
const line = lines[i];
|
|
147
|
+
const keyPattern = `"${key}"`;
|
|
148
|
+
const idx = line.indexOf(keyPattern);
|
|
149
|
+
if (idx !== -1) {
|
|
150
|
+
const afterKey = line.slice(idx + keyPattern.length).trim();
|
|
151
|
+
if (afterKey.startsWith(":")) {
|
|
152
|
+
this.locations.set(fullPath, {
|
|
153
|
+
line: i + 1,
|
|
154
|
+
column: idx + 1,
|
|
155
|
+
position: 0
|
|
156
|
+
});
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
const val = obj[key];
|
|
162
|
+
if (val && typeof val === "object" && !Array.isArray(val)) {
|
|
163
|
+
this.walkObject(
|
|
164
|
+
val,
|
|
165
|
+
[...prefix, key],
|
|
166
|
+
lines
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
lookup(path2) {
|
|
172
|
+
const key = Array.isArray(path2) ? path2.join(".") : path2;
|
|
173
|
+
return this.locations.get(key);
|
|
77
174
|
}
|
|
78
175
|
};
|
|
79
|
-
|
|
176
|
+
function loadConfigFile(filePath) {
|
|
177
|
+
const cached = fileCache.get(filePath);
|
|
178
|
+
if (cached) return cached;
|
|
179
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
180
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
181
|
+
try {
|
|
182
|
+
if (ext === ".json") {
|
|
183
|
+
const result2 = {
|
|
184
|
+
data: JSON.parse(content),
|
|
185
|
+
sourceMap: new JsonSourceMap(content)
|
|
186
|
+
};
|
|
187
|
+
fileCache.set(filePath, result2);
|
|
188
|
+
return result2;
|
|
189
|
+
}
|
|
190
|
+
const sourceMap = new import_js_yaml_source_map.default();
|
|
191
|
+
const data = import_js_yaml.default.load(content, { listener: sourceMap.listen() });
|
|
192
|
+
const result = { data, sourceMap };
|
|
193
|
+
fileCache.set(filePath, result);
|
|
194
|
+
return result;
|
|
195
|
+
} catch (err) {
|
|
196
|
+
const message = err instanceof Error ? err.message : "Unknown parsing error";
|
|
197
|
+
throw new ConfigFileError(
|
|
198
|
+
`Failed to parse config file '${filePath}': ${message}`
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
function clearFileCache() {
|
|
203
|
+
fileCache.clear();
|
|
204
|
+
}
|
|
80
205
|
|
|
81
206
|
// src/utils.ts
|
|
82
207
|
function valueIsInvalid(val) {
|
|
83
208
|
return val instanceof InvalidValue || val === null || val === void 0;
|
|
84
209
|
}
|
|
85
210
|
|
|
86
|
-
// src/option/errors.ts
|
|
87
|
-
var _OptionErrors = class {
|
|
88
|
-
static clearAll() {
|
|
89
|
-
_OptionErrors.errors = [];
|
|
90
|
-
_OptionErrors.warnings = [];
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
|
-
var OptionErrors = _OptionErrors;
|
|
94
|
-
__publicField(OptionErrors, "errors", []);
|
|
95
|
-
__publicField(OptionErrors, "warnings", []);
|
|
96
|
-
|
|
97
211
|
// src/option/base.ts
|
|
212
|
+
function valueToString(val) {
|
|
213
|
+
if (typeof val === "object" && val !== null) {
|
|
214
|
+
return JSON.stringify(val);
|
|
215
|
+
}
|
|
216
|
+
return String(val);
|
|
217
|
+
}
|
|
218
|
+
function lookupLocation(sourceMap, path2) {
|
|
219
|
+
if (!sourceMap) return null;
|
|
220
|
+
const loc = sourceMap.lookup(path2.map(String));
|
|
221
|
+
if (!loc) return null;
|
|
222
|
+
return { line: loc.line, column: loc.column };
|
|
223
|
+
}
|
|
224
|
+
function findEnvFileSource(envKey, currentValue, envFileResults) {
|
|
225
|
+
if (!envFileResults) return null;
|
|
226
|
+
for (let i = envFileResults.length - 1; i >= 0; i--) {
|
|
227
|
+
const result = envFileResults[i];
|
|
228
|
+
const entry = result.entries.get(envKey);
|
|
229
|
+
if (entry && entry.value === currentValue) {
|
|
230
|
+
return {
|
|
231
|
+
filePath: result.filePath,
|
|
232
|
+
line: entry.line,
|
|
233
|
+
column: entry.column
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return null;
|
|
238
|
+
}
|
|
239
|
+
function checkNumberType(val, pathStr, sourceOfVal, errors) {
|
|
240
|
+
if (typeof val === "string") {
|
|
241
|
+
const parseVal = parseInt(val, 10);
|
|
242
|
+
if (Number.isNaN(parseVal)) {
|
|
243
|
+
errors?.errors.push({
|
|
244
|
+
message: `Cannot convert value '${val}' for '${pathStr}' to number in ${sourceOfVal}.`,
|
|
245
|
+
path: pathStr,
|
|
246
|
+
source: sourceOfVal,
|
|
247
|
+
kind: "type_conversion"
|
|
248
|
+
});
|
|
249
|
+
return new InvalidValue();
|
|
250
|
+
}
|
|
251
|
+
errors?.warnings.push(
|
|
252
|
+
`The option ${pathStr} is stated as a number but is provided as a string`
|
|
253
|
+
);
|
|
254
|
+
return parseVal;
|
|
255
|
+
}
|
|
256
|
+
errors?.errors.push({
|
|
257
|
+
message: `Invalid state. Invalid kind in ${sourceOfVal}`,
|
|
258
|
+
source: sourceOfVal,
|
|
259
|
+
kind: "invalid_state"
|
|
260
|
+
});
|
|
261
|
+
return new InvalidValue();
|
|
262
|
+
}
|
|
263
|
+
function formatFileLocation(file, loc) {
|
|
264
|
+
if (!loc) return file;
|
|
265
|
+
return `${file}:${loc.line}:${loc.column}`;
|
|
266
|
+
}
|
|
98
267
|
var OptionBase = class {
|
|
99
268
|
params;
|
|
100
269
|
constructor(params) {
|
|
101
270
|
this.params = params;
|
|
102
271
|
}
|
|
103
|
-
getValue(sourceFile, env, args,
|
|
104
|
-
const ident =
|
|
272
|
+
getValue(sourceFile, env, args, path2, defaultValues, objectFromArray, envFileResults, errors) {
|
|
273
|
+
const ident = path2.join(".");
|
|
105
274
|
if (this.params.cli && args) {
|
|
106
275
|
if (ident in args) {
|
|
107
276
|
return new configNode_default(
|
|
108
|
-
this.checkType(args[ident],
|
|
277
|
+
this.checkType(args[ident], path2, "args", errors),
|
|
109
278
|
ident,
|
|
110
279
|
"args",
|
|
111
280
|
null,
|
|
@@ -118,8 +287,25 @@ var OptionBase = class {
|
|
|
118
287
|
if (this.params.env in env) {
|
|
119
288
|
const val = env[this.params.env];
|
|
120
289
|
if (val) {
|
|
290
|
+
const envFileSource = findEnvFileSource(
|
|
291
|
+
this.params.env,
|
|
292
|
+
val,
|
|
293
|
+
envFileResults
|
|
294
|
+
);
|
|
295
|
+
if (envFileSource) {
|
|
296
|
+
return new configNode_default(
|
|
297
|
+
this.checkType(val, path2, "envFile", errors),
|
|
298
|
+
ident,
|
|
299
|
+
"envFile",
|
|
300
|
+
envFileSource.filePath,
|
|
301
|
+
this.params.env,
|
|
302
|
+
null,
|
|
303
|
+
envFileSource.line,
|
|
304
|
+
envFileSource.column
|
|
305
|
+
);
|
|
306
|
+
}
|
|
121
307
|
return new configNode_default(
|
|
122
|
-
this.checkType(val,
|
|
308
|
+
this.checkType(val, path2, "env", errors),
|
|
123
309
|
ident,
|
|
124
310
|
"env",
|
|
125
311
|
null,
|
|
@@ -130,88 +316,52 @@ var OptionBase = class {
|
|
|
130
316
|
}
|
|
131
317
|
}
|
|
132
318
|
if (typeof sourceFile === "string") {
|
|
133
|
-
const data =
|
|
134
|
-
|
|
319
|
+
const { data, sourceMap } = loadConfigFile(sourceFile);
|
|
320
|
+
const node = this.resolveFromFileData(
|
|
321
|
+
data || {},
|
|
322
|
+
sourceFile,
|
|
323
|
+
sourceMap,
|
|
324
|
+
path2,
|
|
325
|
+
ident,
|
|
326
|
+
errors
|
|
135
327
|
);
|
|
136
|
-
|
|
137
|
-
if (val instanceof arrayOption_default) {
|
|
138
|
-
return new configNode_default(
|
|
139
|
-
this.checkType(val, path, sourceFile),
|
|
140
|
-
ident,
|
|
141
|
-
"file",
|
|
142
|
-
sourceFile,
|
|
143
|
-
null,
|
|
144
|
-
null
|
|
145
|
-
);
|
|
146
|
-
}
|
|
147
|
-
if (!valueIsInvalid(val)) {
|
|
148
|
-
return new configNode_default(
|
|
149
|
-
this.checkType(val, path, sourceFile),
|
|
150
|
-
ident,
|
|
151
|
-
"file",
|
|
152
|
-
sourceFile,
|
|
153
|
-
null,
|
|
154
|
-
null
|
|
155
|
-
);
|
|
156
|
-
}
|
|
328
|
+
if (node) return node;
|
|
157
329
|
}
|
|
158
330
|
if (Array.isArray(sourceFile)) {
|
|
159
331
|
for (let index = 0; index < sourceFile.length; index += 1) {
|
|
160
332
|
const file = sourceFile[index];
|
|
161
|
-
const data =
|
|
162
|
-
|
|
333
|
+
const { data, sourceMap } = loadConfigFile(file);
|
|
334
|
+
const node = this.resolveFromFileData(
|
|
335
|
+
data || {},
|
|
336
|
+
file,
|
|
337
|
+
sourceMap,
|
|
338
|
+
path2,
|
|
339
|
+
ident,
|
|
340
|
+
errors
|
|
163
341
|
);
|
|
164
|
-
|
|
165
|
-
if (val instanceof arrayOption_default) {
|
|
166
|
-
return new configNode_default(
|
|
167
|
-
this.checkType(val, path, file),
|
|
168
|
-
ident,
|
|
169
|
-
"file",
|
|
170
|
-
file,
|
|
171
|
-
null,
|
|
172
|
-
null
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
if (!valueIsInvalid(val)) {
|
|
176
|
-
return new configNode_default(
|
|
177
|
-
this.checkType(val, path, file),
|
|
178
|
-
ident,
|
|
179
|
-
"file",
|
|
180
|
-
file,
|
|
181
|
-
null,
|
|
182
|
-
null
|
|
183
|
-
);
|
|
184
|
-
}
|
|
342
|
+
if (node) return node;
|
|
185
343
|
}
|
|
186
344
|
}
|
|
187
345
|
if (objectFromArray) {
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
);
|
|
198
|
-
}
|
|
199
|
-
if (!valueIsInvalid(val)) {
|
|
200
|
-
return new configNode_default(
|
|
201
|
-
this.checkType(val, path, objectFromArray.file),
|
|
202
|
-
ident,
|
|
203
|
-
"file",
|
|
204
|
-
objectFromArray.file,
|
|
205
|
-
null,
|
|
206
|
-
null
|
|
207
|
-
);
|
|
208
|
-
}
|
|
346
|
+
const node = this.resolveFromFileData(
|
|
347
|
+
objectFromArray.value,
|
|
348
|
+
objectFromArray.file,
|
|
349
|
+
objectFromArray.sourceMap ?? null,
|
|
350
|
+
path2,
|
|
351
|
+
ident,
|
|
352
|
+
errors
|
|
353
|
+
);
|
|
354
|
+
if (node) return node;
|
|
209
355
|
}
|
|
210
356
|
if (defaultValues) {
|
|
211
|
-
const val = this.findInObject(
|
|
357
|
+
const val = this.findInObject(
|
|
358
|
+
defaultValues,
|
|
359
|
+
path2,
|
|
360
|
+
errors
|
|
361
|
+
);
|
|
212
362
|
if (val instanceof arrayOption_default) {
|
|
213
363
|
return new configNode_default(
|
|
214
|
-
this.checkType(val,
|
|
364
|
+
this.checkType(val, path2, "default", errors),
|
|
215
365
|
ident,
|
|
216
366
|
"default",
|
|
217
367
|
null,
|
|
@@ -221,7 +371,7 @@ var OptionBase = class {
|
|
|
221
371
|
}
|
|
222
372
|
if (!valueIsInvalid(val)) {
|
|
223
373
|
return new configNode_default(
|
|
224
|
-
this.checkType(val,
|
|
374
|
+
this.checkType(val, path2, "default", errors),
|
|
225
375
|
ident,
|
|
226
376
|
"default",
|
|
227
377
|
null,
|
|
@@ -232,17 +382,18 @@ var OptionBase = class {
|
|
|
232
382
|
}
|
|
233
383
|
if (this.params.defaultValue !== void 0) {
|
|
234
384
|
let defaultValue;
|
|
235
|
-
|
|
236
|
-
|
|
385
|
+
const rawDefault = this.params.defaultValue;
|
|
386
|
+
if (typeof rawDefault === "function") {
|
|
387
|
+
defaultValue = rawDefault();
|
|
237
388
|
} else {
|
|
238
|
-
defaultValue =
|
|
389
|
+
defaultValue = rawDefault;
|
|
239
390
|
}
|
|
240
391
|
if (this.params.kind === "array" && Array.isArray(defaultValue)) {
|
|
241
|
-
defaultValue = this.buildArrayOption(defaultValue);
|
|
392
|
+
defaultValue = this.buildArrayOption(defaultValue, errors);
|
|
242
393
|
}
|
|
243
394
|
if (!valueIsInvalid(defaultValue)) {
|
|
244
395
|
return new configNode_default(
|
|
245
|
-
this.checkType(defaultValue,
|
|
396
|
+
this.checkType(defaultValue, path2, "default", errors),
|
|
246
397
|
ident,
|
|
247
398
|
"default",
|
|
248
399
|
null,
|
|
@@ -252,32 +403,39 @@ var OptionBase = class {
|
|
|
252
403
|
}
|
|
253
404
|
}
|
|
254
405
|
if (this.params.required) {
|
|
255
|
-
|
|
406
|
+
errors?.errors.push({
|
|
407
|
+
message: `Required option '${ident}' not provided.`,
|
|
408
|
+
path: ident,
|
|
409
|
+
kind: "required"
|
|
410
|
+
});
|
|
256
411
|
}
|
|
257
412
|
return null;
|
|
258
413
|
}
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
414
|
+
resolveFromFileData(data, file, sourceMap, path2, ident, errors) {
|
|
415
|
+
const val = this.findInObject(data, path2, errors);
|
|
416
|
+
const loc = lookupLocation(sourceMap, path2);
|
|
417
|
+
if (val instanceof arrayOption_default || !valueIsInvalid(val)) {
|
|
418
|
+
return new configNode_default(
|
|
419
|
+
this.checkType(val, path2, formatFileLocation(file, loc), errors),
|
|
420
|
+
ident,
|
|
421
|
+
"file",
|
|
422
|
+
file,
|
|
423
|
+
null,
|
|
424
|
+
null,
|
|
425
|
+
loc?.line ?? null,
|
|
426
|
+
loc?.column ?? null
|
|
271
427
|
);
|
|
272
|
-
return parseVal;
|
|
273
428
|
}
|
|
274
|
-
|
|
275
|
-
return new InvalidValue();
|
|
429
|
+
return null;
|
|
276
430
|
}
|
|
277
|
-
checkType(val,
|
|
278
|
-
const ident =
|
|
431
|
+
checkType(val, path2, sourceOfVal, errors) {
|
|
432
|
+
const ident = path2.join(".");
|
|
279
433
|
if (valueIsInvalid(val)) {
|
|
280
|
-
|
|
434
|
+
errors?.errors.push({
|
|
435
|
+
message: `Invalid state. Invalid kind in ${sourceOfVal}`,
|
|
436
|
+
source: sourceOfVal,
|
|
437
|
+
kind: "invalid_state"
|
|
438
|
+
});
|
|
281
439
|
return val;
|
|
282
440
|
}
|
|
283
441
|
if (typeof val === this.params.kind) {
|
|
@@ -285,14 +443,19 @@ var OptionBase = class {
|
|
|
285
443
|
}
|
|
286
444
|
if (this.params.kind === "string") {
|
|
287
445
|
if (typeof val === "number") {
|
|
288
|
-
|
|
446
|
+
errors?.warnings.push(
|
|
289
447
|
`The option ${ident} is stated as a string but is provided as a number`
|
|
290
448
|
);
|
|
291
449
|
return val.toString();
|
|
292
450
|
}
|
|
293
|
-
|
|
294
|
-
`Cannot convert value '${
|
|
295
|
-
|
|
451
|
+
errors?.errors.push({
|
|
452
|
+
message: `Cannot convert value '${valueToString(
|
|
453
|
+
val
|
|
454
|
+
)}' for '${ident}' to string in ${sourceOfVal}.`,
|
|
455
|
+
path: ident,
|
|
456
|
+
source: sourceOfVal,
|
|
457
|
+
kind: "type_conversion"
|
|
458
|
+
});
|
|
296
459
|
return new InvalidValue();
|
|
297
460
|
}
|
|
298
461
|
if (this.params.kind === "boolean") {
|
|
@@ -304,73 +467,106 @@ var OptionBase = class {
|
|
|
304
467
|
return false;
|
|
305
468
|
}
|
|
306
469
|
}
|
|
307
|
-
|
|
308
|
-
`Cannot convert value '${
|
|
309
|
-
|
|
470
|
+
errors?.errors.push({
|
|
471
|
+
message: `Cannot convert value '${valueToString(
|
|
472
|
+
val
|
|
473
|
+
)}' for '${ident}' to boolean in ${sourceOfVal}.`,
|
|
474
|
+
path: ident,
|
|
475
|
+
source: sourceOfVal,
|
|
476
|
+
kind: "type_conversion"
|
|
477
|
+
});
|
|
310
478
|
return new InvalidValue();
|
|
311
479
|
}
|
|
312
480
|
if (this.params.kind === "number") {
|
|
313
|
-
return
|
|
481
|
+
return checkNumberType(val, ident, sourceOfVal, errors);
|
|
314
482
|
}
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
483
|
+
errors?.errors.push({
|
|
484
|
+
message: `Invalid state. Invalid kind in ${sourceOfVal}`,
|
|
485
|
+
source: sourceOfVal,
|
|
486
|
+
kind: "invalid_state"
|
|
487
|
+
});
|
|
319
488
|
throw new Error(
|
|
320
|
-
"Invalid kind. Must be 'string', 'number', 'boolean'
|
|
489
|
+
"Invalid kind. Must be 'string', 'number', 'boolean' or 'array'"
|
|
321
490
|
);
|
|
322
491
|
}
|
|
323
|
-
findInObject(obj,
|
|
324
|
-
if (
|
|
325
|
-
const [child, ...rest] =
|
|
492
|
+
findInObject(obj, path2, errors) {
|
|
493
|
+
if (path2.length > 1) {
|
|
494
|
+
const [child, ...rest] = path2;
|
|
326
495
|
const val = obj[child];
|
|
327
496
|
if (typeof val === "string") {
|
|
328
|
-
|
|
497
|
+
errors?.errors.push({
|
|
498
|
+
message: `Cant get path from string value '${val}'`,
|
|
499
|
+
kind: "invalid_path"
|
|
500
|
+
});
|
|
329
501
|
return new InvalidValue();
|
|
330
502
|
}
|
|
331
503
|
if (typeof val === "number") {
|
|
332
|
-
|
|
504
|
+
errors?.errors.push({
|
|
505
|
+
message: `Cant get path from number value '${val}'`,
|
|
506
|
+
kind: "invalid_path"
|
|
507
|
+
});
|
|
333
508
|
return new InvalidValue();
|
|
334
509
|
}
|
|
335
510
|
if (typeof val === "boolean") {
|
|
336
|
-
|
|
337
|
-
`Cant get path from boolean value '${val.toString()}'
|
|
338
|
-
|
|
511
|
+
errors?.errors.push({
|
|
512
|
+
message: `Cant get path from boolean value '${val.toString()}'`,
|
|
513
|
+
kind: "invalid_path"
|
|
514
|
+
});
|
|
339
515
|
return new InvalidValue();
|
|
340
516
|
}
|
|
341
517
|
if (Array.isArray(val)) {
|
|
342
|
-
|
|
343
|
-
`Cant get path from array value '${val
|
|
344
|
-
|
|
518
|
+
errors?.errors.push({
|
|
519
|
+
message: `Cant get path from array value '${valueToString(val)}'`,
|
|
520
|
+
kind: "invalid_path"
|
|
521
|
+
});
|
|
345
522
|
return new InvalidValue();
|
|
346
523
|
}
|
|
347
524
|
if (val == null) {
|
|
348
525
|
return new InvalidValue();
|
|
349
526
|
}
|
|
350
|
-
return this.findInObject(val, rest);
|
|
527
|
+
return this.findInObject(val, rest, errors);
|
|
351
528
|
}
|
|
352
|
-
if (
|
|
353
|
-
const val = obj[
|
|
529
|
+
if (path2.length === 1) {
|
|
530
|
+
const val = obj[path2[0]];
|
|
354
531
|
if (!Array.isArray(val) && typeof val === "object" && val || typeof val === "string" || typeof val === "number" || typeof val === "boolean" || typeof val === "undefined") {
|
|
355
532
|
return val;
|
|
356
533
|
}
|
|
357
534
|
if (Array.isArray(val)) {
|
|
358
|
-
return this.buildArrayOption(val);
|
|
535
|
+
return this.buildArrayOption(val, errors);
|
|
359
536
|
}
|
|
360
|
-
|
|
361
|
-
`Invalid path '${
|
|
362
|
-
|
|
537
|
+
errors?.errors.push({
|
|
538
|
+
message: `Invalid path '${path2.join(".")}': ${typeof val}`,
|
|
539
|
+
kind: "invalid_path"
|
|
540
|
+
});
|
|
363
541
|
return new InvalidValue();
|
|
364
542
|
}
|
|
365
|
-
|
|
543
|
+
errors?.errors.push({
|
|
544
|
+
message: `Invalid path '${path2.join()}'`,
|
|
545
|
+
kind: "invalid_path"
|
|
546
|
+
});
|
|
366
547
|
return new InvalidValue();
|
|
367
548
|
}
|
|
368
549
|
// eslint-disable-next-line class-methods-use-this
|
|
369
|
-
buildArrayOption(_val) {
|
|
550
|
+
buildArrayOption(_val, _errors) {
|
|
370
551
|
return new InvalidValue();
|
|
371
552
|
}
|
|
372
553
|
};
|
|
373
554
|
|
|
555
|
+
// src/option/object.ts
|
|
556
|
+
var ObjectOption = class extends OptionBase {
|
|
557
|
+
item;
|
|
558
|
+
constructor(params) {
|
|
559
|
+
super({
|
|
560
|
+
kind: "object",
|
|
561
|
+
env: null,
|
|
562
|
+
cli: false,
|
|
563
|
+
help: "",
|
|
564
|
+
...params
|
|
565
|
+
});
|
|
566
|
+
this.item = params.item;
|
|
567
|
+
}
|
|
568
|
+
};
|
|
569
|
+
|
|
374
570
|
// src/option/array.ts
|
|
375
571
|
var ArrayOption = class extends OptionBase {
|
|
376
572
|
item;
|
|
@@ -384,105 +580,186 @@ var ArrayOption = class extends OptionBase {
|
|
|
384
580
|
});
|
|
385
581
|
this.item = params.item;
|
|
386
582
|
}
|
|
387
|
-
buildArrayOption(val) {
|
|
583
|
+
buildArrayOption(val, errors) {
|
|
388
584
|
if (this.item === null) {
|
|
389
|
-
|
|
585
|
+
errors?.errors.push({
|
|
586
|
+
message: `Array item cannot be null`,
|
|
587
|
+
kind: "invalid_state"
|
|
588
|
+
});
|
|
390
589
|
return new InvalidValue();
|
|
391
590
|
}
|
|
392
591
|
return new arrayOption_default(this.item, val);
|
|
393
592
|
}
|
|
394
|
-
|
|
395
|
-
checkType(val, path, sourceOfVal) {
|
|
593
|
+
checkType(val, path2, sourceOfVal, errors) {
|
|
396
594
|
if (val instanceof arrayOption_default) {
|
|
397
595
|
val.val.forEach((v, i) => {
|
|
398
|
-
if (this.item instanceof OptionBase) {
|
|
399
|
-
this.item.checkType(v, [...
|
|
596
|
+
if (this.item instanceof OptionBase && !(this.item instanceof ObjectOption)) {
|
|
597
|
+
this.item.checkType(v, [...path2, i], sourceOfVal, errors);
|
|
400
598
|
}
|
|
401
599
|
});
|
|
402
600
|
return val;
|
|
403
601
|
}
|
|
404
|
-
|
|
602
|
+
errors?.errors.push({
|
|
603
|
+
message: `Invalid state. Invalid kind in ${sourceOfVal}`,
|
|
604
|
+
source: sourceOfVal,
|
|
605
|
+
kind: "invalid_state"
|
|
606
|
+
});
|
|
405
607
|
return new InvalidValue();
|
|
406
608
|
}
|
|
407
609
|
};
|
|
408
610
|
|
|
611
|
+
// src/envFileLoader.ts
|
|
612
|
+
var fs2 = __toESM(require("fs"));
|
|
613
|
+
var envFileCache = /* @__PURE__ */ new Map();
|
|
614
|
+
function loadEnvFile(filePath) {
|
|
615
|
+
const cached = envFileCache.get(filePath);
|
|
616
|
+
if (cached) return cached;
|
|
617
|
+
const content = fs2.readFileSync(filePath, "utf-8");
|
|
618
|
+
const entries = /* @__PURE__ */ new Map();
|
|
619
|
+
const lines = content.split("\n");
|
|
620
|
+
for (let i = 0; i < lines.length; i++) {
|
|
621
|
+
const raw = lines[i];
|
|
622
|
+
const trimmed = raw.trim();
|
|
623
|
+
if (trimmed === "" || trimmed.startsWith("#")) continue;
|
|
624
|
+
const eqIndex = trimmed.indexOf("=");
|
|
625
|
+
if (eqIndex === -1) continue;
|
|
626
|
+
const key = trimmed.slice(0, eqIndex).trim();
|
|
627
|
+
if (key === "") continue;
|
|
628
|
+
let value = trimmed.slice(eqIndex + 1).trim();
|
|
629
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
630
|
+
value = value.slice(1, -1);
|
|
631
|
+
}
|
|
632
|
+
const column = raw.indexOf(key) + 1;
|
|
633
|
+
entries.set(key, {
|
|
634
|
+
value,
|
|
635
|
+
line: i + 1,
|
|
636
|
+
column
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
const result = { entries, filePath };
|
|
640
|
+
envFileCache.set(filePath, result);
|
|
641
|
+
return result;
|
|
642
|
+
}
|
|
643
|
+
function clearEnvFileCache() {
|
|
644
|
+
envFileCache.clear();
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
// src/option/errors.ts
|
|
648
|
+
var OptionErrors = class {
|
|
649
|
+
errors = [];
|
|
650
|
+
warnings = [];
|
|
651
|
+
clearAll() {
|
|
652
|
+
this.errors = [];
|
|
653
|
+
this.warnings = [];
|
|
654
|
+
clearFileCache();
|
|
655
|
+
clearEnvFileCache();
|
|
656
|
+
}
|
|
657
|
+
};
|
|
658
|
+
|
|
409
659
|
// src/option/primitive.ts
|
|
410
660
|
var PrimitiveOption = class extends OptionBase {
|
|
411
661
|
};
|
|
412
662
|
|
|
413
|
-
// src/
|
|
414
|
-
var
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
663
|
+
// src/sourceValidation.ts
|
|
664
|
+
var fs3 = __toESM(require("fs"));
|
|
665
|
+
function validateFiles(files, dir) {
|
|
666
|
+
if (files && dir)
|
|
667
|
+
throw new ConfigFileError("Dir and files are specified, choose one");
|
|
668
|
+
let sourceFile = [];
|
|
669
|
+
if (files) {
|
|
670
|
+
if (Array.isArray(files)) {
|
|
671
|
+
const result = [];
|
|
672
|
+
files.forEach((file) => {
|
|
673
|
+
if (!fs3.existsSync(file)) {
|
|
674
|
+
throw new ConfigFileError(`Invalid config file '${file}'`);
|
|
675
|
+
} else {
|
|
676
|
+
result.push(file);
|
|
677
|
+
}
|
|
678
|
+
});
|
|
679
|
+
sourceFile = result;
|
|
680
|
+
} else {
|
|
681
|
+
if (!fs3.existsSync(files)) {
|
|
682
|
+
throw new ConfigFileError(`Invalid config file '${files}'`);
|
|
683
|
+
}
|
|
684
|
+
sourceFile = files;
|
|
685
|
+
}
|
|
422
686
|
}
|
|
423
|
-
|
|
424
|
-
|
|
687
|
+
if (dir) {
|
|
688
|
+
if (!(fs3.existsSync(dir) && fs3.lstatSync(dir).isDirectory())) {
|
|
689
|
+
throw new ConfigFileError(`'${dir}' not exists or is not a dir`);
|
|
690
|
+
}
|
|
691
|
+
const filesInDirectory = fs3.readdirSync(dir).sort();
|
|
692
|
+
if (filesInDirectory.length === 0) {
|
|
693
|
+
throw new ConfigFileError(`Directory '${dir}' is empty`);
|
|
694
|
+
}
|
|
695
|
+
const result = [];
|
|
696
|
+
filesInDirectory.forEach((file) => {
|
|
697
|
+
result.push(`${dir}/${file}`);
|
|
698
|
+
});
|
|
699
|
+
sourceFile = result;
|
|
700
|
+
}
|
|
701
|
+
return sourceFile;
|
|
702
|
+
}
|
|
703
|
+
function loadEnvFiles(envFile, envData) {
|
|
704
|
+
const envFileResults = [];
|
|
705
|
+
if (!envFile) return { envFileResults, mergedEnvData: envData };
|
|
706
|
+
const envFiles = Array.isArray(envFile) ? envFile : [envFile];
|
|
707
|
+
for (const file of envFiles) {
|
|
708
|
+
if (!fs3.existsSync(file)) {
|
|
709
|
+
throw new ConfigFileError(`Invalid env file '${file}'`);
|
|
710
|
+
}
|
|
711
|
+
const result = loadEnvFile(file);
|
|
712
|
+
envFileResults.push(result);
|
|
713
|
+
}
|
|
714
|
+
const merged = {};
|
|
715
|
+
for (const result of envFileResults) {
|
|
716
|
+
for (const [key, entry] of result.entries) {
|
|
717
|
+
merged[key] = entry.value;
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
for (const [key, value] of Object.entries(envData)) {
|
|
721
|
+
if (value !== void 0) {
|
|
722
|
+
merged[key] = value;
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
return { envFileResults, mergedEnvData: merged };
|
|
726
|
+
}
|
|
425
727
|
|
|
426
728
|
// src/settings.ts
|
|
427
729
|
var Settings = class {
|
|
428
730
|
schema;
|
|
429
731
|
sources;
|
|
732
|
+
errors = new OptionErrors();
|
|
430
733
|
sourceFile = [];
|
|
431
734
|
argsData = {};
|
|
432
735
|
envData = {};
|
|
433
736
|
optionsTree = {};
|
|
434
737
|
defaultData = {};
|
|
738
|
+
envFileResults = [];
|
|
435
739
|
program;
|
|
436
|
-
constructor(
|
|
437
|
-
this.schema =
|
|
740
|
+
constructor(schema2, sources) {
|
|
741
|
+
this.schema = schema2;
|
|
438
742
|
this.sources = sources;
|
|
439
743
|
this.program = new import_commander.Command().allowUnknownOption(true).allowExcessArguments(true);
|
|
440
744
|
this.load();
|
|
441
745
|
}
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
if (!Array.isArray(this.sourceFile)) {
|
|
453
|
-
this.sourceFile = [];
|
|
454
|
-
}
|
|
455
|
-
this.sourceFile.push(file);
|
|
456
|
-
}
|
|
457
|
-
});
|
|
458
|
-
} else {
|
|
459
|
-
if (!fs2.existsSync(files)) {
|
|
460
|
-
throw new Error(`Invalid config file '${files}'`);
|
|
461
|
-
}
|
|
462
|
-
this.sourceFile = files;
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
if (dir) {
|
|
466
|
-
if (!(fs2.existsSync(dir) && fs2.lstatSync(dir).isDirectory())) {
|
|
467
|
-
throw new Error(`'${dir}' not exists or is not a dir`);
|
|
468
|
-
}
|
|
469
|
-
const filesInDirectory = fs2.readdirSync(dir).sort();
|
|
470
|
-
if (filesInDirectory.length === 0) {
|
|
471
|
-
throw new Error(`Directory '${dir}' is empty`);
|
|
472
|
-
}
|
|
473
|
-
filesInDirectory.forEach((file) => {
|
|
474
|
-
if (!Array.isArray(this.sourceFile)) {
|
|
475
|
-
this.sourceFile = [];
|
|
476
|
-
}
|
|
477
|
-
this.sourceFile.push(`${dir}/${file}`);
|
|
478
|
-
});
|
|
479
|
-
}
|
|
746
|
+
validateAndLoadFiles() {
|
|
747
|
+
this.sourceFile = validateFiles(this.sources.files, this.sources.dir);
|
|
748
|
+
}
|
|
749
|
+
loadAndMergeEnvFiles() {
|
|
750
|
+
const { envFileResults, mergedEnvData } = loadEnvFiles(
|
|
751
|
+
this.sources.envFile,
|
|
752
|
+
this.envData
|
|
753
|
+
);
|
|
754
|
+
this.envFileResults = envFileResults;
|
|
755
|
+
this.envData = mergedEnvData;
|
|
480
756
|
}
|
|
481
757
|
load() {
|
|
482
|
-
this.
|
|
758
|
+
this.validateAndLoadFiles();
|
|
483
759
|
if (this.sources.env) {
|
|
484
|
-
this.envData = process.env;
|
|
760
|
+
this.envData = { ...process.env };
|
|
485
761
|
}
|
|
762
|
+
this.loadAndMergeEnvFiles();
|
|
486
763
|
if (this.sources.args) {
|
|
487
764
|
this.traverseOptions(this.schema, [], this.addArg.bind(this));
|
|
488
765
|
this.program.parse(process.argv);
|
|
@@ -498,44 +775,66 @@ var Settings = class {
|
|
|
498
775
|
sourceFile: this.sourceFile,
|
|
499
776
|
envData: this.envData,
|
|
500
777
|
argsData: this.argsData,
|
|
501
|
-
defaultValue: this.defaultData
|
|
778
|
+
defaultValue: this.defaultData,
|
|
779
|
+
envFileResults: this.envFileResults,
|
|
780
|
+
errors: this.errors
|
|
502
781
|
})
|
|
503
782
|
);
|
|
504
|
-
if (
|
|
505
|
-
for (let index = 0; index <
|
|
506
|
-
console.warn(`[Warning]: ${
|
|
783
|
+
if (this.errors.warnings.length > 0) {
|
|
784
|
+
for (let index = 0; index < this.errors.warnings.length; index += 1) {
|
|
785
|
+
console.warn(`[Warning]: ${this.errors.warnings[index]}`);
|
|
507
786
|
}
|
|
508
787
|
}
|
|
509
|
-
if (
|
|
510
|
-
|
|
511
|
-
|
|
788
|
+
if (this.errors.errors.length > 0) {
|
|
789
|
+
if (this.sources.exitOnError) {
|
|
790
|
+
for (let index = 0; index < this.errors.errors.length; index += 1) {
|
|
791
|
+
console.error(`[Error]: ${this.errors.errors[index].message}`);
|
|
792
|
+
}
|
|
793
|
+
process.exit(1);
|
|
512
794
|
}
|
|
513
|
-
|
|
795
|
+
throw new ConfigLoadError(
|
|
796
|
+
[...this.errors.errors],
|
|
797
|
+
[...this.errors.warnings]
|
|
798
|
+
);
|
|
514
799
|
}
|
|
515
800
|
}
|
|
516
|
-
traverseOptions(node,
|
|
517
|
-
if (node instanceof
|
|
518
|
-
|
|
801
|
+
traverseOptions(node, path2, callback) {
|
|
802
|
+
if (node instanceof ObjectOption) {
|
|
803
|
+
const item = node.item;
|
|
804
|
+
Object.keys(item).forEach((key) => {
|
|
805
|
+
this.traverseOptions(item[key], [...path2, key], callback);
|
|
806
|
+
});
|
|
807
|
+
} else if (node instanceof OptionBase) {
|
|
808
|
+
callback(node, path2);
|
|
519
809
|
} else {
|
|
520
810
|
Object.keys(node).forEach((key) => {
|
|
521
811
|
const val = node[key];
|
|
522
|
-
this.traverseOptions(val, [...
|
|
812
|
+
this.traverseOptions(val, [...path2, key], callback);
|
|
523
813
|
});
|
|
524
814
|
}
|
|
525
815
|
}
|
|
526
|
-
buildOption(result, configData, node,
|
|
527
|
-
const {
|
|
816
|
+
buildOption(result, configData, node, path2) {
|
|
817
|
+
const {
|
|
818
|
+
sourceFile = [],
|
|
819
|
+
envData = {},
|
|
820
|
+
argsData = {},
|
|
821
|
+
defaultValue = {},
|
|
822
|
+
objectFromArray,
|
|
823
|
+
envFileResults,
|
|
824
|
+
errors
|
|
825
|
+
} = configData;
|
|
528
826
|
const value = node.getValue(
|
|
529
827
|
sourceFile,
|
|
530
828
|
envData,
|
|
531
829
|
argsData,
|
|
532
|
-
|
|
830
|
+
path2,
|
|
533
831
|
defaultValue,
|
|
534
|
-
objectFromArray
|
|
832
|
+
objectFromArray,
|
|
833
|
+
envFileResults,
|
|
834
|
+
errors
|
|
535
835
|
);
|
|
536
|
-
if (value
|
|
537
|
-
|
|
538
|
-
this.setOption(result, path, value);
|
|
836
|
+
if (value !== null) {
|
|
837
|
+
this.setOption(result, path2, value);
|
|
539
838
|
}
|
|
540
839
|
}
|
|
541
840
|
getValidatedArray(item, values, file) {
|
|
@@ -548,27 +847,18 @@ var Settings = class {
|
|
|
548
847
|
}
|
|
549
848
|
if (item.params.kind === "boolean") {
|
|
550
849
|
return values.map((v) => {
|
|
551
|
-
if (v === "true")
|
|
552
|
-
|
|
553
|
-
if (v ===
|
|
554
|
-
|
|
555
|
-
if (v ===
|
|
556
|
-
|
|
557
|
-
if (v === "false")
|
|
558
|
-
return false;
|
|
559
|
-
if (v === "0")
|
|
560
|
-
return false;
|
|
561
|
-
if (v === 0)
|
|
562
|
-
return false;
|
|
850
|
+
if (v === "true") return true;
|
|
851
|
+
if (v === "1") return true;
|
|
852
|
+
if (v === 1) return true;
|
|
853
|
+
if (v === "false") return false;
|
|
854
|
+
if (v === "0") return false;
|
|
855
|
+
if (v === 0) return false;
|
|
563
856
|
return v;
|
|
564
857
|
});
|
|
565
858
|
}
|
|
566
859
|
}
|
|
567
860
|
const arrayValues = values.map(
|
|
568
|
-
(v) => (
|
|
569
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
570
|
-
this.processArrayWithSchema(item, v, file)
|
|
571
|
-
)
|
|
861
|
+
(v) => this.processArrayWithSchema(item, v, file)
|
|
572
862
|
);
|
|
573
863
|
return new configNodeArray_default(arrayValues);
|
|
574
864
|
}
|
|
@@ -579,30 +869,34 @@ var Settings = class {
|
|
|
579
869
|
[],
|
|
580
870
|
this.buildOption.bind(this, result, {
|
|
581
871
|
objectFromArray: {
|
|
582
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
583
872
|
value: v,
|
|
584
873
|
file
|
|
585
|
-
}
|
|
874
|
+
},
|
|
875
|
+
errors: this.errors
|
|
586
876
|
})
|
|
587
877
|
);
|
|
588
878
|
return result;
|
|
589
879
|
}
|
|
590
|
-
setOption(options,
|
|
591
|
-
if (
|
|
592
|
-
const [child, ...rest] =
|
|
880
|
+
setOption(options, path2, node) {
|
|
881
|
+
if (path2.length > 1) {
|
|
882
|
+
const [child, ...rest] = path2;
|
|
593
883
|
if (!options[child]) {
|
|
594
884
|
options[child] = {};
|
|
595
885
|
}
|
|
596
|
-
this.setOption(
|
|
597
|
-
|
|
598
|
-
|
|
886
|
+
this.setOption(
|
|
887
|
+
options[child],
|
|
888
|
+
rest,
|
|
889
|
+
node
|
|
890
|
+
);
|
|
891
|
+
} else if (path2.length === 1) {
|
|
892
|
+
const [child] = path2;
|
|
599
893
|
if (node != null) {
|
|
600
894
|
if (node.value instanceof arrayOption_default) {
|
|
601
895
|
options[child] = node;
|
|
602
896
|
options[child].value = this.getValidatedArray(
|
|
603
897
|
node.value.item,
|
|
604
898
|
node.value.val,
|
|
605
|
-
node.file || node.
|
|
899
|
+
node.file || node.variableName || node.argName || ""
|
|
606
900
|
);
|
|
607
901
|
} else {
|
|
608
902
|
options[child] = node;
|
|
@@ -610,13 +904,13 @@ var Settings = class {
|
|
|
610
904
|
}
|
|
611
905
|
} else {
|
|
612
906
|
throw new Error(
|
|
613
|
-
`Invalid path '${node.path}' getting from '${node.
|
|
907
|
+
`Invalid path '${node.path}' getting from '${node.argName || node.file || node.variableName || ""}' in ' ${node.sourceType}`
|
|
614
908
|
);
|
|
615
909
|
}
|
|
616
910
|
}
|
|
617
|
-
addArg(node,
|
|
911
|
+
addArg(node, path2 = []) {
|
|
618
912
|
if (node.params.cli) {
|
|
619
|
-
const ident =
|
|
913
|
+
const ident = path2.join(".");
|
|
620
914
|
this.program.option(`--${ident} <value>`, node.params.help);
|
|
621
915
|
}
|
|
622
916
|
}
|
|
@@ -637,7 +931,9 @@ var Settings = class {
|
|
|
637
931
|
);
|
|
638
932
|
}
|
|
639
933
|
get() {
|
|
640
|
-
return this.getValuesFromTree(
|
|
934
|
+
return this.getValuesFromTree(
|
|
935
|
+
this.optionsTree
|
|
936
|
+
);
|
|
641
937
|
}
|
|
642
938
|
getExtended() {
|
|
643
939
|
return this.optionsTree;
|
|
@@ -645,14 +941,28 @@ var Settings = class {
|
|
|
645
941
|
};
|
|
646
942
|
var settings_default = Settings;
|
|
647
943
|
|
|
944
|
+
// src/builder/settings.ts
|
|
945
|
+
var SettingsBuilder = class {
|
|
946
|
+
schema;
|
|
947
|
+
constructor(schema2) {
|
|
948
|
+
this.schema = schema2;
|
|
949
|
+
}
|
|
950
|
+
load(sources) {
|
|
951
|
+
const settings = new settings_default(this.schema, sources);
|
|
952
|
+
return settings.get();
|
|
953
|
+
}
|
|
954
|
+
loadExtended(sources) {
|
|
955
|
+
const settings = new settings_default(this.schema, sources);
|
|
956
|
+
return settings.getExtended();
|
|
957
|
+
}
|
|
958
|
+
};
|
|
959
|
+
|
|
648
960
|
// src/index.ts
|
|
649
|
-
var src_default = settings_default;
|
|
650
961
|
var DEFAULTS = {
|
|
651
962
|
required: false,
|
|
652
963
|
env: null,
|
|
653
964
|
cli: false,
|
|
654
965
|
help: ""
|
|
655
|
-
// properties: {},
|
|
656
966
|
};
|
|
657
967
|
var string = (opts) => {
|
|
658
968
|
return new PrimitiveOption({
|
|
@@ -681,14 +991,26 @@ var array = (opts) => {
|
|
|
681
991
|
...opts
|
|
682
992
|
});
|
|
683
993
|
};
|
|
994
|
+
var object = (opts) => {
|
|
995
|
+
return new ObjectOption({
|
|
996
|
+
required: false,
|
|
997
|
+
...opts
|
|
998
|
+
});
|
|
999
|
+
};
|
|
1000
|
+
var schema = (theSchema) => {
|
|
1001
|
+
return new SettingsBuilder(theSchema);
|
|
1002
|
+
};
|
|
684
1003
|
var option = {
|
|
685
1004
|
string,
|
|
686
1005
|
number,
|
|
687
1006
|
bool,
|
|
688
|
-
|
|
689
|
-
|
|
1007
|
+
array,
|
|
1008
|
+
object,
|
|
1009
|
+
schema
|
|
690
1010
|
};
|
|
1011
|
+
var index_default = option;
|
|
691
1012
|
// Annotate the CommonJS export names for ESM import in node:
|
|
692
1013
|
0 && (module.exports = {
|
|
693
|
-
|
|
1014
|
+
ConfigFileError,
|
|
1015
|
+
ConfigLoadError
|
|
694
1016
|
});
|