@backstage/config-loader
Advanced tools
Comparing version 0.0.0-nightly-20217521743 to 0.0.0-nightly-20218721719
# @backstage/config-loader | ||
## 0.0.0-nightly-20217521743 | ||
## 0.0.0-nightly-20218721719 | ||
### Patch Changes | ||
- d1da88a19: Properly export all used types. | ||
- Updated dependencies | ||
- @backstage/cli-common@0.0.0-nightly-20218721719 | ||
- @backstage/config@0.0.0-nightly-20218721719 | ||
## 0.6.7 | ||
### Patch Changes | ||
- 0ade9d02b: Include `devDependencies` and `optionalDependencies` in the detection of Backstage packages when collecting configuration schema. | ||
- 9b8cec063: Add support for config file watching through a new group of `watch` options to `loadConfig`. | ||
- Updated dependencies | ||
- @backstage/config@0.1.7 | ||
## 0.6.6 | ||
### Patch Changes | ||
- e9d3983ee: Add option to populate the `filteredKeys` property when processing configuration with a schema. | ||
- Updated dependencies | ||
- @backstage/config@0.0.0-nightly-20217521743 | ||
- @backstage/config@0.1.6 | ||
@@ -11,0 +29,0 @@ ## 0.6.5 |
@@ -12,2 +12,3 @@ 'use strict'; | ||
var typescriptJsonSchema = require('typescript-json-schema'); | ||
var chokidar = require('chokidar'); | ||
@@ -20,2 +21,3 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } | ||
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs); | ||
var chokidar__default = /*#__PURE__*/_interopDefaultLegacy(chokidar); | ||
@@ -318,3 +320,3 @@ const ENV_PREFIX = "APP_CONFIG_"; | ||
async function processItem({name, parentPath}) { | ||
var _a, _b; | ||
var _a, _b, _c, _d; | ||
if (visitedPackages.has(name)) { | ||
@@ -335,3 +337,5 @@ return; | ||
...Object.keys((_a = pkg.dependencies) != null ? _a : {}), | ||
...Object.keys((_b = pkg.peerDependencies) != null ? _b : {}) | ||
...Object.keys((_b = pkg.devDependencies) != null ? _b : {}), | ||
...Object.keys((_c = pkg.optionalDependencies) != null ? _c : {}), | ||
...Object.keys((_d = pkg.peerDependencies) != null ? _d : {}) | ||
]; | ||
@@ -509,4 +513,3 @@ const hasSchema = "configSchema" in pkg; | ||
async function loadConfig(options) { | ||
const configs = []; | ||
const {configRoot, experimentalEnvFunc: envFunc} = options; | ||
const {configRoot, experimentalEnvFunc: envFunc, watch} = options; | ||
const configPaths = options.configPaths.slice(); | ||
@@ -521,3 +524,4 @@ if (configPaths.length === 0) { | ||
const env = envFunc != null ? envFunc : async (name) => process.env[name]; | ||
try { | ||
const loadConfigFiles = async () => { | ||
const configs = []; | ||
for (const configPath of configPaths) { | ||
@@ -537,7 +541,36 @@ if (!path.isAbsolute(configPath)) { | ||
} | ||
return configs; | ||
}; | ||
let fileConfigs; | ||
try { | ||
fileConfigs = await loadConfigFiles(); | ||
} catch (error) { | ||
throw new Error(`Failed to read static configuration file, ${error.message}`); | ||
} | ||
configs.push(...readEnvConfig(process.env)); | ||
return configs; | ||
const envConfigs = await readEnvConfig(process.env); | ||
if (watch) { | ||
let currentSerializedConfig = JSON.stringify(fileConfigs); | ||
const watcher = chokidar__default['default'].watch(configPaths, { | ||
usePolling: process.env.NODE_ENV === "test" | ||
}); | ||
watcher.on("change", async () => { | ||
try { | ||
const newConfigs = await loadConfigFiles(); | ||
const newSerializedConfig = JSON.stringify(newConfigs); | ||
if (currentSerializedConfig === newSerializedConfig) { | ||
return; | ||
} | ||
currentSerializedConfig = newSerializedConfig; | ||
watch.onChange([...newConfigs, ...envConfigs]); | ||
} catch (error) { | ||
console.error(`Failed to reload configuration files, ${error}`); | ||
} | ||
}); | ||
if (watch.stopSignal) { | ||
watch.stopSignal.then(() => { | ||
watcher.close(); | ||
}); | ||
} | ||
} | ||
return [...fileConfigs, ...envConfigs]; | ||
} | ||
@@ -544,0 +577,0 @@ |
@@ -21,2 +21,4 @@ import { AppConfig, JsonObject } from '@backstage/config'; | ||
* APP_CONFIG_app_title='"My Title"' | ||
* | ||
* @public | ||
*/ | ||
@@ -27,14 +29,15 @@ declare function readEnvConfig(env: { | ||
/** @public */ | ||
declare type EnvFunc = (name: string) => Promise<string | undefined>; | ||
/** | ||
* A list of all possible configuration value visibilities. | ||
*/ | ||
declare const CONFIG_VISIBILITIES: readonly ["frontend", "backend", "secret"]; | ||
/** | ||
* A type representing the possible configuration value visibilities | ||
* | ||
* @public | ||
*/ | ||
declare type ConfigVisibility = typeof CONFIG_VISIBILITIES[number]; | ||
declare type ConfigVisibility = 'frontend' | 'backend' | 'secret'; | ||
/** | ||
* A function used to transform primitive configuration values. | ||
* | ||
* @public | ||
*/ | ||
@@ -46,4 +49,6 @@ declare type TransformFunc<T extends number | string | boolean> = (value: T, context: { | ||
* Options used to process configuration data with a schema. | ||
* | ||
* @public | ||
*/ | ||
declare type ConfigProcessingOptions = { | ||
declare type ConfigSchemaProcessingOptions = { | ||
/** | ||
@@ -70,5 +75,7 @@ * The visibilities that should be included in the output data. | ||
* A loaded configuration schema that is ready to process configuration data. | ||
* | ||
* @public | ||
*/ | ||
declare type ConfigSchema = { | ||
process(appConfigs: AppConfig[], options?: ConfigProcessingOptions): AppConfig[]; | ||
process(appConfigs: AppConfig[], options?: ConfigSchemaProcessingOptions): AppConfig[]; | ||
serialize(): JsonObject; | ||
@@ -80,6 +87,9 @@ }; | ||
* into a single json schema. | ||
* | ||
* @public | ||
*/ | ||
declare function mergeConfigSchemas(schemas: JSONSchema7[]): JSONSchema7; | ||
declare type Options = { | ||
/** @public */ | ||
declare type LoadConfigSchemaOptions = { | ||
dependencies: string[]; | ||
@@ -91,5 +101,8 @@ } | { | ||
* Loads config schema for a Backstage instance. | ||
* | ||
* @public | ||
*/ | ||
declare function loadConfigSchema(options: Options): Promise<ConfigSchema>; | ||
declare function loadConfigSchema(options: LoadConfigSchemaOptions): Promise<ConfigSchema>; | ||
/** @public */ | ||
declare type LoadConfigOptions = { | ||
@@ -106,5 +119,23 @@ configRoot: string; | ||
experimentalEnvFunc?: EnvFunc; | ||
/** | ||
* An optional configuration that enables watching of config files. | ||
*/ | ||
watch?: { | ||
/** | ||
* A listener that is called when a config file is changed. | ||
*/ | ||
onChange: (configs: AppConfig[]) => void; | ||
/** | ||
* An optional signal that stops the watcher once the promise resolves. | ||
*/ | ||
stopSignal?: Promise<void>; | ||
}; | ||
}; | ||
/** | ||
* Load configuration data. | ||
* | ||
* @public | ||
*/ | ||
declare function loadConfig(options: LoadConfigOptions): Promise<AppConfig[]>; | ||
export { ConfigSchema, ConfigVisibility, LoadConfigOptions, loadConfig, loadConfigSchema, mergeConfigSchemas, readEnvConfig }; | ||
export { ConfigSchema, ConfigSchemaProcessingOptions, ConfigVisibility, EnvFunc, LoadConfigOptions, LoadConfigSchemaOptions, TransformFunc, loadConfig, loadConfigSchema, mergeConfigSchemas, readEnvConfig }; |
@@ -8,2 +8,3 @@ import yaml from 'yaml'; | ||
import { getProgramFromFiles, generateSchema } from 'typescript-json-schema'; | ||
import chokidar from 'chokidar'; | ||
@@ -306,3 +307,3 @@ const ENV_PREFIX = "APP_CONFIG_"; | ||
async function processItem({name, parentPath}) { | ||
var _a, _b; | ||
var _a, _b, _c, _d; | ||
if (visitedPackages.has(name)) { | ||
@@ -323,3 +324,5 @@ return; | ||
...Object.keys((_a = pkg.dependencies) != null ? _a : {}), | ||
...Object.keys((_b = pkg.peerDependencies) != null ? _b : {}) | ||
...Object.keys((_b = pkg.devDependencies) != null ? _b : {}), | ||
...Object.keys((_c = pkg.optionalDependencies) != null ? _c : {}), | ||
...Object.keys((_d = pkg.peerDependencies) != null ? _d : {}) | ||
]; | ||
@@ -497,4 +500,3 @@ const hasSchema = "configSchema" in pkg; | ||
async function loadConfig(options) { | ||
const configs = []; | ||
const {configRoot, experimentalEnvFunc: envFunc} = options; | ||
const {configRoot, experimentalEnvFunc: envFunc, watch} = options; | ||
const configPaths = options.configPaths.slice(); | ||
@@ -509,3 +511,4 @@ if (configPaths.length === 0) { | ||
const env = envFunc != null ? envFunc : async (name) => process.env[name]; | ||
try { | ||
const loadConfigFiles = async () => { | ||
const configs = []; | ||
for (const configPath of configPaths) { | ||
@@ -525,7 +528,36 @@ if (!isAbsolute(configPath)) { | ||
} | ||
return configs; | ||
}; | ||
let fileConfigs; | ||
try { | ||
fileConfigs = await loadConfigFiles(); | ||
} catch (error) { | ||
throw new Error(`Failed to read static configuration file, ${error.message}`); | ||
} | ||
configs.push(...readEnvConfig(process.env)); | ||
return configs; | ||
const envConfigs = await readEnvConfig(process.env); | ||
if (watch) { | ||
let currentSerializedConfig = JSON.stringify(fileConfigs); | ||
const watcher = chokidar.watch(configPaths, { | ||
usePolling: process.env.NODE_ENV === "test" | ||
}); | ||
watcher.on("change", async () => { | ||
try { | ||
const newConfigs = await loadConfigFiles(); | ||
const newSerializedConfig = JSON.stringify(newConfigs); | ||
if (currentSerializedConfig === newSerializedConfig) { | ||
return; | ||
} | ||
currentSerializedConfig = newSerializedConfig; | ||
watch.onChange([...newConfigs, ...envConfigs]); | ||
} catch (error) { | ||
console.error(`Failed to reload configuration files, ${error}`); | ||
} | ||
}); | ||
if (watch.stopSignal) { | ||
watch.stopSignal.then(() => { | ||
watcher.close(); | ||
}); | ||
} | ||
} | ||
return [...fileConfigs, ...envConfigs]; | ||
} | ||
@@ -532,0 +564,0 @@ |
{ | ||
"name": "@backstage/config-loader", | ||
"description": "Config loading functionality used by Backstage backend, and CLI", | ||
"version": "0.0.0-nightly-20217521743", | ||
"version": "0.0.0-nightly-20218721719", | ||
"private": false, | ||
@@ -33,6 +33,7 @@ "publishConfig": { | ||
"dependencies": { | ||
"@backstage/cli-common": "^0.1.1", | ||
"@backstage/config": "^0.0.0-nightly-20217521743", | ||
"@backstage/cli-common": "^0.0.0-nightly-20218721719", | ||
"@backstage/config": "^0.0.0-nightly-20218721719", | ||
"@types/json-schema": "^7.0.6", | ||
"ajv": "^7.0.3", | ||
"chokidar": "^3.5.2", | ||
"fs-extra": "9.1.0", | ||
@@ -39,0 +40,0 @@ "json-schema": "^0.3.0", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
148635
1234
11
10
+ Addedchokidar@^3.5.2
+ Added@backstage/cli-common@0.0.0-nightly-20241119023621(transitive)
+ Addedanymatch@3.1.3(transitive)
+ Addedbinary-extensions@2.3.0(transitive)
+ Addedbraces@3.0.3(transitive)
+ Addedchokidar@3.6.0(transitive)
+ Addedfill-range@7.1.1(transitive)
+ Addedfsevents@2.3.3(transitive)
+ Addedglob-parent@5.1.2(transitive)
+ Addedis-binary-path@2.1.0(transitive)
+ Addedis-extglob@2.1.1(transitive)
+ Addedis-glob@4.0.3(transitive)
+ Addedis-number@7.0.0(transitive)
+ Addedmath-intrinsics@1.1.0(transitive)
+ Addednormalize-path@3.0.0(transitive)
+ Addedpicomatch@2.3.1(transitive)
+ Addedreaddirp@3.6.0(transitive)
+ Addedto-regex-range@5.0.1(transitive)
- Removed@backstage/cli-common@0.1.15(transitive)
- Removedmath-intrinsics@1.0.0(transitive)