@travetto/config 5.0.0-rc.1 → 5.0.0-rc.10
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 +7 -7
- package/package.json +3 -3
- package/src/decorator.ts +1 -1
- package/src/parser/parser.ts +1 -1
- package/src/service.ts +11 -13
- package/src/source/env.ts +1 -1
- package/src/source/file.ts +7 -5
- package/src/trv.d.ts +1 -1
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ npm install @travetto/config
|
|
|
13
13
|
yarn add @travetto/config
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
The config module provides support for loading application config on startup. Configuration values support the common [YAML](https://en.wikipedia.org/wiki/YAML) constructs as defined in [yaml](https://github.com/eemeli/yaml). Additionally, the configuration is built upon the [Schema](https://github.com/travetto/travetto/tree/main/module/schema#readme "Data type registry for runtime validation, reflection and binding.") module, to enforce type correctness, and allow for validation of configuration as an entrypoint into the application. Given that all [@Config](https://github.com/travetto/travetto/tree/main/module/config/src/decorator.ts#L13) classes are [@Schema](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/schema.ts#L14)-based classes, all the standard [@Schema](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/schema.ts#L14) and [@Field](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#
|
|
16
|
+
The config module provides support for loading application config on startup. Configuration values support the common [YAML](https://en.wikipedia.org/wiki/YAML) constructs as defined in [yaml](https://github.com/eemeli/yaml). Additionally, the configuration is built upon the [Schema](https://github.com/travetto/travetto/tree/main/module/schema#readme "Data type registry for runtime validation, reflection and binding.") module, to enforce type correctness, and allow for validation of configuration as an entrypoint into the application. Given that all [@Config](https://github.com/travetto/travetto/tree/main/module/config/src/decorator.ts#L13) classes are [@Schema](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/schema.ts#L14)-based classes, all the standard [@Schema](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/schema.ts#L14) and [@Field](https://github.com/travetto/travetto/tree/main/module/schema/src/decorator/field.ts#L30) functionality applies.
|
|
17
17
|
|
|
18
18
|
## Resolution
|
|
19
19
|
The configuration information is comprised of:
|
|
@@ -23,7 +23,7 @@ Config loading follows a defined resolution path, below is the order in increasi
|
|
|
23
23
|
1. `resources/application.<ext>` - Priority `100` - Load the default `application.<ext>` if available.
|
|
24
24
|
1. `resources/{env}.<ext>` - Priority `200` - Load environment specific profile configurations as defined by the values of `process.env.TRV_ENV`.
|
|
25
25
|
1. `resources/*.<ext>` - Priority `300` - Load profile specific configurations as defined by the values in `process.env.TRV_PROFILES`
|
|
26
|
-
1. [@Injectable](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#
|
|
26
|
+
1. [@Injectable](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#L29) [ConfigSource](https://github.com/travetto/travetto/tree/main/module/config/src/source/types.ts#L11) - Priority `???` - These are custom config sources provided by the module, and are able to define their own priorities
|
|
27
27
|
1. [OverrideConfigSource](https://github.com/travetto/travetto/tree/main/module/config/src/source/override.ts#L11) - Priority `999` - This is for [EnvVar](https://github.com/travetto/travetto/tree/main/module/config/src/decorator.ts#L34) overrides, and is at the top priority for all built-in config sources.
|
|
28
28
|
By default all configuration data is inert, and will only be applied when constructing an instance of a configuration class.
|
|
29
29
|
|
|
@@ -140,7 +140,7 @@ export class EnvConfigSource implements ConfigSource {
|
|
|
140
140
|
try {
|
|
141
141
|
const data = JSON.parse(process.env[this.#envKey] || '{}');
|
|
142
142
|
return { data, priority: this.#priority, source: `env://${this.#envKey}` };
|
|
143
|
-
} catch
|
|
143
|
+
} catch {
|
|
144
144
|
console.error(`env.${this.#envKey} is an invalid format`, { text: process.env[this.#envKey] });
|
|
145
145
|
}
|
|
146
146
|
}
|
|
@@ -148,7 +148,7 @@ export class EnvConfigSource implements ConfigSource {
|
|
|
148
148
|
```
|
|
149
149
|
|
|
150
150
|
### Custom Configuration Provider
|
|
151
|
-
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#
|
|
151
|
+
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#L20) service for input. This means any needed configuration will need to be accessed via specific patterns.
|
|
152
152
|
|
|
153
153
|
**Code: Custom Configuration Source**
|
|
154
154
|
```typescript
|
|
@@ -167,10 +167,10 @@ export class CustomConfigSource implements ConfigSource {
|
|
|
167
167
|
```
|
|
168
168
|
|
|
169
169
|
## Startup
|
|
170
|
-
At startup, the [ConfigurationService](https://github.com/travetto/travetto/tree/main/module/config/src/service.ts#
|
|
170
|
+
At startup, the [ConfigurationService](https://github.com/travetto/travetto/tree/main/module/config/src/service.ts#L20) 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.
|
|
171
171
|
|
|
172
172
|
## Consuming
|
|
173
|
-
The [ConfigurationService](https://github.com/travetto/travetto/tree/main/module/config/src/service.ts#
|
|
173
|
+
The [ConfigurationService](https://github.com/travetto/travetto/tree/main/module/config/src/service.ts#L20) 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.
|
|
174
174
|
|
|
175
175
|
### Environment Variables
|
|
176
176
|
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.
|
|
@@ -206,7 +206,7 @@ $ trv main doc/dbconfig-run.ts
|
|
|
206
206
|
at: '2029-03-14T04:00:00.618Z',
|
|
207
207
|
details: {
|
|
208
208
|
class: '@travetto/config:doc/dbconfig○DBConfig',
|
|
209
|
-
|
|
209
|
+
import: '@travetto/config/doc/dbconfig.ts',
|
|
210
210
|
errors: [
|
|
211
211
|
{
|
|
212
212
|
kind: 'required',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/config",
|
|
3
|
-
"version": "5.0.0-rc.
|
|
3
|
+
"version": "5.0.0-rc.10",
|
|
4
4
|
"description": "Configuration support",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"yaml",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"directory": "module/config"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@travetto/di": "^5.0.0-rc.
|
|
30
|
-
"@travetto/schema": "^5.0.0-rc.
|
|
29
|
+
"@travetto/di": "^5.0.0-rc.9",
|
|
30
|
+
"@travetto/schema": "^5.0.0-rc.10",
|
|
31
31
|
"yaml": "^2.4.5"
|
|
32
32
|
},
|
|
33
33
|
"travetto": {
|
package/src/decorator.ts
CHANGED
package/src/parser/parser.ts
CHANGED
|
@@ -2,7 +2,7 @@ import fs from 'node:fs/promises';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
|
|
4
4
|
import { DependencyRegistry, Injectable } from '@travetto/di';
|
|
5
|
-
import { AppError } from '@travetto/
|
|
5
|
+
import { AppError } from '@travetto/runtime';
|
|
6
6
|
|
|
7
7
|
import { ConfigParserTarget } from '../internal/types';
|
|
8
8
|
import { ConfigData, ConfigParser } from './types';
|
package/src/service.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import util from 'node:util';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { AppError, Class, ClassInstance, Env, RuntimeContext, RuntimeResources } from '@travetto/base';
|
|
3
|
+
import { AppError, castTo, Class, ClassInstance, Env, Runtime, RuntimeResources } from '@travetto/runtime';
|
|
5
4
|
import { DependencyRegistry, Injectable } from '@travetto/di';
|
|
6
5
|
import { BindUtil, DataUtil, SchemaRegistry, SchemaValidator, ValidationResultError } from '@travetto/schema';
|
|
7
6
|
|
|
@@ -34,8 +33,7 @@ export class ConfigurationService {
|
|
|
34
33
|
|
|
35
34
|
while (parts.length && sub) {
|
|
36
35
|
const next = parts.shift()!;
|
|
37
|
-
|
|
38
|
-
sub = sub[next] as Record<string, unknown>;
|
|
36
|
+
sub = castTo(sub[next]);
|
|
39
37
|
}
|
|
40
38
|
|
|
41
39
|
return sub;
|
|
@@ -127,8 +125,8 @@ export class ConfigurationService {
|
|
|
127
125
|
const ogMessage = err.message;
|
|
128
126
|
err.message = `Failed to construct ${cls.Ⲑid} as validation errors have occurred`;
|
|
129
127
|
err.stack = err.stack?.replace(ogMessage, err.message);
|
|
130
|
-
const
|
|
131
|
-
Object.defineProperty(err, 'details', { value: { class: cls.Ⲑid,
|
|
128
|
+
const imp = Runtime.getImport(cls);
|
|
129
|
+
Object.defineProperty(err, 'details', { value: { class: cls.Ⲑid, import: imp, ...(err.details ?? {}) } });
|
|
132
130
|
}
|
|
133
131
|
throw err;
|
|
134
132
|
}
|
|
@@ -145,14 +143,14 @@ export class ConfigurationService {
|
|
|
145
143
|
|
|
146
144
|
console.log('Initialized', {
|
|
147
145
|
manifest: {
|
|
148
|
-
main:
|
|
149
|
-
workspace:
|
|
146
|
+
main: Runtime.main,
|
|
147
|
+
workspace: Runtime.workspace
|
|
150
148
|
},
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
debug:
|
|
154
|
-
production:
|
|
155
|
-
dynamic:
|
|
149
|
+
runtime: {
|
|
150
|
+
env: Runtime.env,
|
|
151
|
+
debug: Runtime.debug,
|
|
152
|
+
production: Runtime.production,
|
|
153
|
+
dynamic: Runtime.dynamic,
|
|
156
154
|
resourcePaths: RuntimeResources.searchPaths,
|
|
157
155
|
profiles: Env.TRV_PROFILES.list ?? []
|
|
158
156
|
},
|
package/src/source/env.ts
CHANGED
|
@@ -16,7 +16,7 @@ export class EnvConfigSource implements ConfigSource {
|
|
|
16
16
|
try {
|
|
17
17
|
const data = JSON.parse(process.env[this.#envKey] || '{}');
|
|
18
18
|
return { data, priority: this.#priority, source: `env://${this.#envKey}` };
|
|
19
|
-
} catch
|
|
19
|
+
} catch {
|
|
20
20
|
console.error(`env.${this.#envKey} is an invalid format`, { text: process.env[this.#envKey] });
|
|
21
21
|
}
|
|
22
22
|
}
|
package/src/source/file.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
|
|
4
|
-
import { Env,
|
|
4
|
+
import { Env, Runtime, RuntimeResources } from '@travetto/runtime';
|
|
5
5
|
|
|
6
6
|
import { ConfigSource, ConfigSpec } from './types';
|
|
7
7
|
import { ParserManager } from '../parser/parser';
|
|
@@ -22,7 +22,7 @@ export class FileConfigSource implements ConfigSource {
|
|
|
22
22
|
this.#searchPaths = RuntimeResources.searchPaths.slice().reverse();
|
|
23
23
|
this.#profiles = ([
|
|
24
24
|
['application', 100],
|
|
25
|
-
[
|
|
25
|
+
[Runtime.env!, 200],
|
|
26
26
|
...(Env.TRV_PROFILES.list ?? [])
|
|
27
27
|
.map((p, i) => [p, 300 + i * 10] as const)
|
|
28
28
|
] as const).filter(x => !!x[0]);
|
|
@@ -31,18 +31,20 @@ export class FileConfigSource implements ConfigSource {
|
|
|
31
31
|
async get(): Promise<ConfigSpec[]> {
|
|
32
32
|
const cache: Record<string, Promise<string[]>> = {};
|
|
33
33
|
const configs: Promise<ConfigSpec>[] = [];
|
|
34
|
+
|
|
34
35
|
for (const [profile, priority] of this.#profiles) {
|
|
35
|
-
let i =
|
|
36
|
+
let i = priority;
|
|
36
37
|
for (const folder of this.#searchPaths) {
|
|
37
38
|
const files = await (cache[folder] ??= fs.readdir(folder).catch(() => []));
|
|
38
39
|
for (const file of files) {
|
|
39
40
|
if (this.#parser.matches(file) && path.basename(file, path.extname(file)) === profile) {
|
|
40
41
|
const full = path.resolve(folder, file);
|
|
42
|
+
const configPriority = i++;
|
|
41
43
|
configs.push(this.#parser.parse(full).then(data => ({
|
|
42
44
|
data,
|
|
43
|
-
priority:
|
|
45
|
+
priority: configPriority,
|
|
44
46
|
source: `file://${profile}`,
|
|
45
|
-
detail:
|
|
47
|
+
detail: Runtime.stripWorkspacePath(full)
|
|
46
48
|
})));
|
|
47
49
|
}
|
|
48
50
|
}
|
package/src/trv.d.ts
CHANGED