Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/gallolabs/config
Config javascript component
https://github.com/gallolabs/config
config configuration
Last synced: about 1 month ago
JSON representation
Config javascript component
- Host: GitHub
- URL: https://github.com/gallolabs/config
- Owner: gallolabs
- Created: 2023-12-17T19:36:47.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2024-06-19T17:56:08.000Z (8 months ago)
- Last Synced: 2024-06-20T06:18:00.929Z (8 months ago)
- Topics: config, configuration
- Language: TypeScript
- Homepage:
- Size: 698 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
Gallo config
## Work in progress in main branch
But should be good
Todo
- Detect impossible resolutions (cyclic refs, etc) and throw errors (already managed one case but not all)
- Add Yaml !env THE_ENV to use unflatten env var (but resolved ?)
- Add support of variable substition in various parsers like for envs API_URL="${BASE_URL}/api" targetting same content before unflat and resolve (subtition in parser on raw content)
- Add merge function in QueryToken with support of deepMerge with options (array, objects, etc), and with not byPathMerge, and shallowMerge ; with not ability to extend ref/merge in others contexts (in yaml ?). To test use cases.
- allowError option (only reader ?) for example to merge a local translation files with remote one and accepting remote fail without blocking everything. To see events to catch that
- Config loader load() or reload() callable method to force reloading
- emit activite.change, and various event (see debug-info), here to track the change event without adding a listener on it. Can be view like a watching activities inside the system
- Accept file:/ and not only file:/// as it seems to be in a RFC ; use env:/ instead of env: to use URI resolve for every readers ?
- A command to convert a config (env, args, files, etc) to another format (ex to envs, json, etc). Don't need to use gallolabs/config to be flexible !## Definition
Global Workflow :
- Event 'load' is emitted
- Process env & argv are read to identify config* keys (CONFIG_*, --config-* uri & opts)
- If config uri is provided, it is loaded and used as base config ; loaded uri can be watched and are cached
- Process env is unflatten thanks to the schema and merged to the base config
- Process argv then also
- The candidate config is validated (and type converted) ... or not
- If no validated, and same of any error, event 'error' is emitted
- Event 'loaded' is emitted
- If previous config was loaded, the new config is compared and :
+ Event 'change' is emitted with patches, old config and new config
+ Events 'change:/xxx/yyy/zzz' are emitted with all the tree. For example if admin.identity.name is modified, are emitted :
* change:/
* change:/admin
* change:/admin/identity
* change:/admin/identity/nameNotes: To use watch, both configLoader must be configured to support it, and provided config must activate it (ex CONFIG_OPTS_WATCH=true)
Ref / Uri workflow :
- It is possible to load uri, providing transformation as fragment and options
- The $ref is called from anywhere with the format :
+ one-line (if supported) for example env : @ref ./variables#my.variable {options}
+ as dictionnary (if supported) for example yaml : !ref uri: ./variables#my.variable opts: {options}
- Transformation is handled by jsonata and so advanced query/transformations are possible. However, the readability is very bad. Prefer $query for advanced use, and keep $ref with fragment to subresource query for example
- Also is available $query for advanced uses (use multiples values, for example @query "$ref('env:BASE_URL') & $ref('arg:url-suffix')")
- Uri are resolved with a reader to read the raw value (stored in cache, and with watcher), a parser to parse depending of the content type, and parsed token (ref, query) are resolved## Old doc
Advanced config:
- [X] from files (super-yaml, json) and envs (scoped or not)
- [X] Validated user config (with validate component with cast and defaults values)
- [X] Finalization fn to transform user config to config
- [X] watch changes and emit on change new config
- [X] watch alerts in case of no listen on watch events
- [X] watch changes included files
- [ ] watch new files and unwatch old files if new config does not use same files
- [ ] include files into config from envs (ex: APP_DB_PASSWORD='!include /run/secrets/db_password')
- [ ] Super Json (like Yaml, for example { db: { password: { $include: '/run/secrets/db_password' }, username: { $env: 'USER' } } })
- [ ] Command line arguments as config param
- [ ] Refacto, refacto, refactoExample:
```typescript
import {loadConfig} from '@gallolabs/config'const watchEventEmitter = new EventEmitter
watchEventEmitter.on('change:machin.truc', ({value/*, previousValue, config, previousConfig*/}) => {
// Update service
machinService.setTruc(value)
})deepEqual(
await loadConfig({
defaultFilename: __dirname + '/config.test.yml',
envFilename: 'config',
envPrefix: 'app',
userProvidedConfigSchema: tsToJsSchema(),
watchChanges: {
onChange({config/*, previousConfig, patch*/}) {
console.log('My new config', config)
}
eventEmitter: watchEventEmitter
}
}),
{
machin: {
truc: {
bidule: true
}
},
envShell: 'hello world'
}
)const machinService = new MachinService(config.machin)
```