configorama 0.6.11 → 0.6.13
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 +196 -24
- package/cli.js +3 -3
- package/package.json +1 -1
- package/src/index.js +22 -32
- package/src/main.js +775 -857
- package/src/parsers/yaml.js +3 -47
- package/src/resolvers/valueFromCron.js +3 -1
- package/src/resolvers/valueFromEnv.js +1 -0
- package/src/resolvers/valueFromEval.js +1 -0
- package/src/resolvers/valueFromFile.js +394 -0
- package/src/resolvers/valueFromGit.js +3 -2
- package/src/resolvers/valueFromOptions.js +1 -0
- package/src/resolvers/valueFromString.js +2 -1
- package/src/sync.js +12 -5
- package/src/utils/parsing/arrayToJsonPath.test.js +56 -0
- package/src/utils/{enrichMetadata.js → parsing/enrichMetadata.js} +244 -94
- package/src/utils/{parse.js → parsing/parse.js} +13 -13
- package/src/utils/parsing/preProcess.js +165 -0
- package/src/utils/paths/filePathUtils.js +136 -0
- package/src/utils/paths/filePathUtils.test.js +214 -0
- package/src/utils/paths/findLineForKey.js +47 -0
- package/src/utils/paths/findLineForKey.test.js +126 -0
- package/src/utils/{getFullFilePath.js → paths/getFullFilePath.js} +22 -26
- package/src/utils/{resolveAlias.js → paths/resolveAlias.js} +1 -1
- package/src/utils/regex/index.js +23 -1
- package/src/utils/resolution/preResolveVariable.js +260 -0
- package/src/utils/resolution/preResolveVariable.test.js +98 -0
- package/src/utils/strings/bracketMatcher.js +86 -0
- package/src/utils/strings/bracketMatcher.test.js +135 -0
- package/src/utils/{formatFunctionArgs.js → strings/formatFunctionArgs.js} +3 -2
- package/src/utils/strings/formatFunctionArgs.test.js +77 -0
- package/src/utils/strings/quoteUtils.js +89 -0
- package/src/utils/strings/quoteUtils.test.js +217 -0
- package/src/utils/strings/replaceAll.test.js +82 -0
- package/src/utils/{splitByComma.js → strings/splitByComma.js} +1 -1
- package/src/utils/strings/splitCsv.js +38 -0
- package/src/utils/strings/splitCsv.test.js +96 -0
- package/src/utils/strings/textUtils.test.js +86 -0
- package/src/utils/{configWizard.js → ui/configWizard.js} +212 -60
- package/src/utils/{createEditorLink.js → ui/createEditorLink.js} +11 -2
- package/src/utils/{logs.js → ui/logs.js} +3 -3
- package/src/utils/validation/isValidValue.test.js +64 -0
- package/src/utils/validation/warnIfNotFound.js +52 -0
- package/src/utils/variables/appendDeepVariable.test.js +41 -0
- package/src/utils/{cleanVariable.js → variables/cleanVariable.js} +5 -26
- package/src/utils/{find-nested-variables.js → variables/findNestedVariables.js} +2 -2
- package/src/utils/{find-nested-variables.test.js → variables/findNestedVariables.test.js} +5 -5
- package/src/utils/variables/getVariableType.test.js +109 -0
- package/src/utils/variables/variableUtils.test.js +117 -0
- package/src/utils/isValidValue.js +0 -8
- package/src/utils/splitCsv.js +0 -29
- package/src/utils/trimSurroundingQuotes.js +0 -5
- /package/src/utils/{arrayToJsonPath.js → parsing/arrayToJsonPath.js} +0 -0
- /package/src/utils/{cloudformationSchema.js → parsing/cloudformationSchema.js} +0 -0
- /package/src/utils/{mergeByKeys.js → parsing/mergeByKeys.js} +0 -0
- /package/src/utils/{find-project-root.js → paths/findProjectRoot.js} +0 -0
- /package/src/utils/{resolveAlias.test.js → paths/resolveAlias.test.js} +0 -0
- /package/src/utils/{replaceAll.js → strings/replaceAll.js} +0 -0
- /package/src/utils/{splitByComma.test.js → strings/splitByComma.test.js} +0 -0
- /package/src/utils/{textUtils.js → strings/textUtils.js} +0 -0
- /package/src/utils/{chalk.js → ui/chalk.js} +0 -0
- /package/src/utils/{deep-log.js → ui/deep-log.js} +0 -0
- /package/src/utils/{appendDeepVariable.js → variables/appendDeepVariable.js} +0 -0
- /package/src/utils/{cleanVariable.test.js → variables/cleanVariable.test.js} +0 -0
- /package/src/utils/{getVariableType.js → variables/getVariableType.js} +0 -0
- /package/src/utils/{variableUtils.js → variables/variableUtils.js} +0 -0
package/README.md
CHANGED
|
@@ -15,6 +15,7 @@ Configorama extends your configuration with a powerful variable system. It resol
|
|
|
15
15
|
- Self references (other keys/values in config)
|
|
16
16
|
- Git references
|
|
17
17
|
- Cron values
|
|
18
|
+
- Eval expressions
|
|
18
19
|
- Async/sync JS functions
|
|
19
20
|
- Filters (experimental)
|
|
20
21
|
- Functions (experimental)
|
|
@@ -28,6 +29,7 @@ See [tests](https://github.com/DavidWells/configorama/tree/master/tests) for mor
|
|
|
28
29
|
<summary>Click to expand</summary>
|
|
29
30
|
|
|
30
31
|
- [About](#about)
|
|
32
|
+
- [How it works](#how-it-works)
|
|
31
33
|
- [Usage](#usage)
|
|
32
34
|
- [Variable Sources](#variable-sources)
|
|
33
35
|
- [Environment variables](#environment-variables)
|
|
@@ -38,10 +40,12 @@ See [tests](https://github.com/DavidWells/configorama/tree/master/tests) for mor
|
|
|
38
40
|
- [TypeScript file references](#typescript-file-references)
|
|
39
41
|
- [Git references](#git-references)
|
|
40
42
|
- [Cron Values](#cron-values)
|
|
43
|
+
- [Eval expressions](#eval-expressions)
|
|
41
44
|
- [Filters (experimental)](#filters-experimental)
|
|
42
45
|
- [Functions (experimental)](#functions-experimental)
|
|
43
46
|
- [More Examples](#more-examples)
|
|
44
47
|
- [Custom Variable Sources](#custom-variable-sources)
|
|
48
|
+
- [Options](#options)
|
|
45
49
|
- [FAQ](#faq)
|
|
46
50
|
- [Whats new](#whats-new)
|
|
47
51
|
- [Alt libs](#alt-libs)
|
|
@@ -61,10 +65,9 @@ const cliFlags = require('minimist')(process.argv.slice(2))
|
|
|
61
65
|
|
|
62
66
|
// Path to yaml/json/toml config
|
|
63
67
|
const myConfigFilePath = path.join(__dirname, 'config.yml')
|
|
64
|
-
|
|
65
|
-
const config = await configorama(myConfigFilePath, {
|
|
66
|
-
|
|
67
|
-
})
|
|
68
|
+
// Execute config resolution asyncronously
|
|
69
|
+
const config = await configorama(myConfigFilePath, { options: cliFlags })
|
|
70
|
+
console.log(config) // resolved config
|
|
68
71
|
```
|
|
69
72
|
|
|
70
73
|
Sync API:
|
|
@@ -76,16 +79,73 @@ const cliFlags = require('minimist')(process.argv.slice(2))
|
|
|
76
79
|
|
|
77
80
|
// Path to yaml/json/toml config
|
|
78
81
|
const myConfigFilePath = path.join(__dirname, 'config.yml')
|
|
82
|
+
// Execute config resolution syncronously
|
|
83
|
+
const config = configorama.sync(myConfigFilePath, { options: cliFlags })
|
|
84
|
+
console.log(config) // resolved config
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## How it works
|
|
88
|
+
|
|
89
|
+
Configorama creates a graph of your config file and all its dependencies, then it resolves the value based on it's variable sources. If `returnMetadata` option is set, you can see the entire graph and all file dependencies.
|
|
90
|
+
|
|
91
|
+
```mermaid
|
|
92
|
+
flowchart TD
|
|
93
|
+
A[Load config file] --> B[Parse yml/json/toml to object]
|
|
94
|
+
B --> C[Preprocess: raw config file]
|
|
95
|
+
C --> D{Return metadata only?}
|
|
96
|
+
D -->|Yes| E[Collect variable metadata]
|
|
97
|
+
E --> F[Return found variable metadata + original config]
|
|
98
|
+
D -->|No| G[Traverse & resolve variables recursively]
|
|
99
|
+
G --> H[Post-process: runs filters and functions]
|
|
100
|
+
H --> I[Return resolved config]
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Analyze config without resolving:**
|
|
79
104
|
|
|
80
|
-
|
|
81
|
-
|
|
105
|
+
```js
|
|
106
|
+
const result = await configorama.analyze('config.yml')
|
|
107
|
+
|
|
108
|
+
// Returns metadata about variables without resolving them
|
|
109
|
+
console.log(result.originalConfig) // Raw config object
|
|
110
|
+
console.log(result.variables) // All variables found
|
|
111
|
+
console.log(result.uniqueVariables) // Variables grouped by name
|
|
112
|
+
console.log(result.fileDependencies) // File references found
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Resolve config and return metadata:**
|
|
116
|
+
|
|
117
|
+
```js
|
|
118
|
+
const result = await configorama('config.yml', {
|
|
119
|
+
returnMetadata: true,
|
|
120
|
+
// Example option for ${opt:stage}
|
|
121
|
+
options: { stage: 'prod' }
|
|
82
122
|
})
|
|
123
|
+
|
|
124
|
+
// Returns both resolved config and metadata
|
|
125
|
+
console.log(result.originalConfig) // Raw config object
|
|
126
|
+
console.log(result.config) // Fully resolved config
|
|
127
|
+
console.log(result.metadata.variables) // Variable info with resolution details
|
|
128
|
+
console.log(result.metadata.fileDependencies) // All file dependencies
|
|
129
|
+
console.log(result.metadata.summary) // { totalVariables, requiredVariables, variablesWithDefaults }
|
|
130
|
+
console.log(result.resolutionHistory) // Step-by-step resolution for each path
|
|
83
131
|
```
|
|
84
132
|
|
|
85
133
|
## Variable Sources
|
|
86
134
|
|
|
135
|
+
| Variable | Syntax | Description |
|
|
136
|
+
|----------|-----------------------|------------------------|
|
|
137
|
+
| env | ${env:VAR} | Environment variables |
|
|
138
|
+
| opt | ${opt:flag} | CLI option flags |
|
|
139
|
+
| self | ${key} or ${self:key} | Self references |
|
|
140
|
+
| file | ${file(path)} | File references |
|
|
141
|
+
| git | ${git:value} | Git data |
|
|
142
|
+
| cron | ${cron(expr)} | Cron expressions |
|
|
143
|
+
| eval | ${eval(expr)} | Math/logic expressions |
|
|
144
|
+
|
|
87
145
|
### Environment variables
|
|
88
146
|
|
|
147
|
+
Access values from `process.env` environment variables.
|
|
148
|
+
|
|
89
149
|
```yml
|
|
90
150
|
apiKey: ${env:SECRET_KEY}
|
|
91
151
|
|
|
@@ -95,6 +155,8 @@ apiKeyWithFallback: ${env:SECRET_KEY, 'defaultApiKey'}
|
|
|
95
155
|
|
|
96
156
|
### CLI option flags
|
|
97
157
|
|
|
158
|
+
Access values from command line arguments passed via the `options` parameter.
|
|
159
|
+
|
|
98
160
|
```yml
|
|
99
161
|
# CLI option. Example `cmd --stage dev` makes `bar: dev`
|
|
100
162
|
bar: ${opt:stage}
|
|
@@ -108,6 +170,8 @@ foo: ${opt:stage, 'dev'}
|
|
|
108
170
|
|
|
109
171
|
### Self references
|
|
110
172
|
|
|
173
|
+
Reference values from other key paths in the same configuration file.
|
|
174
|
+
|
|
111
175
|
```yml
|
|
112
176
|
foo: bar
|
|
113
177
|
|
|
@@ -116,18 +180,20 @@ zaz:
|
|
|
116
180
|
wow:
|
|
117
181
|
cool: 2
|
|
118
182
|
|
|
119
|
-
#
|
|
120
|
-
|
|
183
|
+
# Shorthand dot.prop reference.
|
|
184
|
+
two: ${foo} # Resolves to `bar`
|
|
121
185
|
|
|
122
|
-
#
|
|
123
|
-
|
|
186
|
+
# Longer more explicit self file reference.
|
|
187
|
+
one: ${self:foo} # Resolves to `bar`
|
|
124
188
|
|
|
125
|
-
# Dot prop reference will traverse the object.
|
|
126
|
-
three: ${zaz.wow.cool}
|
|
189
|
+
# Dot prop reference will traverse the object.
|
|
190
|
+
three: ${zaz.wow.cool} # Resolves to `2`
|
|
127
191
|
```
|
|
128
192
|
|
|
129
193
|
### File references
|
|
130
194
|
|
|
195
|
+
Import values from external yml, json, or toml files by relative path.
|
|
196
|
+
|
|
131
197
|
```yml
|
|
132
198
|
# Import full yml/json/toml file via relative path
|
|
133
199
|
fileRef: ${file(./subFile.yml)}
|
|
@@ -142,8 +208,22 @@ fileValueSubKey: ${file(./other-config.json):nested.value}
|
|
|
142
208
|
fallbackValueExample: ${file(./not-found.yml), 'fall back value'}
|
|
143
209
|
```
|
|
144
210
|
|
|
211
|
+
Supported file types (extensions are case-insensitive):
|
|
212
|
+
|
|
213
|
+
| Type | Extensions |
|
|
214
|
+
|------|------------|
|
|
215
|
+
| TypeScript | `.ts`, `.tsx`, `.mts`, `.cts` |
|
|
216
|
+
| JavaScript | `.js`, `.cjs` |
|
|
217
|
+
| ESM | `.mjs`, `.esm` |
|
|
218
|
+
| YAML | `.yml`, `.yaml` |
|
|
219
|
+
| TOML | `.toml`, `.tml` |
|
|
220
|
+
| INI | `.ini` |
|
|
221
|
+
| JSON | `.json`, `.json5` |
|
|
222
|
+
|
|
145
223
|
### Sync/Async file references
|
|
146
224
|
|
|
225
|
+
Execute JavaScript files and use their exported function's return value.
|
|
226
|
+
|
|
147
227
|
```yml
|
|
148
228
|
asyncJSValue: ${file(./async-value.js)}
|
|
149
229
|
# resolves to 'asyncval'
|
|
@@ -152,11 +232,6 @@ asyncJSValue: ${file(./async-value.js)}
|
|
|
152
232
|
`${file(./asyncValue.js)}` will call into `async-value` and run/resolve the async function with values. These values can be strings, objects, arrays, whatever.
|
|
153
233
|
|
|
154
234
|
```js
|
|
155
|
-
/* async-value.js */
|
|
156
|
-
function delay(t, v) {
|
|
157
|
-
return new Promise((resolve) => setTimeout(resolve.bind(null, v), t))
|
|
158
|
-
}
|
|
159
|
-
|
|
160
235
|
async function fetchSecretsFromRemoteStore(config) {
|
|
161
236
|
await delay(1000)
|
|
162
237
|
return 'asyncval'
|
|
@@ -167,7 +242,7 @@ module.exports = fetchSecretsFromRemoteStore
|
|
|
167
242
|
|
|
168
243
|
### TypeScript file references
|
|
169
244
|
|
|
170
|
-
|
|
245
|
+
Execute TypeScript files using tsx (recommended) or ts-node.
|
|
171
246
|
|
|
172
247
|
```yml
|
|
173
248
|
# TypeScript configuration object
|
|
@@ -323,7 +398,7 @@ npm install ts-node typescript --save-dev
|
|
|
323
398
|
|
|
324
399
|
### Git references
|
|
325
400
|
|
|
326
|
-
|
|
401
|
+
Access repository information from the current working directory's git data.
|
|
327
402
|
|
|
328
403
|
<!-- doc-gen CODE src=tests/gitVariables/gitVariables.yml -->
|
|
329
404
|
```yml
|
|
@@ -381,7 +456,7 @@ gitTimestampAbsolutePath: ${git:timestamp('package.json')}
|
|
|
381
456
|
|
|
382
457
|
### Cron Values
|
|
383
458
|
|
|
384
|
-
Convert human-readable time expressions into cron
|
|
459
|
+
Convert human-readable time expressions into standard cron syntax.
|
|
385
460
|
|
|
386
461
|
```yml
|
|
387
462
|
# Basic patterns
|
|
@@ -413,9 +488,31 @@ sundayNoon: ${cron('on sunday at 12:00')} # 0 12 * * 0
|
|
|
413
488
|
customCron: ${cron('15 2 * * *')} # 15 2 * * *
|
|
414
489
|
```
|
|
415
490
|
|
|
491
|
+
### Eval expressions
|
|
492
|
+
|
|
493
|
+
Evaluate mathematical and logical expressions safely (without using JavaScript's `eval`).
|
|
494
|
+
|
|
495
|
+
```yml
|
|
496
|
+
# Math operations
|
|
497
|
+
sum: ${eval(10 + 5)} # 15
|
|
498
|
+
multiply: ${eval(10 * 3)} # 30
|
|
499
|
+
divide: ${eval(100 / 4)} # 25
|
|
500
|
+
|
|
501
|
+
# Comparisons (returns boolean)
|
|
502
|
+
isGreater: ${eval(200 > 100)} # true
|
|
503
|
+
isLess: ${eval(100 > 200)} # false
|
|
504
|
+
|
|
505
|
+
# String comparisons
|
|
506
|
+
isEqual: ${eval("hello" == "hello")} # true
|
|
507
|
+
strictEqual: ${eval("foo" === "foo")} # true
|
|
508
|
+
|
|
509
|
+
# Complex expressions
|
|
510
|
+
complex: ${eval((10 + 5) * 2)} # 30
|
|
511
|
+
```
|
|
512
|
+
|
|
416
513
|
### Filters (experimental)
|
|
417
514
|
|
|
418
|
-
|
|
515
|
+
Pipe resolved values through transformation functions like case conversion.
|
|
419
516
|
|
|
420
517
|
```yml
|
|
421
518
|
toUpperCaseString: ${'value' | toUpperCase }
|
|
@@ -433,7 +530,7 @@ toCamelCase: ${keyTwo | toCamelCase }
|
|
|
433
530
|
|
|
434
531
|
### Functions (experimental)
|
|
435
532
|
|
|
436
|
-
|
|
533
|
+
Apply built-in functions to combine, transform, or manipulate values.
|
|
437
534
|
|
|
438
535
|
```yml
|
|
439
536
|
object:
|
|
@@ -464,6 +561,16 @@ There are 2 ways to resolve variables from custom sources.
|
|
|
464
561
|
```js
|
|
465
562
|
const config = configorama('path/to/configFile', {
|
|
466
563
|
variableSources: [{
|
|
564
|
+
// Variable type name (used in metadata)
|
|
565
|
+
type: 'consul',
|
|
566
|
+
// Source type for config wizard behavior (see table below)
|
|
567
|
+
source: 'remote',
|
|
568
|
+
// Prefix shown in syntax examples
|
|
569
|
+
prefix: 'consul',
|
|
570
|
+
// Example syntax for documentation
|
|
571
|
+
syntax: '${consul:path/to/key}',
|
|
572
|
+
// Description for help text
|
|
573
|
+
description: 'Resolves values from Consul KV store',
|
|
467
574
|
// Match variables ${consul:xyz}
|
|
468
575
|
match: RegExp(/^consul:/g),
|
|
469
576
|
// Custom variable source. Must return a promise
|
|
@@ -482,6 +589,72 @@ There are 2 ways to resolve variables from custom sources.
|
|
|
482
589
|
key: ${consul:xyz}
|
|
483
590
|
```
|
|
484
591
|
|
|
592
|
+
### Variable Source Types
|
|
593
|
+
|
|
594
|
+
The `source` property defines how the config wizard handles each variable type:
|
|
595
|
+
|
|
596
|
+
| Source | Description | Wizard Behavior | Examples |
|
|
597
|
+
|--------|-------------|-----------------|----------|
|
|
598
|
+
| `'user'` | Values provided by user at runtime | Prompt user for value | `env`, `opt` |
|
|
599
|
+
| `'config'` | Values from config files or self-references | Check existence, can create | `self`, `file`, `text` |
|
|
600
|
+
| `'remote'` | Values from external services | Fetch, prompt if missing, can write back | `ssm`, `vault`, `consul` |
|
|
601
|
+
| `'readonly'` | Computed or system-derived values | Display only, cannot modify | `git`, `cron`, `eval` |
|
|
602
|
+
|
|
603
|
+
**Built-in variable sources and their types:**
|
|
604
|
+
|
|
605
|
+
| Variable | Source Type | Description |
|
|
606
|
+
|----------|-------------|-------------|
|
|
607
|
+
| `${env:VAR}` | `user` | Environment variables |
|
|
608
|
+
| `${opt:flag}` | `user` | CLI option flags |
|
|
609
|
+
| `${self:key}` | `config` | Self references |
|
|
610
|
+
| `${file(path)}` | `config` | File references |
|
|
611
|
+
| `${text(path)}` | `config` | Raw text file references |
|
|
612
|
+
| `${git:branch}` | `readonly` | Git repository data |
|
|
613
|
+
| `${cron(expr)}` | `readonly` | Cron expression conversion |
|
|
614
|
+
| `${eval(expr)}` | `readonly` | Math/logic evaluation |
|
|
615
|
+
|
|
616
|
+
## Options
|
|
617
|
+
|
|
618
|
+
| Option | Type | Default | Description |
|
|
619
|
+
|--------|------|---------|-------------|
|
|
620
|
+
| `options` | object | `{}` | CLI options/flags to populate `${opt:xyz}` variables |
|
|
621
|
+
| `allowUnknownVariables` | boolean | `false` | Allow unknown variable types to pass through (e.g., `${custom:thing}`) |
|
|
622
|
+
| `allowUnresolvedVariables` | boolean | `false` | Allow known variable types that can't be resolved to pass through instead of throwing |
|
|
623
|
+
| `allowUndefinedValues` | boolean | `false` | Allow undefined to be an end result |
|
|
624
|
+
| `variableSources` | array | `[]` | Custom variable sources (see above) |
|
|
625
|
+
|
|
626
|
+
> **Note:** `allowUnknownVars` is deprecated, use `allowUnknownVariables` instead.
|
|
627
|
+
|
|
628
|
+
### allowUnknownVariables
|
|
629
|
+
|
|
630
|
+
When `allowUnknownVariables: true`, unknown variable types (not registered resolvers) pass through as-is:
|
|
631
|
+
|
|
632
|
+
```js
|
|
633
|
+
const config = await configorama(configFile, {
|
|
634
|
+
allowUnknownVariables: true,
|
|
635
|
+
options: { stage: 'dev' }
|
|
636
|
+
})
|
|
637
|
+
|
|
638
|
+
// Input: { key: '${ssm:/path/to/secret}' } // ssm: not a registered type
|
|
639
|
+
// Output: { key: '${ssm:/path/to/secret}' } // passes through instead of throwing
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
### allowUnresolvedVariables
|
|
643
|
+
|
|
644
|
+
When `allowUnresolvedVariables: true`, variables that can't be resolved (missing env vars, missing files, etc.) pass through as-is instead of throwing an error:
|
|
645
|
+
|
|
646
|
+
```js
|
|
647
|
+
const config = await configorama(configFile, {
|
|
648
|
+
allowUnresolvedVariables: true,
|
|
649
|
+
options: { stage: 'dev' }
|
|
650
|
+
})
|
|
651
|
+
|
|
652
|
+
// Input: { key: '${env:MISSING_VAR}' }
|
|
653
|
+
// Output: { key: '${env:MISSING_VAR}' } // passes through instead of throwing
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
This is useful for multi-stage resolution or when you want to analyze config structure without providing all values.
|
|
657
|
+
|
|
485
658
|
## FAQ
|
|
486
659
|
|
|
487
660
|
**Q: Why should I use this?**
|
|
@@ -537,13 +710,12 @@ How is this different than the serverless variable system?
|
|
|
537
710
|
key: ${env:whatever, 2}
|
|
538
711
|
```
|
|
539
712
|
|
|
540
|
-
6. TOML, YML, JSON, etc support
|
|
713
|
+
6. TOML, YML, JSON, INI etc support
|
|
541
714
|
|
|
542
715
|
Configorama will work on any configuration format that can be converted into a JS object.
|
|
543
716
|
|
|
544
717
|
Parse any config format and pass it into configorama.
|
|
545
718
|
|
|
546
|
-
|
|
547
719
|
7. Configorama has a number of built-in functions.
|
|
548
720
|
|
|
549
721
|
Build in functions can be used within expressions as another way to transform and combine values. These are similar to the operators but all follow a common syntax:
|
package/cli.js
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
const fs = require('fs')
|
|
4
4
|
const minimist = require('minimist')
|
|
5
5
|
const Configorama = require('./src/main')
|
|
6
|
-
const deepLog = require('./src/utils/deep-log')
|
|
7
|
-
const { logHeader } = require('./src/utils/logs')
|
|
6
|
+
const deepLog = require('./src/utils/ui/deep-log')
|
|
7
|
+
const { logHeader } = require('./src/utils/ui/logs')
|
|
8
8
|
const configorama = require('./src')
|
|
9
9
|
const { makeBox } = require('@davidwells/box-logger')
|
|
10
10
|
|
|
@@ -81,7 +81,7 @@ const options = {
|
|
|
81
81
|
allowUndefinedValues: argv['allow-undefined'] || false,
|
|
82
82
|
allowUnknownFileRefs: argv['allow-unknown-file-refs'] || false,
|
|
83
83
|
returnMetadata: argv['return-metadata'] || false,
|
|
84
|
-
returnPreResolvedVariableDetails:
|
|
84
|
+
returnPreResolvedVariableDetails: false,
|
|
85
85
|
dynamicArgs: argv
|
|
86
86
|
}
|
|
87
87
|
|
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const Configorama = require('./main')
|
|
2
2
|
const parsers = require('./parsers')
|
|
3
|
-
const enrichMetadata = require('./utils/enrichMetadata')
|
|
3
|
+
const enrichMetadata = require('./utils/parsing/enrichMetadata')
|
|
4
4
|
|
|
5
5
|
module.exports.Configorama = Configorama
|
|
6
6
|
|
|
@@ -28,52 +28,27 @@ module.exports = async (configPathOrObject, settings = {}) => {
|
|
|
28
28
|
if (settings.returnMetadata) {
|
|
29
29
|
const metadata = instance.collectVariableMetadata()
|
|
30
30
|
|
|
31
|
-
// console.log('instance.fileRefsFound', instance.fileRefsFound)
|
|
32
|
-
// console.log('instance.resolutionTracking', instance.resolutionTracking)
|
|
33
|
-
// process.exit(1)
|
|
34
|
-
|
|
35
31
|
// Enrich metadata with resolution tracking data collected during execution
|
|
36
|
-
const enrichedMetadata = enrichMetadata(
|
|
32
|
+
const enrichedMetadata = await enrichMetadata(
|
|
37
33
|
metadata,
|
|
38
34
|
instance.resolutionTracking,
|
|
39
35
|
instance.variableSyntax,
|
|
40
36
|
instance.fileRefsFound,
|
|
41
37
|
instance.originalConfig,
|
|
42
38
|
instance.configFilePath,
|
|
43
|
-
Object.keys(instance.filters)
|
|
39
|
+
Object.keys(instance.filters),
|
|
40
|
+
config, // pass resolved config for post-resolution enrichment
|
|
41
|
+
options,
|
|
42
|
+
instance.variableTypes
|
|
44
43
|
)
|
|
45
44
|
|
|
46
|
-
// Add resolvedPropertyValue to resolutionTracking
|
|
47
|
-
const resolutionHistoryWithResolvedValues = {}
|
|
48
|
-
for (const pathKey in instance.resolutionTracking) {
|
|
49
|
-
const tracking = instance.resolutionTracking[pathKey]
|
|
50
|
-
const keys = pathKey.split('.')
|
|
51
|
-
let resolvedValue = config
|
|
52
|
-
|
|
53
|
-
// Navigate to the resolved value in the config
|
|
54
|
-
for (const key of keys) {
|
|
55
|
-
if (resolvedValue && typeof resolvedValue === 'object') {
|
|
56
|
-
resolvedValue = resolvedValue[key]
|
|
57
|
-
} else {
|
|
58
|
-
resolvedValue = undefined
|
|
59
|
-
break
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
resolutionHistoryWithResolvedValues[pathKey] = {
|
|
64
|
-
...tracking,
|
|
65
|
-
resolvedPropertyValue: resolvedValue
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
45
|
return {
|
|
70
46
|
variableSyntax: instance.variableSyntax,
|
|
71
47
|
variableTypes: instance.variableTypes,
|
|
72
48
|
config,
|
|
73
49
|
originalConfig: instance.originalConfig,
|
|
74
50
|
metadata: enrichedMetadata,
|
|
75
|
-
|
|
76
|
-
resolutionHistory: resolutionHistoryWithResolvedValues,
|
|
51
|
+
resolutionHistory: enrichedMetadata.resolutionHistory,
|
|
77
52
|
}
|
|
78
53
|
}
|
|
79
54
|
|
|
@@ -96,5 +71,20 @@ module.exports.sync = (configPathOrObject, settings = {}) => {
|
|
|
96
71
|
})
|
|
97
72
|
}
|
|
98
73
|
|
|
74
|
+
/**
|
|
75
|
+
* Analyze config variables without resolving them
|
|
76
|
+
* @param {string|object} configPathOrObject - Path to config file or raw javascript config object
|
|
77
|
+
* @param {object} [settings] - Same settings as the main API
|
|
78
|
+
* @return {Promise} Pre-resolved variable metadata
|
|
79
|
+
*/
|
|
80
|
+
module.exports.analyze = async (configPathOrObject, settings = {}) => {
|
|
81
|
+
const instance = new Configorama(configPathOrObject, {
|
|
82
|
+
...settings,
|
|
83
|
+
returnPreResolvedVariableDetails: true,
|
|
84
|
+
})
|
|
85
|
+
const options = settings.options || {}
|
|
86
|
+
return instance.init(options)
|
|
87
|
+
}
|
|
88
|
+
|
|
99
89
|
// Export format utilities
|
|
100
90
|
module.exports.format = parsers
|