@backstage/config-loader 1.8.0 → 1.8.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/CHANGELOG.md +20 -0
- package/dist/index.cjs.js +188 -330
- package/dist/index.cjs.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs.js
CHANGED
|
@@ -55,7 +55,7 @@ function compileConfigSchemas(schemas, options) {
|
|
|
55
55
|
},
|
|
56
56
|
compile(visibility) {
|
|
57
57
|
return (_data, context) => {
|
|
58
|
-
if (
|
|
58
|
+
if (context?.instancePath === void 0) {
|
|
59
59
|
return false;
|
|
60
60
|
}
|
|
61
61
|
if (visibility && visibility !== "backend") {
|
|
@@ -80,7 +80,7 @@ function compileConfigSchemas(schemas, options) {
|
|
|
80
80
|
},
|
|
81
81
|
compile(visibility) {
|
|
82
82
|
return (_data, context) => {
|
|
83
|
-
if (
|
|
83
|
+
if (context?.instancePath === void 0) {
|
|
84
84
|
return false;
|
|
85
85
|
}
|
|
86
86
|
if (visibility) {
|
|
@@ -95,7 +95,7 @@ function compileConfigSchemas(schemas, options) {
|
|
|
95
95
|
metaSchema: { type: "string" },
|
|
96
96
|
compile(deprecationDescription) {
|
|
97
97
|
return (_data, context) => {
|
|
98
|
-
if (
|
|
98
|
+
if (context?.instancePath === void 0) {
|
|
99
99
|
return false;
|
|
100
100
|
}
|
|
101
101
|
const normalizedPath = normalizeAjvPath(context.instancePath);
|
|
@@ -115,13 +115,12 @@ function compileConfigSchemas(schemas, options) {
|
|
|
115
115
|
traverse__default.default(
|
|
116
116
|
merged,
|
|
117
117
|
(schema, jsonPtr, _1, _2, _3, parentSchema) => {
|
|
118
|
-
|
|
119
|
-
(_b = schema[inheritedVisibility]) != null ? _b : schema[inheritedVisibility] = (_a = schema == null ? void 0 : schema.deepVisibility) != null ? _a : parentSchema == null ? void 0 : parentSchema[inheritedVisibility];
|
|
118
|
+
schema[inheritedVisibility] ??= schema?.deepVisibility ?? parentSchema?.[inheritedVisibility];
|
|
120
119
|
if (schema[inheritedVisibility]) {
|
|
121
120
|
const values = [
|
|
122
121
|
schema.visibility,
|
|
123
122
|
schema[inheritedVisibility],
|
|
124
|
-
parentSchema
|
|
123
|
+
parentSchema?.[inheritedVisibility]
|
|
125
124
|
];
|
|
126
125
|
const hasFrontend = values.some((e) => e === "frontend");
|
|
127
126
|
const hasSecret = values.some((e) => e === "secret");
|
|
@@ -131,9 +130,9 @@ function compileConfigSchemas(schemas, options) {
|
|
|
131
130
|
);
|
|
132
131
|
}
|
|
133
132
|
}
|
|
134
|
-
if (options
|
|
135
|
-
if (
|
|
136
|
-
schema.additionalProperties
|
|
133
|
+
if (options?.noUndeclaredProperties) {
|
|
134
|
+
if (schema?.type === "object") {
|
|
135
|
+
schema.additionalProperties ||= false;
|
|
137
136
|
}
|
|
138
137
|
}
|
|
139
138
|
}
|
|
@@ -149,14 +148,13 @@ function compileConfigSchemas(schemas, options) {
|
|
|
149
148
|
}
|
|
150
149
|
});
|
|
151
150
|
return (configs) => {
|
|
152
|
-
var _a;
|
|
153
151
|
const config$1 = config.ConfigReader.fromConfigs(configs).getOptional();
|
|
154
152
|
visibilityByDataPath.clear();
|
|
155
153
|
deepVisibilityByDataPath.clear();
|
|
156
154
|
const valid = validate(config$1);
|
|
157
155
|
if (!valid) {
|
|
158
156
|
return {
|
|
159
|
-
errors:
|
|
157
|
+
errors: validate.errors ?? [],
|
|
160
158
|
visibilityByDataPath: new Map(visibilityByDataPath),
|
|
161
159
|
deepVisibilityByDataPath: new Map(deepVisibilityByDataPath),
|
|
162
160
|
visibilityBySchemaPath,
|
|
@@ -211,7 +209,6 @@ async function collectConfigSchemas(packageNames, packagePaths) {
|
|
|
211
209
|
const visitedPackageVersions = /* @__PURE__ */ new Map();
|
|
212
210
|
const currentDir = await fs__default.default.realpath(process.cwd());
|
|
213
211
|
async function processItem(item) {
|
|
214
|
-
var _a, _b, _c, _d;
|
|
215
212
|
let pkgPath = item.packagePath;
|
|
216
213
|
if (pkgPath) {
|
|
217
214
|
const pkgExists = await fs__default.default.pathExists(pkgPath);
|
|
@@ -235,7 +232,7 @@ async function collectConfigSchemas(packageNames, packagePaths) {
|
|
|
235
232
|
}
|
|
236
233
|
const pkg = await fs__default.default.readJson(pkgPath);
|
|
237
234
|
let versions = visitedPackageVersions.get(pkg.name);
|
|
238
|
-
if (versions
|
|
235
|
+
if (versions?.has(pkg.version)) {
|
|
239
236
|
return;
|
|
240
237
|
}
|
|
241
238
|
if (!versions) {
|
|
@@ -244,10 +241,10 @@ async function collectConfigSchemas(packageNames, packagePaths) {
|
|
|
244
241
|
}
|
|
245
242
|
versions.add(pkg.version);
|
|
246
243
|
const depNames = [
|
|
247
|
-
...Object.keys(
|
|
248
|
-
...Object.keys(
|
|
249
|
-
...Object.keys(
|
|
250
|
-
...Object.keys(
|
|
244
|
+
...Object.keys(pkg.dependencies ?? {}),
|
|
245
|
+
...Object.keys(pkg.devDependencies ?? {}),
|
|
246
|
+
...Object.keys(pkg.optionalDependencies ?? {}),
|
|
247
|
+
...Object.keys(pkg.peerDependencies ?? {})
|
|
251
248
|
];
|
|
252
249
|
const hasSchema = "configSchema" in pkg;
|
|
253
250
|
const hasBackstageDep = depNames.some((_) => _.startsWith("@backstage/"));
|
|
@@ -319,7 +316,6 @@ async function compileTsSchemas(paths) {
|
|
|
319
316
|
types: []
|
|
320
317
|
});
|
|
321
318
|
const tsSchemas = paths.map((path$1) => {
|
|
322
|
-
var _a;
|
|
323
319
|
let value;
|
|
324
320
|
try {
|
|
325
321
|
const generator = buildGenerator(
|
|
@@ -332,8 +328,8 @@ async function compileTsSchemas(paths) {
|
|
|
332
328
|
[path$1.split(path.sep).join("/")]
|
|
333
329
|
// Unix paths are expected for all OSes here
|
|
334
330
|
);
|
|
335
|
-
value = generator
|
|
336
|
-
const userSymbols = new Set(generator
|
|
331
|
+
value = generator?.getSchemaForSymbol("Config");
|
|
332
|
+
const userSymbols = new Set(generator?.getUserSymbols());
|
|
337
333
|
userSymbols.delete("Config");
|
|
338
334
|
if (userSymbols.size !== 0) {
|
|
339
335
|
const names = Array.from(userSymbols).join("', '");
|
|
@@ -341,7 +337,7 @@ async function compileTsSchemas(paths) {
|
|
|
341
337
|
`Invalid configuration schema in ${path$1}, additional symbol definitions are not allowed, found '${names}'`
|
|
342
338
|
);
|
|
343
339
|
}
|
|
344
|
-
const reffedDefs = Object.keys(
|
|
340
|
+
const reffedDefs = Object.keys(generator?.ReffedDefinitions ?? {});
|
|
345
341
|
if (reffedDefs.length !== 0) {
|
|
346
342
|
const lines = reffedDefs.join(`${os.EOL} `);
|
|
347
343
|
throw new Error(
|
|
@@ -363,14 +359,12 @@ async function compileTsSchemas(paths) {
|
|
|
363
359
|
}
|
|
364
360
|
|
|
365
361
|
function filterByVisibility(data, includeVisibilities, visibilityByDataPath, deepVisibilityByDataPath, deprecationByDataPath, transformFunc, withFilteredKeys, withDeprecatedKeys) {
|
|
366
|
-
var _a;
|
|
367
362
|
const filteredKeys = new Array();
|
|
368
363
|
const deprecatedKeys = new Array();
|
|
369
364
|
function transform(jsonVal, visibilityPath, filterPath, inheritedVisibility) {
|
|
370
|
-
|
|
371
|
-
const visibility = (_a2 = visibilityByDataPath.get(visibilityPath)) != null ? _a2 : inheritedVisibility;
|
|
365
|
+
const visibility = visibilityByDataPath.get(visibilityPath) ?? inheritedVisibility;
|
|
372
366
|
const isVisible = includeVisibilities.includes(visibility);
|
|
373
|
-
const newInheritedVisibility =
|
|
367
|
+
const newInheritedVisibility = deepVisibilityByDataPath.get(visibilityPath) ?? inheritedVisibility;
|
|
374
368
|
const deprecation = deprecationByDataPath.get(visibilityPath);
|
|
375
369
|
if (deprecation) {
|
|
376
370
|
deprecatedKeys.push({ key: filterPath, description: deprecation });
|
|
@@ -438,7 +432,7 @@ function filterByVisibility(data, includeVisibilities, visibilityByDataPath, dee
|
|
|
438
432
|
return {
|
|
439
433
|
filteredKeys: withFilteredKeys ? filteredKeys : void 0,
|
|
440
434
|
deprecatedKeys: withDeprecatedKeys ? deprecatedKeys : void 0,
|
|
441
|
-
data:
|
|
435
|
+
data: transform(data, "", "", DEFAULT_CONFIG_VISIBILITY) ?? {}
|
|
442
436
|
};
|
|
443
437
|
}
|
|
444
438
|
function filterErrorsByVisibility(errors, includeVisibilities, visibilityByDataPath, visibilityBySchemaPath) {
|
|
@@ -450,7 +444,6 @@ function filterErrorsByVisibility(errors, includeVisibilities, visibilityByDataP
|
|
|
450
444
|
}
|
|
451
445
|
const visibleSchemaPaths = Array.from(visibilityBySchemaPath).filter(([, v]) => includeVisibilities.includes(v)).map(([k]) => k);
|
|
452
446
|
return errors.filter((error) => {
|
|
453
|
-
var _a;
|
|
454
447
|
if (error.keyword === "type" && ["object", "array"].includes(error.params.type)) {
|
|
455
448
|
return true;
|
|
456
449
|
}
|
|
@@ -464,7 +457,7 @@ function filterErrorsByVisibility(errors, includeVisibilities, visibilityByDataP
|
|
|
464
457
|
return true;
|
|
465
458
|
}
|
|
466
459
|
}
|
|
467
|
-
const vis =
|
|
460
|
+
const vis = visibilityByDataPath.get(normalizeAjvPath(error.instancePath)) ?? DEFAULT_CONFIG_VISIBILITY;
|
|
468
461
|
return vis && includeVisibilities.includes(vis);
|
|
469
462
|
});
|
|
470
463
|
}
|
|
@@ -481,16 +474,15 @@ function errorsToError(errors) {
|
|
|
481
474
|
return error;
|
|
482
475
|
}
|
|
483
476
|
async function loadConfigSchema(options) {
|
|
484
|
-
var _a;
|
|
485
477
|
let schemas;
|
|
486
478
|
if ("dependencies" in options) {
|
|
487
479
|
schemas = await collectConfigSchemas(
|
|
488
480
|
options.dependencies,
|
|
489
|
-
|
|
481
|
+
options.packagePaths ?? []
|
|
490
482
|
);
|
|
491
483
|
} else {
|
|
492
484
|
const { serialized } = options;
|
|
493
|
-
if (
|
|
485
|
+
if (serialized?.backstageConfigSchemaVersion !== 1) {
|
|
494
486
|
throw new Error(
|
|
495
487
|
"Serialized configuration schema is invalid or has an invalid version number"
|
|
496
488
|
);
|
|
@@ -572,8 +564,7 @@ class EnvConfigSource {
|
|
|
572
564
|
* @returns A new config source that reads from the environment.
|
|
573
565
|
*/
|
|
574
566
|
static create(options) {
|
|
575
|
-
|
|
576
|
-
return new EnvConfigSource((_a = options == null ? void 0 : options.env) != null ? _a : process.env);
|
|
567
|
+
return new EnvConfigSource(options?.env ?? process.env);
|
|
577
568
|
}
|
|
578
569
|
async *readConfigData() {
|
|
579
570
|
const configs = readEnvConfig(this.env);
|
|
@@ -590,7 +581,6 @@ class EnvConfigSource {
|
|
|
590
581
|
const ENV_PREFIX = "APP_CONFIG_";
|
|
591
582
|
const CONFIG_KEY_PART_PATTERN = /^[a-z][a-z0-9]*(?:[-_][a-z][a-z0-9]*)*$/i;
|
|
592
583
|
function readEnvConfig(env) {
|
|
593
|
-
var _a;
|
|
594
584
|
let data = void 0;
|
|
595
585
|
for (const [name, value] of Object.entries(env)) {
|
|
596
586
|
if (!value) {
|
|
@@ -599,13 +589,13 @@ function readEnvConfig(env) {
|
|
|
599
589
|
if (name.startsWith(ENV_PREFIX)) {
|
|
600
590
|
const key = name.replace(ENV_PREFIX, "");
|
|
601
591
|
const keyParts = key.split("_");
|
|
602
|
-
let obj = data = data
|
|
592
|
+
let obj = data = data ?? {};
|
|
603
593
|
for (const [index, part] of keyParts.entries()) {
|
|
604
594
|
if (!CONFIG_KEY_PART_PATTERN.test(part)) {
|
|
605
595
|
throw new TypeError(`Invalid env config key '${key}'`);
|
|
606
596
|
}
|
|
607
597
|
if (index < keyParts.length - 1) {
|
|
608
|
-
obj = obj[part] =
|
|
598
|
+
obj = obj[part] = obj[part] ?? {};
|
|
609
599
|
if (typeof obj !== "object" || Array.isArray(obj)) {
|
|
610
600
|
const subKey = keyParts.slice(0, index + 1).join("_");
|
|
611
601
|
throw new TypeError(
|
|
@@ -780,7 +770,6 @@ function createIncludeTransform(env, readFile, substitute) {
|
|
|
780
770
|
|
|
781
771
|
async function applyConfigTransforms(input, context, transforms) {
|
|
782
772
|
async function transform(inputObj, path, baseDir) {
|
|
783
|
-
var _a;
|
|
784
773
|
let obj = inputObj;
|
|
785
774
|
let dir = baseDir;
|
|
786
775
|
for (const tf of transforms) {
|
|
@@ -791,7 +780,7 @@ async function applyConfigTransforms(input, context, transforms) {
|
|
|
791
780
|
return void 0;
|
|
792
781
|
}
|
|
793
782
|
obj = result.value;
|
|
794
|
-
dir =
|
|
783
|
+
dir = result?.newDir ?? dir;
|
|
795
784
|
break;
|
|
796
785
|
}
|
|
797
786
|
} catch (error) {
|
|
@@ -824,7 +813,7 @@ async function applyConfigTransforms(input, context, transforms) {
|
|
|
824
813
|
}
|
|
825
814
|
return out;
|
|
826
815
|
}
|
|
827
|
-
const finalData = await transform(input, "", context
|
|
816
|
+
const finalData = await transform(input, "", context?.dir);
|
|
828
817
|
if (!isObject(finalData)) {
|
|
829
818
|
throw new TypeError("expected object at config root");
|
|
830
819
|
}
|
|
@@ -832,10 +821,7 @@ async function applyConfigTransforms(input, context, transforms) {
|
|
|
832
821
|
}
|
|
833
822
|
function createConfigTransformer(options) {
|
|
834
823
|
const {
|
|
835
|
-
substitutionFunc = async (name) =>
|
|
836
|
-
var _a;
|
|
837
|
-
return (_a = process.env[name]) == null ? void 0 : _a.trim();
|
|
838
|
-
},
|
|
824
|
+
substitutionFunc = async (name) => process.env[name]?.trim(),
|
|
839
825
|
readFile
|
|
840
826
|
} = options;
|
|
841
827
|
const substitutionTransform = createSubstitutionTransform(substitutionFunc);
|
|
@@ -848,32 +834,9 @@ function createConfigTransformer(options) {
|
|
|
848
834
|
);
|
|
849
835
|
transforms.push(includeTransform);
|
|
850
836
|
}
|
|
851
|
-
return async (input, ctx) => applyConfigTransforms(input, ctx
|
|
837
|
+
return async (input, ctx) => applyConfigTransforms(input, ctx ?? {}, transforms);
|
|
852
838
|
}
|
|
853
839
|
|
|
854
|
-
var __accessCheck$3 = (obj, member, msg) => {
|
|
855
|
-
if (!member.has(obj))
|
|
856
|
-
throw TypeError("Cannot " + msg);
|
|
857
|
-
};
|
|
858
|
-
var __privateGet$2 = (obj, member, getter) => {
|
|
859
|
-
__accessCheck$3(obj, member, "read from private field");
|
|
860
|
-
return getter ? getter.call(obj) : member.get(obj);
|
|
861
|
-
};
|
|
862
|
-
var __privateAdd$3 = (obj, member, value) => {
|
|
863
|
-
if (member.has(obj))
|
|
864
|
-
throw TypeError("Cannot add the same private member more than once");
|
|
865
|
-
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
866
|
-
};
|
|
867
|
-
var __privateSet$2 = (obj, member, value, setter) => {
|
|
868
|
-
__accessCheck$3(obj, member, "write to private field");
|
|
869
|
-
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
870
|
-
return value;
|
|
871
|
-
};
|
|
872
|
-
var __privateMethod$2 = (obj, member, method) => {
|
|
873
|
-
__accessCheck$3(obj, member, "access private method");
|
|
874
|
-
return method;
|
|
875
|
-
};
|
|
876
|
-
var _path, _substitutionFunc, _watch, _waitForEvent, waitForEvent_fn;
|
|
877
840
|
async function readFile(path) {
|
|
878
841
|
try {
|
|
879
842
|
const content = await fs__default.default.readFile(path, "utf8");
|
|
@@ -889,17 +852,7 @@ async function readFile(path) {
|
|
|
889
852
|
throw error;
|
|
890
853
|
}
|
|
891
854
|
}
|
|
892
|
-
|
|
893
|
-
constructor(options) {
|
|
894
|
-
__privateAdd$3(this, _waitForEvent);
|
|
895
|
-
__privateAdd$3(this, _path, void 0);
|
|
896
|
-
__privateAdd$3(this, _substitutionFunc, void 0);
|
|
897
|
-
__privateAdd$3(this, _watch, void 0);
|
|
898
|
-
var _a;
|
|
899
|
-
__privateSet$2(this, _path, options.path);
|
|
900
|
-
__privateSet$2(this, _substitutionFunc, options.substitutionFunc);
|
|
901
|
-
__privateSet$2(this, _watch, (_a = options.watch) != null ? _a : true);
|
|
902
|
-
}
|
|
855
|
+
class FileConfigSource {
|
|
903
856
|
/**
|
|
904
857
|
* Creates a new config source that loads configuration from the given path.
|
|
905
858
|
*
|
|
@@ -914,25 +867,33 @@ const _FileConfigSource = class _FileConfigSource {
|
|
|
914
867
|
if (!path.isAbsolute(options.path)) {
|
|
915
868
|
throw new Error(`Config load path is not absolute: "${options.path}"`);
|
|
916
869
|
}
|
|
917
|
-
return new
|
|
870
|
+
return new FileConfigSource(options);
|
|
871
|
+
}
|
|
872
|
+
#path;
|
|
873
|
+
#substitutionFunc;
|
|
874
|
+
#watch;
|
|
875
|
+
constructor(options) {
|
|
876
|
+
this.#path = options.path;
|
|
877
|
+
this.#substitutionFunc = options.substitutionFunc;
|
|
878
|
+
this.#watch = options.watch ?? true;
|
|
918
879
|
}
|
|
919
880
|
// Work is duplicated across each read, in practice that should not
|
|
920
881
|
// have any impact since there won't be multiple consumers. If that
|
|
921
882
|
// changes it might be worth refactoring this to avoid duplicate work.
|
|
922
883
|
async *readConfigData(options) {
|
|
923
|
-
const signal = options
|
|
924
|
-
const configFileName = path.basename(
|
|
884
|
+
const signal = options?.signal;
|
|
885
|
+
const configFileName = path.basename(this.#path);
|
|
925
886
|
let watchedPaths = null;
|
|
926
887
|
let watcher = null;
|
|
927
|
-
if (
|
|
888
|
+
if (this.#watch) {
|
|
928
889
|
watchedPaths = new Array();
|
|
929
|
-
watcher = chokidar__default.default.watch(
|
|
890
|
+
watcher = chokidar__default.default.watch(this.#path, {
|
|
930
891
|
usePolling: process.env.NODE_ENV === "test"
|
|
931
892
|
});
|
|
932
893
|
}
|
|
933
|
-
const dir = path.dirname(
|
|
894
|
+
const dir = path.dirname(this.#path);
|
|
934
895
|
const transformer = createConfigTransformer({
|
|
935
|
-
substitutionFunc:
|
|
896
|
+
substitutionFunc: this.#substitutionFunc,
|
|
936
897
|
readFile: async (path$1) => {
|
|
937
898
|
const fullPath = path.resolve(dir, path$1);
|
|
938
899
|
if (watcher && watchedPaths) {
|
|
@@ -952,12 +913,12 @@ const _FileConfigSource = class _FileConfigSource {
|
|
|
952
913
|
if (watcher && watchedPaths) {
|
|
953
914
|
watcher.unwatch(watchedPaths);
|
|
954
915
|
watchedPaths.length = 0;
|
|
955
|
-
watcher.add(
|
|
956
|
-
watchedPaths.push(
|
|
916
|
+
watcher.add(this.#path);
|
|
917
|
+
watchedPaths.push(this.#path);
|
|
957
918
|
}
|
|
958
|
-
const content = await readFile(
|
|
919
|
+
const content = await readFile(this.#path);
|
|
959
920
|
if (content === void 0) {
|
|
960
|
-
throw new errors.NotFoundError(`Config file "${
|
|
921
|
+
throw new errors.NotFoundError(`Config file "${this.#path}" does not exist`);
|
|
961
922
|
}
|
|
962
923
|
const parsed = yaml__default.default.parse(content);
|
|
963
924
|
if (parsed === null) {
|
|
@@ -965,23 +926,23 @@ const _FileConfigSource = class _FileConfigSource {
|
|
|
965
926
|
}
|
|
966
927
|
try {
|
|
967
928
|
const data = await transformer(parsed, { dir });
|
|
968
|
-
return [{ data, context: configFileName, path:
|
|
929
|
+
return [{ data, context: configFileName, path: this.#path }];
|
|
969
930
|
} catch (error) {
|
|
970
931
|
throw new Error(
|
|
971
|
-
`Failed to read config file at "${
|
|
932
|
+
`Failed to read config file at "${this.#path}", ${error.message}`
|
|
972
933
|
);
|
|
973
934
|
}
|
|
974
935
|
};
|
|
975
936
|
const onAbort = () => {
|
|
976
|
-
signal
|
|
937
|
+
signal?.removeEventListener("abort", onAbort);
|
|
977
938
|
if (watcher)
|
|
978
939
|
watcher.close();
|
|
979
940
|
};
|
|
980
|
-
signal
|
|
941
|
+
signal?.addEventListener("abort", onAbort);
|
|
981
942
|
yield { configs: await readConfigFile() };
|
|
982
943
|
if (watcher) {
|
|
983
944
|
for (; ; ) {
|
|
984
|
-
const event = await
|
|
945
|
+
const event = await this.#waitForEvent(watcher, signal);
|
|
985
946
|
if (event === "abort") {
|
|
986
947
|
return;
|
|
987
948
|
}
|
|
@@ -990,65 +951,51 @@ const _FileConfigSource = class _FileConfigSource {
|
|
|
990
951
|
}
|
|
991
952
|
}
|
|
992
953
|
toString() {
|
|
993
|
-
return `FileConfigSource{path="${
|
|
954
|
+
return `FileConfigSource{path="${this.#path}"}`;
|
|
994
955
|
}
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
watcher.addListener("change", onChange);
|
|
1015
|
-
signal == null ? void 0 : signal.addEventListener("abort", onAbort);
|
|
1016
|
-
});
|
|
1017
|
-
};
|
|
1018
|
-
let FileConfigSource = _FileConfigSource;
|
|
956
|
+
#waitForEvent(watcher, signal) {
|
|
957
|
+
return new Promise((resolve) => {
|
|
958
|
+
function onChange() {
|
|
959
|
+
resolve("change");
|
|
960
|
+
onDone();
|
|
961
|
+
}
|
|
962
|
+
function onAbort() {
|
|
963
|
+
resolve("abort");
|
|
964
|
+
onDone();
|
|
965
|
+
}
|
|
966
|
+
function onDone() {
|
|
967
|
+
watcher.removeListener("change", onChange);
|
|
968
|
+
signal?.removeEventListener("abort", onAbort);
|
|
969
|
+
}
|
|
970
|
+
watcher.addListener("change", onChange);
|
|
971
|
+
signal?.addEventListener("abort", onAbort);
|
|
972
|
+
});
|
|
973
|
+
}
|
|
974
|
+
}
|
|
1019
975
|
|
|
1020
|
-
var __defProp$1 = Object.defineProperty;
|
|
1021
|
-
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1022
|
-
var __publicField$1 = (obj, key, value) => {
|
|
1023
|
-
__defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1024
|
-
return value;
|
|
1025
|
-
};
|
|
1026
|
-
var __accessCheck$2 = (obj, member, msg) => {
|
|
1027
|
-
if (!member.has(obj))
|
|
1028
|
-
throw TypeError("Cannot " + msg);
|
|
1029
|
-
};
|
|
1030
|
-
var __privateAdd$2 = (obj, member, value) => {
|
|
1031
|
-
if (member.has(obj))
|
|
1032
|
-
throw TypeError("Cannot add the same private member more than once");
|
|
1033
|
-
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
1034
|
-
};
|
|
1035
|
-
var __privateMethod$1 = (obj, member, method) => {
|
|
1036
|
-
__accessCheck$2(obj, member, "access private method");
|
|
1037
|
-
return method;
|
|
1038
|
-
};
|
|
1039
|
-
var _flattenSources, flattenSources_fn, _a;
|
|
1040
976
|
const sourcesSymbol = Symbol.for(
|
|
1041
977
|
"@backstage/config-loader#MergedConfigSource.sources"
|
|
1042
978
|
);
|
|
1043
|
-
|
|
979
|
+
class MergedConfigSource {
|
|
1044
980
|
constructor(sources) {
|
|
1045
981
|
this.sources = sources;
|
|
1046
|
-
__publicField$1(this, _a);
|
|
1047
982
|
this[sourcesSymbol] = this.sources;
|
|
1048
983
|
}
|
|
984
|
+
// An optimization to flatten nested merged sources to avid unnecessary microtasks
|
|
985
|
+
static #flattenSources(sources) {
|
|
986
|
+
return sources.flatMap((source) => {
|
|
987
|
+
if (sourcesSymbol in source && Array.isArray(source[sourcesSymbol])) {
|
|
988
|
+
return this.#flattenSources(
|
|
989
|
+
source[sourcesSymbol]
|
|
990
|
+
);
|
|
991
|
+
}
|
|
992
|
+
return source;
|
|
993
|
+
});
|
|
994
|
+
}
|
|
1049
995
|
static from(sources) {
|
|
1050
|
-
return new
|
|
996
|
+
return new MergedConfigSource(this.#flattenSources(sources));
|
|
1051
997
|
}
|
|
998
|
+
[sourcesSymbol];
|
|
1052
999
|
async *readConfigData(options) {
|
|
1053
1000
|
const its = this.sources.map((source) => source.readConfigData(options));
|
|
1054
1001
|
const initialResults = await Promise.all(its.map((it) => it.next()));
|
|
@@ -1084,20 +1031,7 @@ const _MergedConfigSource = class _MergedConfigSource {
|
|
|
1084
1031
|
toString() {
|
|
1085
1032
|
return `MergedConfigSource{${this.sources.map(String).join(", ")}}`;
|
|
1086
1033
|
}
|
|
1087
|
-
}
|
|
1088
|
-
_a = sourcesSymbol;
|
|
1089
|
-
_flattenSources = new WeakSet();
|
|
1090
|
-
flattenSources_fn = function(sources) {
|
|
1091
|
-
return sources.flatMap((source) => {
|
|
1092
|
-
if (sourcesSymbol in source && Array.isArray(source[sourcesSymbol])) {
|
|
1093
|
-
return __privateMethod$1(this, _flattenSources, flattenSources_fn).call(this, source[sourcesSymbol]);
|
|
1094
|
-
}
|
|
1095
|
-
return source;
|
|
1096
|
-
});
|
|
1097
|
-
};
|
|
1098
|
-
// An optimization to flatten nested merged sources to avid unnecessary microtasks
|
|
1099
|
-
__privateAdd$2(_MergedConfigSource, _flattenSources);
|
|
1100
|
-
let MergedConfigSource = _MergedConfigSource;
|
|
1034
|
+
}
|
|
1101
1035
|
function nextWithIndex(iterator, index) {
|
|
1102
1036
|
return iterator.next().then(
|
|
1103
1037
|
(r) => [index, r],
|
|
@@ -1107,46 +1041,8 @@ function nextWithIndex(iterator, index) {
|
|
|
1107
1041
|
);
|
|
1108
1042
|
}
|
|
1109
1043
|
|
|
1110
|
-
var __accessCheck$1 = (obj, member, msg) => {
|
|
1111
|
-
if (!member.has(obj))
|
|
1112
|
-
throw TypeError("Cannot " + msg);
|
|
1113
|
-
};
|
|
1114
|
-
var __privateGet$1 = (obj, member, getter) => {
|
|
1115
|
-
__accessCheck$1(obj, member, "read from private field");
|
|
1116
|
-
return getter ? getter.call(obj) : member.get(obj);
|
|
1117
|
-
};
|
|
1118
|
-
var __privateAdd$1 = (obj, member, value) => {
|
|
1119
|
-
if (member.has(obj))
|
|
1120
|
-
throw TypeError("Cannot add the same private member more than once");
|
|
1121
|
-
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
1122
|
-
};
|
|
1123
|
-
var __privateSet$1 = (obj, member, value, setter) => {
|
|
1124
|
-
__accessCheck$1(obj, member, "write to private field");
|
|
1125
|
-
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
1126
|
-
return value;
|
|
1127
|
-
};
|
|
1128
|
-
var __privateMethod = (obj, member, method) => {
|
|
1129
|
-
__accessCheck$1(obj, member, "access private method");
|
|
1130
|
-
return method;
|
|
1131
|
-
};
|
|
1132
|
-
var _url, _reloadIntervalMs, _transformer, _load, load_fn, _wait, wait_fn;
|
|
1133
1044
|
const DEFAULT_RELOAD_INTERVAL = { seconds: 60 };
|
|
1134
|
-
|
|
1135
|
-
constructor(options) {
|
|
1136
|
-
__privateAdd$1(this, _load);
|
|
1137
|
-
__privateAdd$1(this, _wait);
|
|
1138
|
-
__privateAdd$1(this, _url, void 0);
|
|
1139
|
-
__privateAdd$1(this, _reloadIntervalMs, void 0);
|
|
1140
|
-
__privateAdd$1(this, _transformer, void 0);
|
|
1141
|
-
var _a;
|
|
1142
|
-
__privateSet$1(this, _url, options.url);
|
|
1143
|
-
__privateSet$1(this, _reloadIntervalMs, types.durationToMilliseconds(
|
|
1144
|
-
(_a = options.reloadInterval) != null ? _a : DEFAULT_RELOAD_INTERVAL
|
|
1145
|
-
));
|
|
1146
|
-
__privateSet$1(this, _transformer, createConfigTransformer({
|
|
1147
|
-
substitutionFunc: options.substitutionFunc
|
|
1148
|
-
}));
|
|
1149
|
-
}
|
|
1045
|
+
class RemoteConfigSource {
|
|
1150
1046
|
/**
|
|
1151
1047
|
* Creates a new {@link RemoteConfigSource}.
|
|
1152
1048
|
*
|
|
@@ -1161,89 +1057,88 @@ const _RemoteConfigSource = class _RemoteConfigSource {
|
|
|
1161
1057
|
`Invalid URL provided to remote config source, '${options.url}', ${error}`
|
|
1162
1058
|
);
|
|
1163
1059
|
}
|
|
1164
|
-
return new
|
|
1060
|
+
return new RemoteConfigSource(options);
|
|
1061
|
+
}
|
|
1062
|
+
#url;
|
|
1063
|
+
#reloadIntervalMs;
|
|
1064
|
+
#transformer;
|
|
1065
|
+
constructor(options) {
|
|
1066
|
+
this.#url = options.url;
|
|
1067
|
+
this.#reloadIntervalMs = types.durationToMilliseconds(
|
|
1068
|
+
options.reloadInterval ?? DEFAULT_RELOAD_INTERVAL
|
|
1069
|
+
);
|
|
1070
|
+
this.#transformer = createConfigTransformer({
|
|
1071
|
+
substitutionFunc: options.substitutionFunc
|
|
1072
|
+
});
|
|
1165
1073
|
}
|
|
1166
1074
|
async *readConfigData(options) {
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
yield { configs: [{ data, context: __privateGet$1(this, _url) }] };
|
|
1075
|
+
let data = await this.#load();
|
|
1076
|
+
yield { configs: [{ data, context: this.#url }] };
|
|
1170
1077
|
for (; ; ) {
|
|
1171
|
-
await
|
|
1172
|
-
if (
|
|
1078
|
+
await this.#wait(options?.signal);
|
|
1079
|
+
if (options?.signal?.aborted) {
|
|
1173
1080
|
return;
|
|
1174
1081
|
}
|
|
1175
1082
|
try {
|
|
1176
|
-
const newData = await
|
|
1083
|
+
const newData = await this.#load(options?.signal);
|
|
1177
1084
|
if (newData && !isEqual__default.default(data, newData)) {
|
|
1178
1085
|
data = newData;
|
|
1179
|
-
yield { configs: [{ data, context:
|
|
1086
|
+
yield { configs: [{ data, context: this.#url }] };
|
|
1180
1087
|
}
|
|
1181
1088
|
} catch (error) {
|
|
1182
1089
|
if (error.name !== "AbortError") {
|
|
1183
|
-
console.error(`Failed to read config from ${
|
|
1090
|
+
console.error(`Failed to read config from ${this.#url}, ${error}`);
|
|
1184
1091
|
}
|
|
1185
1092
|
}
|
|
1186
1093
|
}
|
|
1187
1094
|
}
|
|
1188
1095
|
toString() {
|
|
1189
|
-
return `RemoteConfigSource{path="${
|
|
1096
|
+
return `RemoteConfigSource{path="${this.#url}"}`;
|
|
1190
1097
|
}
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
throw new Error("configuration data is not an object");
|
|
1209
|
-
} else if (Array.isArray(data)) {
|
|
1210
|
-
throw new Error(
|
|
1211
|
-
"configuration data is an array, expected an object instead"
|
|
1212
|
-
);
|
|
1213
|
-
}
|
|
1214
|
-
return data;
|
|
1215
|
-
};
|
|
1216
|
-
_wait = new WeakSet();
|
|
1217
|
-
wait_fn = async function(signal) {
|
|
1218
|
-
return new Promise((resolve) => {
|
|
1219
|
-
const timeoutId = setTimeout(onDone, __privateGet$1(this, _reloadIntervalMs));
|
|
1220
|
-
signal == null ? void 0 : signal.addEventListener("abort", onDone);
|
|
1221
|
-
function onDone() {
|
|
1222
|
-
clearTimeout(timeoutId);
|
|
1223
|
-
signal == null ? void 0 : signal.removeEventListener("abort", onDone);
|
|
1224
|
-
resolve();
|
|
1098
|
+
async #load(signal) {
|
|
1099
|
+
const res = await fetch__default.default(this.#url, {
|
|
1100
|
+
signal
|
|
1101
|
+
});
|
|
1102
|
+
if (!res.ok) {
|
|
1103
|
+
throw await errors.ResponseError.fromResponse(res);
|
|
1104
|
+
}
|
|
1105
|
+
const content = await res.text();
|
|
1106
|
+
const data = await this.#transformer(yaml__default.default.parse(content));
|
|
1107
|
+
if (data === null) {
|
|
1108
|
+
throw new Error("configuration data is null");
|
|
1109
|
+
} else if (typeof data !== "object") {
|
|
1110
|
+
throw new Error("configuration data is not an object");
|
|
1111
|
+
} else if (Array.isArray(data)) {
|
|
1112
|
+
throw new Error(
|
|
1113
|
+
"configuration data is an array, expected an object instead"
|
|
1114
|
+
);
|
|
1225
1115
|
}
|
|
1226
|
-
|
|
1227
|
-
}
|
|
1228
|
-
|
|
1116
|
+
return data;
|
|
1117
|
+
}
|
|
1118
|
+
async #wait(signal) {
|
|
1119
|
+
return new Promise((resolve) => {
|
|
1120
|
+
const timeoutId = setTimeout(onDone, this.#reloadIntervalMs);
|
|
1121
|
+
signal?.addEventListener("abort", onDone);
|
|
1122
|
+
function onDone() {
|
|
1123
|
+
clearTimeout(timeoutId);
|
|
1124
|
+
signal?.removeEventListener("abort", onDone);
|
|
1125
|
+
resolve();
|
|
1126
|
+
}
|
|
1127
|
+
});
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1229
1130
|
|
|
1230
|
-
var __defProp = Object.defineProperty;
|
|
1231
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1232
|
-
var __publicField = (obj, key, value) => {
|
|
1233
|
-
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1234
|
-
return value;
|
|
1235
|
-
};
|
|
1236
1131
|
class ObservableConfigProxy {
|
|
1237
1132
|
constructor(parent, parentKey, abortController) {
|
|
1238
1133
|
this.parent = parent;
|
|
1239
1134
|
this.parentKey = parentKey;
|
|
1240
1135
|
this.abortController = abortController;
|
|
1241
|
-
__publicField(this, "config", new config.ConfigReader({}));
|
|
1242
|
-
__publicField(this, "subscribers", []);
|
|
1243
1136
|
if (parent && !parentKey) {
|
|
1244
1137
|
throw new Error("parentKey is required if parent is set");
|
|
1245
1138
|
}
|
|
1246
1139
|
}
|
|
1140
|
+
config = new config.ConfigReader({});
|
|
1141
|
+
subscribers = [];
|
|
1247
1142
|
static create(abortController) {
|
|
1248
1143
|
return new ObservableConfigProxy(void 0, void 0, abortController);
|
|
1249
1144
|
}
|
|
@@ -1284,36 +1179,31 @@ class ObservableConfigProxy {
|
|
|
1284
1179
|
};
|
|
1285
1180
|
}
|
|
1286
1181
|
select(required) {
|
|
1287
|
-
var _a;
|
|
1288
1182
|
if (this.parent && this.parentKey) {
|
|
1289
1183
|
if (required) {
|
|
1290
1184
|
return this.parent.select(true).getConfig(this.parentKey);
|
|
1291
1185
|
}
|
|
1292
|
-
return
|
|
1186
|
+
return this.parent.select(false)?.getOptionalConfig(this.parentKey);
|
|
1293
1187
|
}
|
|
1294
1188
|
return this.config;
|
|
1295
1189
|
}
|
|
1296
1190
|
has(key) {
|
|
1297
|
-
|
|
1298
|
-
return (_b = (_a = this.select(false)) == null ? void 0 : _a.has(key)) != null ? _b : false;
|
|
1191
|
+
return this.select(false)?.has(key) ?? false;
|
|
1299
1192
|
}
|
|
1300
1193
|
keys() {
|
|
1301
|
-
|
|
1302
|
-
return (_b = (_a = this.select(false)) == null ? void 0 : _a.keys()) != null ? _b : [];
|
|
1194
|
+
return this.select(false)?.keys() ?? [];
|
|
1303
1195
|
}
|
|
1304
1196
|
get(key) {
|
|
1305
1197
|
return this.select(true).get(key);
|
|
1306
1198
|
}
|
|
1307
1199
|
getOptional(key) {
|
|
1308
|
-
|
|
1309
|
-
return (_a = this.select(false)) == null ? void 0 : _a.getOptional(key);
|
|
1200
|
+
return this.select(false)?.getOptional(key);
|
|
1310
1201
|
}
|
|
1311
1202
|
getConfig(key) {
|
|
1312
1203
|
return new ObservableConfigProxy(this, key);
|
|
1313
1204
|
}
|
|
1314
1205
|
getOptionalConfig(key) {
|
|
1315
|
-
|
|
1316
|
-
if ((_a = this.select(false)) == null ? void 0 : _a.has(key)) {
|
|
1206
|
+
if (this.select(false)?.has(key)) {
|
|
1317
1207
|
return new ObservableConfigProxy(this, key);
|
|
1318
1208
|
}
|
|
1319
1209
|
return void 0;
|
|
@@ -1322,36 +1212,31 @@ class ObservableConfigProxy {
|
|
|
1322
1212
|
return this.select(true).getConfigArray(key);
|
|
1323
1213
|
}
|
|
1324
1214
|
getOptionalConfigArray(key) {
|
|
1325
|
-
|
|
1326
|
-
return (_a = this.select(false)) == null ? void 0 : _a.getOptionalConfigArray(key);
|
|
1215
|
+
return this.select(false)?.getOptionalConfigArray(key);
|
|
1327
1216
|
}
|
|
1328
1217
|
getNumber(key) {
|
|
1329
1218
|
return this.select(true).getNumber(key);
|
|
1330
1219
|
}
|
|
1331
1220
|
getOptionalNumber(key) {
|
|
1332
|
-
|
|
1333
|
-
return (_a = this.select(false)) == null ? void 0 : _a.getOptionalNumber(key);
|
|
1221
|
+
return this.select(false)?.getOptionalNumber(key);
|
|
1334
1222
|
}
|
|
1335
1223
|
getBoolean(key) {
|
|
1336
1224
|
return this.select(true).getBoolean(key);
|
|
1337
1225
|
}
|
|
1338
1226
|
getOptionalBoolean(key) {
|
|
1339
|
-
|
|
1340
|
-
return (_a = this.select(false)) == null ? void 0 : _a.getOptionalBoolean(key);
|
|
1227
|
+
return this.select(false)?.getOptionalBoolean(key);
|
|
1341
1228
|
}
|
|
1342
1229
|
getString(key) {
|
|
1343
1230
|
return this.select(true).getString(key);
|
|
1344
1231
|
}
|
|
1345
1232
|
getOptionalString(key) {
|
|
1346
|
-
|
|
1347
|
-
return (_a = this.select(false)) == null ? void 0 : _a.getOptionalString(key);
|
|
1233
|
+
return this.select(false)?.getOptionalString(key);
|
|
1348
1234
|
}
|
|
1349
1235
|
getStringArray(key) {
|
|
1350
1236
|
return this.select(true).getStringArray(key);
|
|
1351
1237
|
}
|
|
1352
1238
|
getOptionalStringArray(key) {
|
|
1353
|
-
|
|
1354
|
-
return (_a = this.select(false)) == null ? void 0 : _a.getOptionalStringArray(key);
|
|
1239
|
+
return this.select(false)?.getOptionalStringArray(key);
|
|
1355
1240
|
}
|
|
1356
1241
|
}
|
|
1357
1242
|
|
|
@@ -1392,8 +1277,7 @@ class ConfigSources {
|
|
|
1392
1277
|
* @returns A config source for the provided targets
|
|
1393
1278
|
*/
|
|
1394
1279
|
static defaultForTargets(options) {
|
|
1395
|
-
|
|
1396
|
-
const rootDir = (_a = options.rootDir) != null ? _a : cliCommon.findPaths(process.cwd()).targetRoot;
|
|
1280
|
+
const rootDir = options.rootDir ?? cliCommon.findPaths(process.cwd()).targetRoot;
|
|
1397
1281
|
const argSources = options.targets.map((arg) => {
|
|
1398
1282
|
if (arg.type === "url") {
|
|
1399
1283
|
if (!options.remote) {
|
|
@@ -1541,35 +1425,7 @@ async function waitOrAbort(promise, signal) {
|
|
|
1541
1425
|
});
|
|
1542
1426
|
}
|
|
1543
1427
|
|
|
1544
|
-
|
|
1545
|
-
if (!member.has(obj))
|
|
1546
|
-
throw TypeError("Cannot " + msg);
|
|
1547
|
-
};
|
|
1548
|
-
var __privateGet = (obj, member, getter) => {
|
|
1549
|
-
__accessCheck(obj, member, "read from private field");
|
|
1550
|
-
return getter ? getter.call(obj) : member.get(obj);
|
|
1551
|
-
};
|
|
1552
|
-
var __privateAdd = (obj, member, value) => {
|
|
1553
|
-
if (member.has(obj))
|
|
1554
|
-
throw TypeError("Cannot add the same private member more than once");
|
|
1555
|
-
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
1556
|
-
};
|
|
1557
|
-
var __privateSet = (obj, member, value, setter) => {
|
|
1558
|
-
__accessCheck(obj, member, "write to private field");
|
|
1559
|
-
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
1560
|
-
return value;
|
|
1561
|
-
};
|
|
1562
|
-
var _currentData, _deferred, _context, _abortController;
|
|
1563
|
-
const _MutableConfigSource = class _MutableConfigSource {
|
|
1564
|
-
constructor(context, initialData) {
|
|
1565
|
-
__privateAdd(this, _currentData, void 0);
|
|
1566
|
-
__privateAdd(this, _deferred, void 0);
|
|
1567
|
-
__privateAdd(this, _context, void 0);
|
|
1568
|
-
__privateAdd(this, _abortController, new AbortController());
|
|
1569
|
-
__privateSet(this, _currentData, initialData);
|
|
1570
|
-
__privateSet(this, _context, context);
|
|
1571
|
-
__privateSet(this, _deferred, simpleDefer());
|
|
1572
|
-
}
|
|
1428
|
+
class MutableConfigSource {
|
|
1573
1429
|
/**
|
|
1574
1430
|
* Creates a new mutable config source.
|
|
1575
1431
|
*
|
|
@@ -1577,29 +1433,37 @@ const _MutableConfigSource = class _MutableConfigSource {
|
|
|
1577
1433
|
* @returns A new mutable config source.
|
|
1578
1434
|
*/
|
|
1579
1435
|
static create(options) {
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
options == null ? void 0 : options.data
|
|
1436
|
+
return new MutableConfigSource(
|
|
1437
|
+
options?.context ?? "mutable-config",
|
|
1438
|
+
options?.data
|
|
1584
1439
|
);
|
|
1585
1440
|
}
|
|
1441
|
+
#currentData;
|
|
1442
|
+
#deferred;
|
|
1443
|
+
#context;
|
|
1444
|
+
#abortController = new AbortController();
|
|
1445
|
+
constructor(context, initialData) {
|
|
1446
|
+
this.#currentData = initialData;
|
|
1447
|
+
this.#context = context;
|
|
1448
|
+
this.#deferred = simpleDefer();
|
|
1449
|
+
}
|
|
1586
1450
|
async *readConfigData(options) {
|
|
1587
|
-
let deferredPromise =
|
|
1588
|
-
if (
|
|
1589
|
-
yield { configs: [{ data:
|
|
1451
|
+
let deferredPromise = this.#deferred.promise;
|
|
1452
|
+
if (this.#currentData !== void 0) {
|
|
1453
|
+
yield { configs: [{ data: this.#currentData, context: this.#context }] };
|
|
1590
1454
|
}
|
|
1591
1455
|
for (; ; ) {
|
|
1592
1456
|
const [ok] = await waitOrAbort(deferredPromise, [
|
|
1593
|
-
options
|
|
1594
|
-
|
|
1457
|
+
options?.signal,
|
|
1458
|
+
this.#abortController.signal
|
|
1595
1459
|
]);
|
|
1596
1460
|
if (!ok) {
|
|
1597
1461
|
return;
|
|
1598
1462
|
}
|
|
1599
|
-
deferredPromise =
|
|
1600
|
-
if (
|
|
1463
|
+
deferredPromise = this.#deferred.promise;
|
|
1464
|
+
if (this.#currentData !== void 0) {
|
|
1601
1465
|
yield {
|
|
1602
|
-
configs: [{ data:
|
|
1466
|
+
configs: [{ data: this.#currentData, context: this.#context }]
|
|
1603
1467
|
};
|
|
1604
1468
|
}
|
|
1605
1469
|
}
|
|
@@ -1610,10 +1474,10 @@ const _MutableConfigSource = class _MutableConfigSource {
|
|
|
1610
1474
|
* @param data - The new data to set
|
|
1611
1475
|
*/
|
|
1612
1476
|
setData(data) {
|
|
1613
|
-
if (!
|
|
1614
|
-
|
|
1615
|
-
const oldDeferred =
|
|
1616
|
-
|
|
1477
|
+
if (!this.#abortController.signal.aborted) {
|
|
1478
|
+
this.#currentData = data;
|
|
1479
|
+
const oldDeferred = this.#deferred;
|
|
1480
|
+
this.#deferred = simpleDefer();
|
|
1617
1481
|
oldDeferred.resolve();
|
|
1618
1482
|
}
|
|
1619
1483
|
}
|
|
@@ -1621,18 +1485,13 @@ const _MutableConfigSource = class _MutableConfigSource {
|
|
|
1621
1485
|
* Close the config source, preventing any further updates.
|
|
1622
1486
|
*/
|
|
1623
1487
|
close() {
|
|
1624
|
-
|
|
1625
|
-
|
|
1488
|
+
this.#currentData = void 0;
|
|
1489
|
+
this.#abortController.abort();
|
|
1626
1490
|
}
|
|
1627
1491
|
toString() {
|
|
1628
1492
|
return `MutableConfigSource{}`;
|
|
1629
1493
|
}
|
|
1630
|
-
}
|
|
1631
|
-
_currentData = new WeakMap();
|
|
1632
|
-
_deferred = new WeakMap();
|
|
1633
|
-
_context = new WeakMap();
|
|
1634
|
-
_abortController = new WeakMap();
|
|
1635
|
-
let MutableConfigSource = _MutableConfigSource;
|
|
1494
|
+
}
|
|
1636
1495
|
|
|
1637
1496
|
class StaticObservableConfigSource {
|
|
1638
1497
|
constructor(data, context) {
|
|
@@ -1652,7 +1511,7 @@ class StaticObservableConfigSource {
|
|
|
1652
1511
|
deferred.resolve();
|
|
1653
1512
|
}
|
|
1654
1513
|
});
|
|
1655
|
-
const signal = options
|
|
1514
|
+
const signal = options?.signal;
|
|
1656
1515
|
if (signal) {
|
|
1657
1516
|
const onAbort = () => {
|
|
1658
1517
|
sub.unsubscribe();
|
|
@@ -1738,21 +1597,20 @@ async function loadConfig(options) {
|
|
|
1738
1597
|
});
|
|
1739
1598
|
return new Promise((resolve, reject) => {
|
|
1740
1599
|
async function loadConfigReaderLoop() {
|
|
1741
|
-
var _a, _b, _c, _d;
|
|
1742
1600
|
let loaded = false;
|
|
1743
1601
|
try {
|
|
1744
1602
|
const abortController = new AbortController();
|
|
1745
|
-
|
|
1603
|
+
options.watch?.stopSignal?.then(() => abortController.abort());
|
|
1746
1604
|
for await (const { configs } of source.readConfigData({
|
|
1747
1605
|
signal: abortController.signal
|
|
1748
1606
|
})) {
|
|
1749
1607
|
if (loaded) {
|
|
1750
|
-
|
|
1608
|
+
options.watch?.onChange(configs);
|
|
1751
1609
|
} else {
|
|
1752
1610
|
resolve({ appConfigs: configs });
|
|
1753
1611
|
loaded = true;
|
|
1754
1612
|
if (options.watch) {
|
|
1755
|
-
|
|
1613
|
+
options.watch.stopSignal?.then(() => abortController.abort());
|
|
1756
1614
|
} else {
|
|
1757
1615
|
abortController.abort();
|
|
1758
1616
|
}
|