@meltstudio/config-loader 1.1.0 → 2.0.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/README.md +306 -169
- package/dist/index.d.ts +138 -68
- package/dist/index.js +570 -259
- 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,37 +26,58 @@ 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
|
-
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
ConfigFileError: () => ConfigFileError,
|
|
34
|
+
ConfigLoadError: () => ConfigLoadError,
|
|
35
|
+
default: () => index_default
|
|
39
36
|
});
|
|
40
|
-
module.exports = __toCommonJS(
|
|
37
|
+
module.exports = __toCommonJS(index_exports);
|
|
41
38
|
|
|
42
39
|
// src/settings.ts
|
|
43
40
|
var import_commander = require("commander");
|
|
44
|
-
|
|
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
|
+
};
|
|
45
61
|
|
|
46
62
|
// src/nodes/configNode.ts
|
|
47
63
|
var ConfigNode = class {
|
|
48
64
|
value;
|
|
49
65
|
path;
|
|
50
|
-
|
|
66
|
+
sourceType;
|
|
51
67
|
file;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
68
|
+
variableName;
|
|
69
|
+
argName;
|
|
70
|
+
line;
|
|
71
|
+
column;
|
|
72
|
+
constructor(value, path2, sourceType, file, variableName, argName, line = null, column = null) {
|
|
55
73
|
this.value = value;
|
|
56
|
-
this.path =
|
|
57
|
-
this.
|
|
74
|
+
this.path = path2;
|
|
75
|
+
this.sourceType = sourceType;
|
|
58
76
|
this.file = file;
|
|
59
|
-
this.
|
|
60
|
-
this.
|
|
77
|
+
this.variableName = variableName;
|
|
78
|
+
this.argName = argName;
|
|
79
|
+
this.line = line;
|
|
80
|
+
this.column = column;
|
|
61
81
|
}
|
|
62
82
|
};
|
|
63
83
|
var configNode_default = ConfigNode;
|
|
@@ -86,38 +106,175 @@ var ArrayValueContainer = class {
|
|
|
86
106
|
};
|
|
87
107
|
var arrayOption_default = ArrayValueContainer;
|
|
88
108
|
|
|
89
|
-
// src/
|
|
109
|
+
// src/fileLoader.ts
|
|
90
110
|
var fs = __toESM(require("fs"));
|
|
91
111
|
var import_js_yaml = __toESM(require("js-yaml"));
|
|
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);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
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
|
+
}
|
|
92
205
|
|
|
93
206
|
// src/utils.ts
|
|
94
207
|
function valueIsInvalid(val) {
|
|
95
208
|
return val instanceof InvalidValue || val === null || val === void 0;
|
|
96
209
|
}
|
|
97
210
|
|
|
98
|
-
// src/option/errors.ts
|
|
99
|
-
var _OptionErrors = class {
|
|
100
|
-
static clearAll() {
|
|
101
|
-
_OptionErrors.errors = [];
|
|
102
|
-
_OptionErrors.warnings = [];
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
var OptionErrors = _OptionErrors;
|
|
106
|
-
__publicField(OptionErrors, "errors", []);
|
|
107
|
-
__publicField(OptionErrors, "warnings", []);
|
|
108
|
-
|
|
109
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
|
+
}
|
|
110
267
|
var OptionBase = class {
|
|
111
268
|
params;
|
|
112
269
|
constructor(params) {
|
|
113
270
|
this.params = params;
|
|
114
271
|
}
|
|
115
|
-
getValue(sourceFile, env, args,
|
|
116
|
-
const ident =
|
|
272
|
+
getValue(sourceFile, env, args, path2, defaultValues, objectFromArray, envFileResults, errors) {
|
|
273
|
+
const ident = path2.join(".");
|
|
117
274
|
if (this.params.cli && args) {
|
|
118
275
|
if (ident in args) {
|
|
119
276
|
return new configNode_default(
|
|
120
|
-
this.checkType(args[ident],
|
|
277
|
+
this.checkType(args[ident], path2, "args", errors),
|
|
121
278
|
ident,
|
|
122
279
|
"args",
|
|
123
280
|
null,
|
|
@@ -130,8 +287,25 @@ var OptionBase = class {
|
|
|
130
287
|
if (this.params.env in env) {
|
|
131
288
|
const val = env[this.params.env];
|
|
132
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
|
+
}
|
|
133
307
|
return new configNode_default(
|
|
134
|
-
this.checkType(val,
|
|
308
|
+
this.checkType(val, path2, "env", errors),
|
|
135
309
|
ident,
|
|
136
310
|
"env",
|
|
137
311
|
null,
|
|
@@ -142,88 +316,52 @@ var OptionBase = class {
|
|
|
142
316
|
}
|
|
143
317
|
}
|
|
144
318
|
if (typeof sourceFile === "string") {
|
|
145
|
-
const data =
|
|
146
|
-
|
|
319
|
+
const { data, sourceMap } = loadConfigFile(sourceFile);
|
|
320
|
+
const node = this.resolveFromFileData(
|
|
321
|
+
data || {},
|
|
322
|
+
sourceFile,
|
|
323
|
+
sourceMap,
|
|
324
|
+
path2,
|
|
325
|
+
ident,
|
|
326
|
+
errors
|
|
147
327
|
);
|
|
148
|
-
|
|
149
|
-
if (val instanceof arrayOption_default) {
|
|
150
|
-
return new configNode_default(
|
|
151
|
-
this.checkType(val, path, sourceFile),
|
|
152
|
-
ident,
|
|
153
|
-
"file",
|
|
154
|
-
sourceFile,
|
|
155
|
-
null,
|
|
156
|
-
null
|
|
157
|
-
);
|
|
158
|
-
}
|
|
159
|
-
if (!valueIsInvalid(val)) {
|
|
160
|
-
return new configNode_default(
|
|
161
|
-
this.checkType(val, path, sourceFile),
|
|
162
|
-
ident,
|
|
163
|
-
"file",
|
|
164
|
-
sourceFile,
|
|
165
|
-
null,
|
|
166
|
-
null
|
|
167
|
-
);
|
|
168
|
-
}
|
|
328
|
+
if (node) return node;
|
|
169
329
|
}
|
|
170
330
|
if (Array.isArray(sourceFile)) {
|
|
171
331
|
for (let index = 0; index < sourceFile.length; index += 1) {
|
|
172
332
|
const file = sourceFile[index];
|
|
173
|
-
const data =
|
|
174
|
-
|
|
333
|
+
const { data, sourceMap } = loadConfigFile(file);
|
|
334
|
+
const node = this.resolveFromFileData(
|
|
335
|
+
data || {},
|
|
336
|
+
file,
|
|
337
|
+
sourceMap,
|
|
338
|
+
path2,
|
|
339
|
+
ident,
|
|
340
|
+
errors
|
|
175
341
|
);
|
|
176
|
-
|
|
177
|
-
if (val instanceof arrayOption_default) {
|
|
178
|
-
return new configNode_default(
|
|
179
|
-
this.checkType(val, path, file),
|
|
180
|
-
ident,
|
|
181
|
-
"file",
|
|
182
|
-
file,
|
|
183
|
-
null,
|
|
184
|
-
null
|
|
185
|
-
);
|
|
186
|
-
}
|
|
187
|
-
if (!valueIsInvalid(val)) {
|
|
188
|
-
return new configNode_default(
|
|
189
|
-
this.checkType(val, path, file),
|
|
190
|
-
ident,
|
|
191
|
-
"file",
|
|
192
|
-
file,
|
|
193
|
-
null,
|
|
194
|
-
null
|
|
195
|
-
);
|
|
196
|
-
}
|
|
342
|
+
if (node) return node;
|
|
197
343
|
}
|
|
198
344
|
}
|
|
199
345
|
if (objectFromArray) {
|
|
200
|
-
const
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
);
|
|
210
|
-
}
|
|
211
|
-
if (!valueIsInvalid(val)) {
|
|
212
|
-
return new configNode_default(
|
|
213
|
-
this.checkType(val, path, objectFromArray.file),
|
|
214
|
-
ident,
|
|
215
|
-
"file",
|
|
216
|
-
objectFromArray.file,
|
|
217
|
-
null,
|
|
218
|
-
null
|
|
219
|
-
);
|
|
220
|
-
}
|
|
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;
|
|
221
355
|
}
|
|
222
356
|
if (defaultValues) {
|
|
223
|
-
const val = this.findInObject(
|
|
357
|
+
const val = this.findInObject(
|
|
358
|
+
defaultValues,
|
|
359
|
+
path2,
|
|
360
|
+
errors
|
|
361
|
+
);
|
|
224
362
|
if (val instanceof arrayOption_default) {
|
|
225
363
|
return new configNode_default(
|
|
226
|
-
this.checkType(val,
|
|
364
|
+
this.checkType(val, path2, "default", errors),
|
|
227
365
|
ident,
|
|
228
366
|
"default",
|
|
229
367
|
null,
|
|
@@ -233,7 +371,7 @@ var OptionBase = class {
|
|
|
233
371
|
}
|
|
234
372
|
if (!valueIsInvalid(val)) {
|
|
235
373
|
return new configNode_default(
|
|
236
|
-
this.checkType(val,
|
|
374
|
+
this.checkType(val, path2, "default", errors),
|
|
237
375
|
ident,
|
|
238
376
|
"default",
|
|
239
377
|
null,
|
|
@@ -244,17 +382,18 @@ var OptionBase = class {
|
|
|
244
382
|
}
|
|
245
383
|
if (this.params.defaultValue !== void 0) {
|
|
246
384
|
let defaultValue;
|
|
247
|
-
|
|
248
|
-
|
|
385
|
+
const rawDefault = this.params.defaultValue;
|
|
386
|
+
if (typeof rawDefault === "function") {
|
|
387
|
+
defaultValue = rawDefault();
|
|
249
388
|
} else {
|
|
250
|
-
defaultValue =
|
|
389
|
+
defaultValue = rawDefault;
|
|
251
390
|
}
|
|
252
391
|
if (this.params.kind === "array" && Array.isArray(defaultValue)) {
|
|
253
|
-
defaultValue = this.buildArrayOption(defaultValue);
|
|
392
|
+
defaultValue = this.buildArrayOption(defaultValue, errors);
|
|
254
393
|
}
|
|
255
394
|
if (!valueIsInvalid(defaultValue)) {
|
|
256
395
|
return new configNode_default(
|
|
257
|
-
this.checkType(defaultValue,
|
|
396
|
+
this.checkType(defaultValue, path2, "default", errors),
|
|
258
397
|
ident,
|
|
259
398
|
"default",
|
|
260
399
|
null,
|
|
@@ -264,32 +403,39 @@ var OptionBase = class {
|
|
|
264
403
|
}
|
|
265
404
|
}
|
|
266
405
|
if (this.params.required) {
|
|
267
|
-
|
|
406
|
+
errors?.errors.push({
|
|
407
|
+
message: `Required option '${ident}' not provided.`,
|
|
408
|
+
path: ident,
|
|
409
|
+
kind: "required"
|
|
410
|
+
});
|
|
268
411
|
}
|
|
269
412
|
return null;
|
|
270
413
|
}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
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
|
|
283
427
|
);
|
|
284
|
-
return parseVal;
|
|
285
428
|
}
|
|
286
|
-
|
|
287
|
-
return new InvalidValue();
|
|
429
|
+
return null;
|
|
288
430
|
}
|
|
289
|
-
checkType(val,
|
|
290
|
-
const ident =
|
|
431
|
+
checkType(val, path2, sourceOfVal, errors) {
|
|
432
|
+
const ident = path2.join(".");
|
|
291
433
|
if (valueIsInvalid(val)) {
|
|
292
|
-
|
|
434
|
+
errors?.errors.push({
|
|
435
|
+
message: `Invalid state. Invalid kind in ${sourceOfVal}`,
|
|
436
|
+
source: sourceOfVal,
|
|
437
|
+
kind: "invalid_state"
|
|
438
|
+
});
|
|
293
439
|
return val;
|
|
294
440
|
}
|
|
295
441
|
if (typeof val === this.params.kind) {
|
|
@@ -297,14 +443,19 @@ var OptionBase = class {
|
|
|
297
443
|
}
|
|
298
444
|
if (this.params.kind === "string") {
|
|
299
445
|
if (typeof val === "number") {
|
|
300
|
-
|
|
446
|
+
errors?.warnings.push(
|
|
301
447
|
`The option ${ident} is stated as a string but is provided as a number`
|
|
302
448
|
);
|
|
303
449
|
return val.toString();
|
|
304
450
|
}
|
|
305
|
-
|
|
306
|
-
`Cannot convert value '${
|
|
307
|
-
|
|
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
|
+
});
|
|
308
459
|
return new InvalidValue();
|
|
309
460
|
}
|
|
310
461
|
if (this.params.kind === "boolean") {
|
|
@@ -316,73 +467,106 @@ var OptionBase = class {
|
|
|
316
467
|
return false;
|
|
317
468
|
}
|
|
318
469
|
}
|
|
319
|
-
|
|
320
|
-
`Cannot convert value '${
|
|
321
|
-
|
|
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
|
+
});
|
|
322
478
|
return new InvalidValue();
|
|
323
479
|
}
|
|
324
480
|
if (this.params.kind === "number") {
|
|
325
|
-
return
|
|
326
|
-
}
|
|
327
|
-
if (this.params.kind === "any") {
|
|
328
|
-
return val;
|
|
481
|
+
return checkNumberType(val, ident, sourceOfVal, errors);
|
|
329
482
|
}
|
|
330
|
-
|
|
483
|
+
errors?.errors.push({
|
|
484
|
+
message: `Invalid state. Invalid kind in ${sourceOfVal}`,
|
|
485
|
+
source: sourceOfVal,
|
|
486
|
+
kind: "invalid_state"
|
|
487
|
+
});
|
|
331
488
|
throw new Error(
|
|
332
|
-
"Invalid kind. Must be 'string', 'number', 'boolean'
|
|
489
|
+
"Invalid kind. Must be 'string', 'number', 'boolean' or 'array'"
|
|
333
490
|
);
|
|
334
491
|
}
|
|
335
|
-
findInObject(obj,
|
|
336
|
-
if (
|
|
337
|
-
const [child, ...rest] =
|
|
492
|
+
findInObject(obj, path2, errors) {
|
|
493
|
+
if (path2.length > 1) {
|
|
494
|
+
const [child, ...rest] = path2;
|
|
338
495
|
const val = obj[child];
|
|
339
496
|
if (typeof val === "string") {
|
|
340
|
-
|
|
497
|
+
errors?.errors.push({
|
|
498
|
+
message: `Cant get path from string value '${val}'`,
|
|
499
|
+
kind: "invalid_path"
|
|
500
|
+
});
|
|
341
501
|
return new InvalidValue();
|
|
342
502
|
}
|
|
343
503
|
if (typeof val === "number") {
|
|
344
|
-
|
|
504
|
+
errors?.errors.push({
|
|
505
|
+
message: `Cant get path from number value '${val}'`,
|
|
506
|
+
kind: "invalid_path"
|
|
507
|
+
});
|
|
345
508
|
return new InvalidValue();
|
|
346
509
|
}
|
|
347
510
|
if (typeof val === "boolean") {
|
|
348
|
-
|
|
349
|
-
`Cant get path from boolean value '${val.toString()}'
|
|
350
|
-
|
|
511
|
+
errors?.errors.push({
|
|
512
|
+
message: `Cant get path from boolean value '${val.toString()}'`,
|
|
513
|
+
kind: "invalid_path"
|
|
514
|
+
});
|
|
351
515
|
return new InvalidValue();
|
|
352
516
|
}
|
|
353
517
|
if (Array.isArray(val)) {
|
|
354
|
-
|
|
355
|
-
`Cant get path from array value '${val
|
|
356
|
-
|
|
518
|
+
errors?.errors.push({
|
|
519
|
+
message: `Cant get path from array value '${valueToString(val)}'`,
|
|
520
|
+
kind: "invalid_path"
|
|
521
|
+
});
|
|
357
522
|
return new InvalidValue();
|
|
358
523
|
}
|
|
359
524
|
if (val == null) {
|
|
360
525
|
return new InvalidValue();
|
|
361
526
|
}
|
|
362
|
-
return this.findInObject(val, rest);
|
|
527
|
+
return this.findInObject(val, rest, errors);
|
|
363
528
|
}
|
|
364
|
-
if (
|
|
365
|
-
const val = obj[
|
|
529
|
+
if (path2.length === 1) {
|
|
530
|
+
const val = obj[path2[0]];
|
|
366
531
|
if (!Array.isArray(val) && typeof val === "object" && val || typeof val === "string" || typeof val === "number" || typeof val === "boolean" || typeof val === "undefined") {
|
|
367
532
|
return val;
|
|
368
533
|
}
|
|
369
534
|
if (Array.isArray(val)) {
|
|
370
|
-
return this.buildArrayOption(val);
|
|
535
|
+
return this.buildArrayOption(val, errors);
|
|
371
536
|
}
|
|
372
|
-
|
|
373
|
-
`Invalid path '${
|
|
374
|
-
|
|
537
|
+
errors?.errors.push({
|
|
538
|
+
message: `Invalid path '${path2.join(".")}': ${typeof val}`,
|
|
539
|
+
kind: "invalid_path"
|
|
540
|
+
});
|
|
375
541
|
return new InvalidValue();
|
|
376
542
|
}
|
|
377
|
-
|
|
543
|
+
errors?.errors.push({
|
|
544
|
+
message: `Invalid path '${path2.join()}'`,
|
|
545
|
+
kind: "invalid_path"
|
|
546
|
+
});
|
|
378
547
|
return new InvalidValue();
|
|
379
548
|
}
|
|
380
549
|
// eslint-disable-next-line class-methods-use-this
|
|
381
|
-
buildArrayOption(_val) {
|
|
550
|
+
buildArrayOption(_val, _errors) {
|
|
382
551
|
return new InvalidValue();
|
|
383
552
|
}
|
|
384
553
|
};
|
|
385
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
|
+
|
|
386
570
|
// src/option/array.ts
|
|
387
571
|
var ArrayOption = class extends OptionBase {
|
|
388
572
|
item;
|
|
@@ -396,41 +580,162 @@ var ArrayOption = class extends OptionBase {
|
|
|
396
580
|
});
|
|
397
581
|
this.item = params.item;
|
|
398
582
|
}
|
|
399
|
-
buildArrayOption(val) {
|
|
583
|
+
buildArrayOption(val, errors) {
|
|
400
584
|
if (this.item === null) {
|
|
401
|
-
|
|
585
|
+
errors?.errors.push({
|
|
586
|
+
message: `Array item cannot be null`,
|
|
587
|
+
kind: "invalid_state"
|
|
588
|
+
});
|
|
402
589
|
return new InvalidValue();
|
|
403
590
|
}
|
|
404
591
|
return new arrayOption_default(this.item, val);
|
|
405
592
|
}
|
|
406
|
-
|
|
407
|
-
checkType(val, path, sourceOfVal) {
|
|
593
|
+
checkType(val, path2, sourceOfVal, errors) {
|
|
408
594
|
if (val instanceof arrayOption_default) {
|
|
409
595
|
val.val.forEach((v, i) => {
|
|
410
|
-
if (this.item instanceof OptionBase) {
|
|
411
|
-
this.item.checkType(v, [...
|
|
596
|
+
if (this.item instanceof OptionBase && !(this.item instanceof ObjectOption)) {
|
|
597
|
+
this.item.checkType(v, [...path2, i], sourceOfVal, errors);
|
|
412
598
|
}
|
|
413
599
|
});
|
|
414
600
|
return val;
|
|
415
601
|
}
|
|
416
|
-
|
|
602
|
+
errors?.errors.push({
|
|
603
|
+
message: `Invalid state. Invalid kind in ${sourceOfVal}`,
|
|
604
|
+
source: sourceOfVal,
|
|
605
|
+
kind: "invalid_state"
|
|
606
|
+
});
|
|
417
607
|
return new InvalidValue();
|
|
418
608
|
}
|
|
419
609
|
};
|
|
420
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
|
+
|
|
421
659
|
// src/option/primitive.ts
|
|
422
660
|
var PrimitiveOption = class extends OptionBase {
|
|
423
661
|
};
|
|
424
662
|
|
|
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
|
+
}
|
|
686
|
+
}
|
|
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
|
+
}
|
|
727
|
+
|
|
425
728
|
// src/settings.ts
|
|
426
729
|
var Settings = class {
|
|
427
730
|
schema;
|
|
428
731
|
sources;
|
|
732
|
+
errors = new OptionErrors();
|
|
429
733
|
sourceFile = [];
|
|
430
734
|
argsData = {};
|
|
431
735
|
envData = {};
|
|
432
736
|
optionsTree = {};
|
|
433
737
|
defaultData = {};
|
|
738
|
+
envFileResults = [];
|
|
434
739
|
program;
|
|
435
740
|
constructor(schema2, sources) {
|
|
436
741
|
this.schema = schema2;
|
|
@@ -438,50 +743,23 @@ var Settings = class {
|
|
|
438
743
|
this.program = new import_commander.Command().allowUnknownOption(true).allowExcessArguments(true);
|
|
439
744
|
this.load();
|
|
440
745
|
}
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
if (!Array.isArray(this.sourceFile)) {
|
|
452
|
-
this.sourceFile = [];
|
|
453
|
-
}
|
|
454
|
-
this.sourceFile.push(file);
|
|
455
|
-
}
|
|
456
|
-
});
|
|
457
|
-
} else {
|
|
458
|
-
if (!fs2.existsSync(files)) {
|
|
459
|
-
throw new Error(`Invalid config file '${files}'`);
|
|
460
|
-
}
|
|
461
|
-
this.sourceFile = files;
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
if (dir) {
|
|
465
|
-
if (!(fs2.existsSync(dir) && fs2.lstatSync(dir).isDirectory())) {
|
|
466
|
-
throw new Error(`'${dir}' not exists or is not a dir`);
|
|
467
|
-
}
|
|
468
|
-
const filesInDirectory = fs2.readdirSync(dir).sort();
|
|
469
|
-
if (filesInDirectory.length === 0) {
|
|
470
|
-
throw new Error(`Directory '${dir}' is empty`);
|
|
471
|
-
}
|
|
472
|
-
filesInDirectory.forEach((file) => {
|
|
473
|
-
if (!Array.isArray(this.sourceFile)) {
|
|
474
|
-
this.sourceFile = [];
|
|
475
|
-
}
|
|
476
|
-
this.sourceFile.push(`${dir}/${file}`);
|
|
477
|
-
});
|
|
478
|
-
}
|
|
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;
|
|
479
756
|
}
|
|
480
757
|
load() {
|
|
481
|
-
this.
|
|
758
|
+
this.validateAndLoadFiles();
|
|
482
759
|
if (this.sources.env) {
|
|
483
|
-
this.envData = process.env;
|
|
760
|
+
this.envData = { ...process.env };
|
|
484
761
|
}
|
|
762
|
+
this.loadAndMergeEnvFiles();
|
|
485
763
|
if (this.sources.args) {
|
|
486
764
|
this.traverseOptions(this.schema, [], this.addArg.bind(this));
|
|
487
765
|
this.program.parse(process.argv);
|
|
@@ -497,44 +775,66 @@ var Settings = class {
|
|
|
497
775
|
sourceFile: this.sourceFile,
|
|
498
776
|
envData: this.envData,
|
|
499
777
|
argsData: this.argsData,
|
|
500
|
-
defaultValue: this.defaultData
|
|
778
|
+
defaultValue: this.defaultData,
|
|
779
|
+
envFileResults: this.envFileResults,
|
|
780
|
+
errors: this.errors
|
|
501
781
|
})
|
|
502
782
|
);
|
|
503
|
-
if (
|
|
504
|
-
for (let index = 0; index <
|
|
505
|
-
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]}`);
|
|
506
786
|
}
|
|
507
787
|
}
|
|
508
|
-
if (
|
|
509
|
-
|
|
510
|
-
|
|
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);
|
|
511
794
|
}
|
|
512
|
-
|
|
795
|
+
throw new ConfigLoadError(
|
|
796
|
+
[...this.errors.errors],
|
|
797
|
+
[...this.errors.warnings]
|
|
798
|
+
);
|
|
513
799
|
}
|
|
514
800
|
}
|
|
515
|
-
traverseOptions(node,
|
|
516
|
-
if (node instanceof
|
|
517
|
-
|
|
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);
|
|
518
809
|
} else {
|
|
519
810
|
Object.keys(node).forEach((key) => {
|
|
520
811
|
const val = node[key];
|
|
521
|
-
this.traverseOptions(val, [...
|
|
812
|
+
this.traverseOptions(val, [...path2, key], callback);
|
|
522
813
|
});
|
|
523
814
|
}
|
|
524
815
|
}
|
|
525
|
-
buildOption(result, configData, node,
|
|
526
|
-
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;
|
|
527
826
|
const value = node.getValue(
|
|
528
827
|
sourceFile,
|
|
529
828
|
envData,
|
|
530
829
|
argsData,
|
|
531
|
-
|
|
830
|
+
path2,
|
|
532
831
|
defaultValue,
|
|
533
|
-
objectFromArray
|
|
832
|
+
objectFromArray,
|
|
833
|
+
envFileResults,
|
|
834
|
+
errors
|
|
534
835
|
);
|
|
535
|
-
if (value
|
|
536
|
-
|
|
537
|
-
this.setOption(result, path, value);
|
|
836
|
+
if (value !== null) {
|
|
837
|
+
this.setOption(result, path2, value);
|
|
538
838
|
}
|
|
539
839
|
}
|
|
540
840
|
getValidatedArray(item, values, file) {
|
|
@@ -547,27 +847,18 @@ var Settings = class {
|
|
|
547
847
|
}
|
|
548
848
|
if (item.params.kind === "boolean") {
|
|
549
849
|
return values.map((v) => {
|
|
550
|
-
if (v === "true")
|
|
551
|
-
|
|
552
|
-
if (v ===
|
|
553
|
-
|
|
554
|
-
if (v ===
|
|
555
|
-
|
|
556
|
-
if (v === "false")
|
|
557
|
-
return false;
|
|
558
|
-
if (v === "0")
|
|
559
|
-
return false;
|
|
560
|
-
if (v === 0)
|
|
561
|
-
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;
|
|
562
856
|
return v;
|
|
563
857
|
});
|
|
564
858
|
}
|
|
565
859
|
}
|
|
566
860
|
const arrayValues = values.map(
|
|
567
|
-
(v) => (
|
|
568
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
569
|
-
this.processArrayWithSchema(item, v, file)
|
|
570
|
-
)
|
|
861
|
+
(v) => this.processArrayWithSchema(item, v, file)
|
|
571
862
|
);
|
|
572
863
|
return new configNodeArray_default(arrayValues);
|
|
573
864
|
}
|
|
@@ -578,30 +869,34 @@ var Settings = class {
|
|
|
578
869
|
[],
|
|
579
870
|
this.buildOption.bind(this, result, {
|
|
580
871
|
objectFromArray: {
|
|
581
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
582
872
|
value: v,
|
|
583
873
|
file
|
|
584
|
-
}
|
|
874
|
+
},
|
|
875
|
+
errors: this.errors
|
|
585
876
|
})
|
|
586
877
|
);
|
|
587
878
|
return result;
|
|
588
879
|
}
|
|
589
|
-
setOption(options,
|
|
590
|
-
if (
|
|
591
|
-
const [child, ...rest] =
|
|
880
|
+
setOption(options, path2, node) {
|
|
881
|
+
if (path2.length > 1) {
|
|
882
|
+
const [child, ...rest] = path2;
|
|
592
883
|
if (!options[child]) {
|
|
593
884
|
options[child] = {};
|
|
594
885
|
}
|
|
595
|
-
this.setOption(
|
|
596
|
-
|
|
597
|
-
|
|
886
|
+
this.setOption(
|
|
887
|
+
options[child],
|
|
888
|
+
rest,
|
|
889
|
+
node
|
|
890
|
+
);
|
|
891
|
+
} else if (path2.length === 1) {
|
|
892
|
+
const [child] = path2;
|
|
598
893
|
if (node != null) {
|
|
599
894
|
if (node.value instanceof arrayOption_default) {
|
|
600
895
|
options[child] = node;
|
|
601
896
|
options[child].value = this.getValidatedArray(
|
|
602
897
|
node.value.item,
|
|
603
898
|
node.value.val,
|
|
604
|
-
node.file || node.
|
|
899
|
+
node.file || node.variableName || node.argName || ""
|
|
605
900
|
);
|
|
606
901
|
} else {
|
|
607
902
|
options[child] = node;
|
|
@@ -609,13 +904,13 @@ var Settings = class {
|
|
|
609
904
|
}
|
|
610
905
|
} else {
|
|
611
906
|
throw new Error(
|
|
612
|
-
`Invalid path '${node.path}' getting from '${node.
|
|
907
|
+
`Invalid path '${node.path}' getting from '${node.argName || node.file || node.variableName || ""}' in ' ${node.sourceType}`
|
|
613
908
|
);
|
|
614
909
|
}
|
|
615
910
|
}
|
|
616
|
-
addArg(node,
|
|
911
|
+
addArg(node, path2 = []) {
|
|
617
912
|
if (node.params.cli) {
|
|
618
|
-
const ident =
|
|
913
|
+
const ident = path2.join(".");
|
|
619
914
|
this.program.option(`--${ident} <value>`, node.params.help);
|
|
620
915
|
}
|
|
621
916
|
}
|
|
@@ -636,7 +931,9 @@ var Settings = class {
|
|
|
636
931
|
);
|
|
637
932
|
}
|
|
638
933
|
get() {
|
|
639
|
-
return this.getValuesFromTree(
|
|
934
|
+
return this.getValuesFromTree(
|
|
935
|
+
this.optionsTree
|
|
936
|
+
);
|
|
640
937
|
}
|
|
641
938
|
getExtended() {
|
|
642
939
|
return this.optionsTree;
|
|
@@ -654,6 +951,10 @@ var SettingsBuilder = class {
|
|
|
654
951
|
const settings = new settings_default(this.schema, sources);
|
|
655
952
|
return settings.get();
|
|
656
953
|
}
|
|
954
|
+
loadExtended(sources) {
|
|
955
|
+
const settings = new settings_default(this.schema, sources);
|
|
956
|
+
return settings.getExtended();
|
|
957
|
+
}
|
|
657
958
|
};
|
|
658
959
|
|
|
659
960
|
// src/index.ts
|
|
@@ -662,7 +963,6 @@ var DEFAULTS = {
|
|
|
662
963
|
env: null,
|
|
663
964
|
cli: false,
|
|
664
965
|
help: ""
|
|
665
|
-
// properties: {},
|
|
666
966
|
};
|
|
667
967
|
var string = (opts) => {
|
|
668
968
|
return new PrimitiveOption({
|
|
@@ -691,6 +991,12 @@ var array = (opts) => {
|
|
|
691
991
|
...opts
|
|
692
992
|
});
|
|
693
993
|
};
|
|
994
|
+
var object = (opts) => {
|
|
995
|
+
return new ObjectOption({
|
|
996
|
+
required: false,
|
|
997
|
+
...opts
|
|
998
|
+
});
|
|
999
|
+
};
|
|
694
1000
|
var schema = (theSchema) => {
|
|
695
1001
|
return new SettingsBuilder(theSchema);
|
|
696
1002
|
};
|
|
@@ -698,8 +1004,13 @@ var option = {
|
|
|
698
1004
|
string,
|
|
699
1005
|
number,
|
|
700
1006
|
bool,
|
|
701
|
-
// object,
|
|
702
1007
|
array,
|
|
1008
|
+
object,
|
|
703
1009
|
schema
|
|
704
1010
|
};
|
|
705
|
-
var
|
|
1011
|
+
var index_default = option;
|
|
1012
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1013
|
+
0 && (module.exports = {
|
|
1014
|
+
ConfigFileError,
|
|
1015
|
+
ConfigLoadError
|
|
1016
|
+
});
|