@travetto/config 3.4.0-rc.2 → 3.4.0-rc.4

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 CHANGED
@@ -20,11 +20,13 @@ The configuration information is comprised of:
20
20
  * configuration files - [YAML](https://en.wikipedia.org/wiki/YAML), [JSON](https://www.json.org), and basic properties file
21
21
  * configuration classes
22
22
  Config loading follows a defined resolution path, below is the order in increasing specificity (`ext` can be `yaml`, `yml`, `json`, `properties`):
23
- 1. `resources/application.<ext>` - Load the default `application.<ext>` if available.
24
- 1. `resources/*.<ext>` - Load profile specific configurations as defined by the values in `process.env.TRV_PROFILES`
25
- 1. `resources/{env}.<ext>` - Load environment specific profile configurations as defined by the values of `process.env.TRV_ENV`.
23
+ 1. `resources/application.<ext>` - Priority `100` - Load the default `application.<ext>` if available.
24
+ 1. `resources/{env}.<ext>` - Priority `200` - Load environment specific profile configurations as defined by the values of `process.env.TRV_ENV`.
25
+ 1. `resources/*.<ext>` - Priority `300` - Load profile specific configurations as defined by the values in `process.env.TRV_PROFILES`
26
26
  By default all configuration data is inert, and will only be applied when constructing an instance of a configuration class.
27
27
 
28
+ **Note**: When working in a monorepo, the parent resources folder will also be searched with a lower priority than the the module's specific resources. This allows for shared-global configuration that can be overridden at the module level. The general rule is that the longest path has the highest priority.
29
+
28
30
  ### A Complete Example
29
31
  A more complete example setup would look like:
30
32
 
@@ -65,9 +67,17 @@ $ trv main doc/resolve.ts
65
67
 
66
68
  Config {
67
69
  sources: [
68
- 'application.1 - file://./doc/resources/application.yml',
69
- 'prod.1 - file://./doc/resources/prod.json',
70
- 'override.3 - memory://override'
70
+ {
71
+ priority: 100,
72
+ source: 'file://application',
73
+ detail: 'module/config/doc/resources/application.yml'
74
+ },
75
+ {
76
+ priority: 300,
77
+ source: 'file://prod',
78
+ detail: 'module/config/doc/resources/prod.json'
79
+ },
80
+ { priority: 999, source: 'memory://override' }
71
81
  ],
72
82
  active: {
73
83
  DBConfig: { host: 'prod-host-db', port: 2000, creds: { user: 'admin-user' } }
@@ -81,95 +91,84 @@ The framework provides two simple base classes that assist with existing pattern
81
91
  **Code: Memory Provider**
82
92
  ```typescript
83
93
  import { ConfigData } from '../parser/types';
84
- import { ConfigSource, ConfigValue } from './types';
94
+ import { ConfigSource } from './types';
85
95
 
86
96
  /**
87
97
  * Meant to be instantiated and provided as a unique config source
88
98
  */
89
99
  export class MemoryConfigSource implements ConfigSource {
90
- priority = 1;
91
- data: Record<string, ConfigData>;
92
- name = 'memory';
100
+ priority: number;
101
+ data: ConfigData;
102
+ source: string;
93
103
 
94
- constructor(data: Record<string, ConfigData>, priority: number = 1) {
104
+ constructor(key: string, data: ConfigData, priority: number = 500) {
95
105
  this.data = data;
96
106
  this.priority = priority;
107
+ this.source = `memory://${key}`;
97
108
  }
98
109
 
99
- getValues(profiles: string[]): ConfigValue[] {
100
- const out: ConfigValue[] = [];
101
- for (const profile of profiles) {
102
- if (this.data[profile]) {
103
- out.push({ profile, config: this.data[profile], source: `${this.name}://${profile}`, priority: this.priority });
104
- }
105
- }
106
- return out;
110
+ getData(): ConfigData {
111
+ return this.data;
107
112
  }
108
113
  }
109
114
  ```
110
115
 
111
116
  **Code: Environment JSON Provider**
112
117
  ```typescript
113
- import { Env, GlobalEnv } from '@travetto/base';
118
+ import { Env } from '@travetto/base';
114
119
 
115
- import { ConfigSource, ConfigValue } from './types';
120
+ import { ConfigSource } from './types';
121
+ import { ConfigData } from '../parser/types';
116
122
 
117
123
  /**
118
124
  * Represents the environment mapped data as a JSON blob
119
125
  */
120
126
  export class EnvConfigSource implements ConfigSource {
121
127
  priority: number;
122
- name = 'env';
128
+ source: string;
123
129
  #envKey: string;
124
130
 
125
131
  constructor(key: string, priority: number) {
126
132
  this.#envKey = key;
127
133
  this.priority = priority;
134
+ this.source = `env://${this.#envKey}`;
128
135
  }
129
136
 
130
- getValues(profiles: string[]): ConfigValue[] {
137
+ getData(): ConfigData | undefined {
131
138
  try {
132
139
  const data = JSON.parse(Env.get(this.#envKey, '{}'));
133
- return [{ profile: GlobalEnv.envName, config: data, source: `${this.name}://${this.#envKey}`, priority: this.priority }];
140
+ return data;
134
141
  } catch (e) {
135
142
  console.error(`env.${this.#envKey} is an invalid format`, { text: Env.get(this.#envKey) });
136
- return [];
137
143
  }
138
144
  }
139
145
  }
140
146
  ```
141
147
 
142
148
  ### Custom Configuration Provider
143
- In addition to files and environment variables, configuration sources can also be provided via the class itself. This is useful for reading remote configurations, or dealing with complex configuration normalization. The only caveat to this pattern, is that the these configuration sources cannot rely on the [ConfigurationService](https://github.com/travetto/travetto/tree/main/module/config/src/service.ts#L16) service for input. This means any needed configuration will need to be accessed via specific patterns.
149
+ In addition to files and environment variables, configuration sources can also be provided via the class itself. This is useful for reading remote configurations, or dealing with complex configuration normalization. The only caveat to this pattern, is that the these configuration sources cannot rely on the [ConfigurationService](https://github.com/travetto/travetto/tree/main/module/config/src/service.ts#L21) service for input. This means any needed configuration will need to be accessed via specific patterns.
144
150
 
145
151
  **Code: Custom Configuration Source**
146
152
  ```typescript
147
- import { ConfigSource, ConfigValue } from '@travetto/config';
153
+ import { ConfigData, ConfigSource } from '@travetto/config';
148
154
  import { Injectable } from '@travetto/di';
149
155
 
150
156
  @Injectable()
151
157
  export class CustomConfigSource implements ConfigSource {
152
- priority = 1000;
153
- name = 'custom';
154
-
155
- async getValues(): Promise<ConfigValue[]> {
156
- return [
157
- {
158
- config: { user: { name: 'bob' } },
159
- priority: this.priority,
160
- profile: 'override',
161
- source: `custom://${CustomConfigSource.name}`
162
- }
163
- ];
158
+ priority = 2000;
159
+ source = 'custom://override';
160
+
161
+ async getData(): Promise<ConfigData> {
162
+ return { user: { name: 'bob' } };
164
163
  }
165
164
  }
166
165
  ```
167
166
 
168
167
  ## Startup
169
- At startup, the [ConfigurationService](https://github.com/travetto/travetto/tree/main/module/config/src/service.ts#L16) service will log out all the registered configuration objects. The configuration state output is useful to determine if everything is configured properly when diagnosing runtime errors. This service will find all configurations, and output a redacted version with all secrets removed. The default pattern for secrets is `/password|private|secret/i`. More values can be added in your configuration under the path `config.secrets`. These values can either be simple strings (for exact match), or `/pattern/` to create a regular expression.
168
+ At startup, the [ConfigurationService](https://github.com/travetto/travetto/tree/main/module/config/src/service.ts#L21) service will log out all the registered configuration objects. The configuration state output is useful to determine if everything is configured properly when diagnosing runtime errors. This service will find all configurations, and output a redacted version with all secrets removed. The default pattern for secrets is `/password|private|secret/i`. More values can be added in your configuration under the path `config.secrets`. These values can either be simple strings (for exact match), or `/pattern/` to create a regular expression.
170
169
 
171
170
  ## Consuming
172
- The [ConfigurationService](https://github.com/travetto/travetto/tree/main/module/config/src/service.ts#L16) service provides injectable access to all of the loaded configuration. For simplicity, a decorator, [@Config](https://github.com/travetto/travetto/tree/main/module/config/src/decorator.ts#L13) allows for classes to automatically be bound with config information on post construction via the [Dependency Injection](https://github.com/travetto/travetto/tree/main/module/di#readme "Dependency registration/management and injection support.") module. The decorator will install a `postConstruct` method if not already defined, that performs the binding of configuration. This is due to the fact that we cannot rewrite the constructor, and order of operation matters.
171
+ The [ConfigurationService](https://github.com/travetto/travetto/tree/main/module/config/src/service.ts#L21) service provides injectable access to all of the loaded configuration. For simplicity, a decorator, [@Config](https://github.com/travetto/travetto/tree/main/module/config/src/decorator.ts#L13) allows for classes to automatically be bound with config information on post construction via the [Dependency Injection](https://github.com/travetto/travetto/tree/main/module/di#readme "Dependency registration/management and injection support.") module. The decorator will install a `postConstruct` method if not already defined, that performs the binding of configuration. This is due to the fact that we cannot rewrite the constructor, and order of operation matters.
173
172
 
174
173
  ### Environment Variables
175
174
  Additionally there are times in which you may want to also support configuration via environment variables. [EnvVar](https://github.com/travetto/travetto/tree/main/module/config/src/decorator.ts#L34) supports override configuration values when environment variables are present.
@@ -228,9 +227,17 @@ $ DATABASE_PORT=200 trv main doc/dbconfig-run.ts
228
227
 
229
228
  Config {
230
229
  sources: [
231
- 'application.1 - file://./doc/resources/application.yml',
232
- 'prod.1 - file://./doc/resources/prod.json',
233
- 'override.3 - memory://override'
230
+ {
231
+ priority: 100,
232
+ source: 'file://application',
233
+ detail: 'module/config/doc/resources/application.yml'
234
+ },
235
+ {
236
+ priority: 300,
237
+ source: 'file://prod',
238
+ detail: 'module/config/doc/resources/prod.json'
239
+ },
240
+ { priority: 999, source: 'memory://override' }
234
241
  ],
235
242
  active: {
236
243
  DBConfig: { host: 'prod-host-db', port: 200, creds: { user: 'admin-user' } }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/config",
3
- "version": "3.4.0-rc.2",
3
+ "version": "3.4.0-rc.4",
4
4
  "description": "Configuration support",
5
5
  "keywords": [
6
6
  "yaml",
@@ -26,9 +26,9 @@
26
26
  "directory": "module/config"
27
27
  },
28
28
  "dependencies": {
29
- "@travetto/di": "^3.4.0-rc.2",
30
- "@travetto/schema": "^3.4.0-rc.2",
31
- "@travetto/yaml": "^3.4.0-rc.2"
29
+ "@travetto/di": "^3.4.0-rc.4",
30
+ "@travetto/schema": "^3.4.0-rc.4",
31
+ "@travetto/yaml": "^3.4.0-rc.4"
32
32
  },
33
33
  "travetto": {
34
34
  "displayName": "Configuration"
@@ -0,0 +1,37 @@
1
+ import fs from 'fs/promises';
2
+
3
+ import { DependencyRegistry, Injectable } from '@travetto/di';
4
+ import { AppError } from '@travetto/base';
5
+ import { path } from '@travetto/manifest';
6
+
7
+ import { ConfigParserTarget } from '../internal/types';
8
+ import { ConfigData, ConfigParser } from './types';
9
+
10
+ @Injectable()
11
+ export class ParserManager {
12
+
13
+ #extMatch: RegExp;
14
+ #parsers: Record<string, ConfigParser>;
15
+
16
+ async postConstruct(): Promise<void> {
17
+ const parserClasses = await DependencyRegistry.getCandidateTypes(ConfigParserTarget);
18
+ const parsers = await Promise.all(parserClasses.map(x => DependencyRegistry.getInstance<ConfigParser>(x.class, x.qualifier)));
19
+
20
+ // Register parsers
21
+ this.#parsers = Object.fromEntries(parsers.flatMap(p => p.ext.map(e => [e, p])));
22
+
23
+ this.#extMatch = parsers.length ? new RegExp(`(${Object.keys(this.#parsers).join('|').replaceAll('.', '[.]')})`) : /^$/;
24
+ }
25
+
26
+ async parse(file: string): Promise<ConfigData> {
27
+ const ext = path.extname(file);
28
+ if (!this.#parsers[ext]) {
29
+ throw new AppError(`Unknown config format: ${ext}`, 'data');
30
+ }
31
+ return fs.readFile(file, 'utf8').then(content => this.#parsers[ext].parse(content));
32
+ }
33
+
34
+ matches(file: string): boolean {
35
+ return this.#extMatch.test(file);
36
+ }
37
+ }
package/src/service.ts CHANGED
@@ -6,8 +6,13 @@ import { RootIndex } from '@travetto/manifest';
6
6
  import { BindUtil, SchemaRegistry, SchemaValidator, ValidationResultError } from '@travetto/schema';
7
7
 
8
8
  import { ConfigSourceTarget, ConfigTarget } from './internal/types';
9
+ import { ParserManager } from './parser/parser';
9
10
  import { ConfigData } from './parser/types';
10
- import { ConfigSource, ConfigValue } from './source/types';
11
+ import { ConfigSource } from './source/types';
12
+ import { FileConfigSource } from './source/file';
13
+ import { OverrideConfigSource } from './source/override';
14
+
15
+ type ConfigSpec = { source: string, priority: number, detail?: string };
11
16
 
12
17
  /**
13
18
  * Manager for application configuration
@@ -15,21 +20,23 @@ import { ConfigSource, ConfigValue } from './source/types';
15
20
  @Injectable()
16
21
  export class ConfigurationService {
17
22
 
18
- private static getSorted(configs: ConfigValue[], profiles: string[]): ConfigValue[] {
19
- const order = Object.fromEntries(Object.entries(profiles).map(([k, v]) => [v, +k] as const));
20
-
21
- return configs.sort((left, right) =>
22
- (order[left.profile] - order[right.profile]) ||
23
- left.priority - right.priority ||
24
- left.source.localeCompare(right.source)
25
- );
26
- }
27
-
28
23
  #storage: Record<string, unknown> = {}; // Lowered, and flattened
29
- #profiles: string[] = ['application', GlobalEnv.envName, ...Env.getList('TRV_PROFILES') ?? [], 'override'];
30
- #sources: string[] = [];
24
+ #specs: ConfigSpec[] = [];
31
25
  #secrets: (RegExp | string)[] = [/secure(-|_|[a-z])|password|private|secret|salt|(api(-|_)?key)/i];
32
26
 
27
+ async #toSpecPairs(cfg: ConfigSource): Promise<[ConfigSpec, ConfigData][]> {
28
+ const data = await cfg.getData();
29
+ if (!data) {
30
+ return [];
31
+ }
32
+ const arr = Array.isArray(data) ? data : [data];
33
+ return arr.map((d, i) => [{
34
+ priority: cfg.priority + i,
35
+ source: cfg.source,
36
+ ...(d.__ID__ ? { detail: d.__ID__?.toString() } : {})
37
+ }, d]);
38
+ }
39
+
33
40
  /**
34
41
  * Get a sub tree of the config, or everything if namespace is not passed
35
42
  * @param ns The namespace of the config to search for, can be dotted for accessing sub namespaces
@@ -57,17 +64,24 @@ export class ConfigurationService {
57
64
  const providers = await DependencyRegistry.getCandidateTypes(ConfigSourceTarget);
58
65
 
59
66
  const configs = await Promise.all(
60
- providers.map(async (el) => {
61
- const inst = await DependencyRegistry.getInstance<ConfigSource>(el.class, el.qualifier);
62
- return inst.getValues(this.#profiles);
63
- })
67
+ providers.map(async (el) => await DependencyRegistry.getInstance<ConfigSource>(el.class, el.qualifier))
64
68
  );
65
69
 
66
- const sorted = ConfigurationService.getSorted(configs.flat(), this.#profiles);
70
+ const parser = await DependencyRegistry.getInstance(ParserManager);
71
+
72
+ const specPairs = await Promise.all([
73
+ new FileConfigSource(parser, 'application', 100),
74
+ new FileConfigSource(parser, GlobalEnv.envName, 200),
75
+ ...(Env.getList('TRV_PROFILES') ?? []).map((p, i) => new FileConfigSource(parser, p, 300 + i * 10)),
76
+ ...configs,
77
+ new OverrideConfigSource()
78
+ ].map(src => this.#toSpecPairs(src)));
79
+
80
+ const specs = specPairs.flat().sort(([a], [b]) => a.priority - b.priority);
67
81
 
68
- this.#sources = sorted.map(x => `${x.profile}.${x.priority} - ${x.source}`);
82
+ this.#specs = specs.map(([v]) => v);
69
83
 
70
- for (const { config: element } of sorted) {
84
+ for (const [, element] of specs) {
71
85
  DataUtil.deepAssign(this.#storage, BindUtil.expandPaths(element), 'coerce');
72
86
  }
73
87
 
@@ -88,7 +102,7 @@ export class ConfigurationService {
88
102
  * Export all active configuration, useful for displaying active state
89
103
  * - Will not show fields marked as secret
90
104
  */
91
- async exportActive(): Promise<{ sources: string[], active: ConfigData }> {
105
+ async exportActive(): Promise<{ sources: ConfigSpec[], active: ConfigData }> {
92
106
  const configTargets = await DependencyRegistry.getCandidateTypes(ConfigTarget);
93
107
  const configs = await Promise.all(
94
108
  configTargets
@@ -106,7 +120,7 @@ export class ConfigurationService {
106
120
  );
107
121
  out[el.class.name] = DataUtil.filterByKeys(data, this.#secrets);
108
122
  }
109
- return { sources: this.#sources, active: out };
123
+ return { sources: this.#specs, active: out };
110
124
  }
111
125
 
112
126
  /**
package/src/source/env.ts CHANGED
@@ -1,27 +1,28 @@
1
- import { Env, GlobalEnv } from '@travetto/base';
1
+ import { Env } from '@travetto/base';
2
2
 
3
- import { ConfigSource, ConfigValue } from './types';
3
+ import { ConfigSource } from './types';
4
+ import { ConfigData } from '../parser/types';
4
5
 
5
6
  /**
6
7
  * Represents the environment mapped data as a JSON blob
7
8
  */
8
9
  export class EnvConfigSource implements ConfigSource {
9
10
  priority: number;
10
- name = 'env';
11
+ source: string;
11
12
  #envKey: string;
12
13
 
13
14
  constructor(key: string, priority: number) {
14
15
  this.#envKey = key;
15
16
  this.priority = priority;
17
+ this.source = `env://${this.#envKey}`;
16
18
  }
17
19
 
18
- getValues(profiles: string[]): ConfigValue[] {
20
+ getData(): ConfigData | undefined {
19
21
  try {
20
22
  const data = JSON.parse(Env.get(this.#envKey, '{}'));
21
- return [{ profile: GlobalEnv.envName, config: data, source: `${this.name}://${this.#envKey}`, priority: this.priority }];
23
+ return data;
22
24
  } catch (e) {
23
25
  console.error(`env.${this.#envKey} is an invalid format`, { text: Env.get(this.#envKey) });
24
- return [];
25
26
  }
26
27
  }
27
28
  }
@@ -1,59 +1,44 @@
1
- import { path } from '@travetto/manifest';
2
1
  import { FileQueryProvider } from '@travetto/base';
3
- import { DependencyRegistry, InjectableFactory } from '@travetto/di';
2
+ import { RootIndex, path } from '@travetto/manifest';
4
3
 
5
- import { ConfigParserTarget } from '../internal/types';
6
- import { ConfigParser } from '../parser/types';
7
- import { ConfigSource, ConfigValue } from './types';
4
+ import { ConfigSource } from './types';
5
+ import { ParserManager } from '../parser/parser';
6
+ import { ConfigData } from '../parser/types';
8
7
 
9
8
  /**
10
9
  * File-base config source, builds on common file resource provider
11
10
  */
12
11
  export class FileConfigSource extends FileQueryProvider implements ConfigSource {
13
12
 
14
- @InjectableFactory()
15
- static getInstance(): ConfigSource {
16
- return new FileConfigSource();
17
- }
18
-
19
- depth = 1;
20
- extMatch: RegExp;
21
- parsers: Record<string, ConfigParser>;
22
- priority = 1;
13
+ priority = 10;
14
+ source: string;
15
+ profile: string;
16
+ parser: ParserManager;
23
17
 
24
- constructor(paths: string[] = []) {
18
+ constructor(parser: ParserManager, profile: string, priority: number, paths: string[] = []) {
25
19
  super({ includeCommon: true, paths });
20
+ this.priority = priority;
21
+ this.profile = profile;
22
+ this.parser = parser;
23
+ this.source = `file://${profile}`;
26
24
  }
27
25
 
28
- async postConstruct(): Promise<void> {
29
- const parserClasses = await DependencyRegistry.getCandidateTypes(ConfigParserTarget);
30
- const parsers = await Promise.all(parserClasses.map(x => DependencyRegistry.getInstance<ConfigParser>(x.class, x.qualifier)));
31
-
32
- // Register parsers
33
- this.parsers = Object.fromEntries(parsers.flatMap(p => p.ext.map(e => [e, p])));
34
-
35
- this.extMatch = parsers.length ? new RegExp(`(${Object.keys(this.parsers).join('|').replaceAll('.', '[.]')})`) : /^$/;
36
- }
37
-
38
- async getValues(profiles: string[]): Promise<ConfigValue[]> {
39
- const out: ConfigValue[] = [];
40
-
41
- for await (const file of this.query(f => this.extMatch.test(f))) {
26
+ async getData(): Promise<ConfigData[]> {
27
+ const out: { file: string, data: ConfigData }[] = [];
28
+ for await (const file of this.query(f => this.parser.matches(f))) {
42
29
  const ext = path.extname(file);
43
- const profile = path.basename(file, ext);
44
- if (!profiles.includes(profile) || !this.parsers[ext]) {
45
- continue;
30
+ const base = path.basename(file, ext);
31
+ if (base === this.profile && !file.includes('/')) { // Ensures no nesting
32
+ for (const resolved of await this.resolveAll(file)) {
33
+ out.push({ file: resolved, data: await this.parser.parse(resolved) });
34
+ }
46
35
  }
47
- const content = await this.read(file);
48
- const desc = await this.describe(file);
49
- out.push({
50
- profile,
51
- config: await this.parsers[ext].parse(content),
52
- source: `file://${desc.path}`,
53
- priority: this.priority
54
- });
55
36
  }
37
+
56
38
  // Ensure more specific files are processed later
57
- return out.sort((a, b) => (a.source.length - b.source.length) || a.source.localeCompare(b.source));
39
+ return out
40
+ .sort((a, b) => (a.file.length - b.file.length) || a.file.localeCompare(b.file))
41
+ // eslint-disable-next-line @typescript-eslint/naming-convention
42
+ .map(a => ({ ...a.data, __ID__: a.file.replace(`${RootIndex.manifest.workspacePath}/`, '') }));
58
43
  }
59
44
  }
@@ -1,26 +1,21 @@
1
1
  import { ConfigData } from '../parser/types';
2
- import { ConfigSource, ConfigValue } from './types';
2
+ import { ConfigSource } from './types';
3
3
 
4
4
  /**
5
5
  * Meant to be instantiated and provided as a unique config source
6
6
  */
7
7
  export class MemoryConfigSource implements ConfigSource {
8
- priority = 1;
9
- data: Record<string, ConfigData>;
10
- name = 'memory';
8
+ priority: number;
9
+ data: ConfigData;
10
+ source: string;
11
11
 
12
- constructor(data: Record<string, ConfigData>, priority: number = 1) {
12
+ constructor(key: string, data: ConfigData, priority: number = 500) {
13
13
  this.data = data;
14
14
  this.priority = priority;
15
+ this.source = `memory://${key}`;
15
16
  }
16
17
 
17
- getValues(profiles: string[]): ConfigValue[] {
18
- const out: ConfigValue[] = [];
19
- for (const profile of profiles) {
20
- if (this.data[profile]) {
21
- out.push({ profile, config: this.data[profile], source: `${this.name}://${profile}`, priority: this.priority });
22
- }
23
- }
24
- return out;
18
+ getData(): ConfigData {
19
+ return this.data;
25
20
  }
26
21
  }
@@ -1,18 +1,16 @@
1
- import { Injectable } from '@travetto/di';
2
1
  import { SchemaRegistry } from '@travetto/schema';
3
2
 
4
3
  import { ConfigOverrides, CONFIG_OVERRIDES } from '../internal/types';
5
4
  import { ConfigData } from '../parser/types';
6
- import { ConfigSource, ConfigValue } from './types';
5
+ import { ConfigSource } from './types';
7
6
 
8
7
  /**
9
8
  * Overridable config source, provides ability to override field level values, currently used by
10
9
  * - @EnvVar as a means to allow environment specific overrides
11
10
  */
12
- @Injectable()
13
11
  export class OverrideConfigSource implements ConfigSource {
14
- priority = 3;
15
- name = 'override';
12
+ priority = 999;
13
+ source = 'memory://override';
16
14
 
17
15
  #build(): ConfigData {
18
16
  const out: ConfigData = {};
@@ -28,12 +26,7 @@ export class OverrideConfigSource implements ConfigSource {
28
26
  return out;
29
27
  }
30
28
 
31
- getValues(profiles: string[]): [ConfigValue] {
32
- return [{
33
- config: this.#build(),
34
- profile: 'override',
35
- source: 'memory://override',
36
- priority: this.priority
37
- }];
29
+ getData(): ConfigData {
30
+ return this.#build();
38
31
  }
39
32
  }
@@ -1,11 +1,10 @@
1
1
  import { ConfigData } from '../parser/types';
2
2
 
3
- export type ConfigValue = { config: ConfigData, source: string, profile: string, priority: number };
4
-
5
3
  /**
6
4
  * @concrete ../internal/types:ConfigSourceTarget
7
5
  */
8
6
  export interface ConfigSource {
9
7
  priority: number;
10
- getValues(profiles: string[]): Promise<ConfigValue[]> | ConfigValue[];
11
- }
8
+ source: string;
9
+ getData(): Promise<ConfigData[] | ConfigData | undefined> | ConfigData[] | ConfigData | undefined;
10
+ }