configorama 1.0.2 → 1.1.0
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 +31 -0
- package/package.json +10 -3
- package/plugins/cloudformation/README.md +79 -0
- package/plugins/cloudformation/credentials.js +231 -0
- package/plugins/cloudformation/index.js +204 -0
- package/plugins/cloudformation/package-lock.json +657 -0
- package/plugins/cloudformation/package.json +24 -0
- package/plugins/onepassword/README.md +175 -0
- package/plugins/onepassword/fields.js +126 -0
- package/plugins/onepassword/index.js +345 -0
- package/plugins/onepassword/normalize.js +145 -0
- package/plugins/onepassword/op-cli.js +117 -0
- package/plugins/onepassword/package.json +15 -0
- package/plugins/onepassword/parser.js +70 -0
- package/plugins/onepassword/sync-factory.js +15 -0
- package/src/index.js +8 -1
- package/src/main.js +6 -3
- package/src/parsers/dotenv.js +13 -0
- package/src/resolvers/valueFromFile.js +2 -1
- package/src/sync.js +27 -0
- package/src/utils/PromiseTracker.js +11 -4
- package/src/utils/PromiseTracker.test.js +48 -0
- package/src/utils/introspection/audit.js +39 -9
- package/src/utils/parsing/parse.js +10 -2
- package/src/utils/paths/fileType.js +27 -0
- package/src/utils/paths/fileType.test.js +41 -0
- package/src/utils/paths/findLineForKey.js +24 -1
- package/src/utils/paths/findLineForKey.test.js +20 -1
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Classifies config files by type, treating dotenv files as ".env"
|
|
2
|
+
// so extension-less names like .env / .env.local / deploy.env resolve consistently
|
|
3
|
+
const path = require('path')
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Whether a path is a dotenv file (.env, .env.local, deploy.env, ...).
|
|
7
|
+
* `path.extname('.env')` is '' (dotfile), so detection is by basename.
|
|
8
|
+
* @param {string} filePath - File path or name
|
|
9
|
+
* @returns {boolean} True for dotenv files
|
|
10
|
+
*/
|
|
11
|
+
function isEnvFile(filePath) {
|
|
12
|
+
const base = path.basename(String(filePath || ''))
|
|
13
|
+
return base === '.env' || base.startsWith('.env.') || base.endsWith('.env')
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Normalized config file type: '.env' for dotenv files, else the lowercased
|
|
18
|
+
* extension.
|
|
19
|
+
* @param {string} filePath - File path or name
|
|
20
|
+
* @returns {string} File type (e.g. '.yml', '.env', '')
|
|
21
|
+
*/
|
|
22
|
+
function configFileType(filePath) {
|
|
23
|
+
if (isEnvFile(filePath)) return '.env'
|
|
24
|
+
return path.extname(String(filePath || '')).toLowerCase()
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
module.exports = { isEnvFile, configFileType }
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/* Tests for config file type classification (dotenv detection) */
|
|
2
|
+
const { test } = require('uvu')
|
|
3
|
+
const assert = require('uvu/assert')
|
|
4
|
+
const { isEnvFile, configFileType } = require('./fileType')
|
|
5
|
+
|
|
6
|
+
test('isEnvFile detects the env-stage-loader precedence names', () => {
|
|
7
|
+
// .env.{environment}.local, .env.{environment}, .env.local, .env
|
|
8
|
+
assert.ok(isEnvFile('.env'))
|
|
9
|
+
assert.ok(isEnvFile('.env.local'))
|
|
10
|
+
assert.ok(isEnvFile('.env.production'))
|
|
11
|
+
assert.ok(isEnvFile('.env.production.local'))
|
|
12
|
+
assert.ok(isEnvFile('/path/to/.env.staging.local'))
|
|
13
|
+
assert.ok(isEnvFile('deploy.env'))
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
test('isEnvFile rejects non-dotenv names', () => {
|
|
17
|
+
assert.is(isEnvFile('config.yml'), false)
|
|
18
|
+
assert.is(isEnvFile('env.js'), false)
|
|
19
|
+
assert.is(isEnvFile('environment.json'), false)
|
|
20
|
+
assert.is(isEnvFile('.environment'), false)
|
|
21
|
+
assert.is(isEnvFile(''), false)
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
test('configFileType returns .env for staged dotenv names', () => {
|
|
25
|
+
assert.is(configFileType('.env.production.local'), '.env')
|
|
26
|
+
assert.is(configFileType('.env.staging'), '.env')
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
test('configFileType returns .env for dotenv files', () => {
|
|
30
|
+
assert.is(configFileType('.env'), '.env')
|
|
31
|
+
assert.is(configFileType('/x/.env.local'), '.env')
|
|
32
|
+
assert.is(configFileType('deploy.env'), '.env')
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
test('configFileType returns lowercased extension otherwise', () => {
|
|
36
|
+
assert.is(configFileType('config.YML'), '.yml')
|
|
37
|
+
assert.is(configFileType('data.json'), '.json')
|
|
38
|
+
assert.is(configFileType('noext'), '')
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
test.run()
|
|
@@ -31,6 +31,10 @@ function findLineForKey(keyToFind, lines, fileType) {
|
|
|
31
31
|
if (fileType === '.ini') {
|
|
32
32
|
return new RegExp(`^\\s*${escapedKey}\\s*=`).test(line)
|
|
33
33
|
}
|
|
34
|
+
// dotenv: KEY= or export KEY=
|
|
35
|
+
if (fileType === '.env') {
|
|
36
|
+
return new RegExp(`^\\s*(?:export\\s+)?${escapedKey}\\s*=`).test(line)
|
|
37
|
+
}
|
|
34
38
|
// JS/TS/ESM: key: or "key": or 'key': or `key`: or [`key`]:
|
|
35
39
|
if (['.js', '.mjs', '.cjs', '.ts', '.mts', '.cts'].includes(fileType)) {
|
|
36
40
|
return new RegExp(`(?:${escapedKey}|"${escapedKey}"|'${escapedKey}'|\`${escapedKey}\`|\\[\`${escapedKey}\`\\])\\s*:`).test(line)
|
|
@@ -55,13 +59,32 @@ function findLineByPath(configPath, lines, fileType) {
|
|
|
55
59
|
|
|
56
60
|
const isYaml = fileType === '.yml' || fileType === '.yaml'
|
|
57
61
|
const isJson = fileType === '.json' || fileType === '.json5' || fileType === '.jsonc'
|
|
58
|
-
|
|
62
|
+
const isEnv = fileType === '.env'
|
|
63
|
+
if (!isYaml && !isJson && !isEnv) return 0
|
|
59
64
|
|
|
60
65
|
const segments = configPath.split('.')
|
|
66
|
+
if (isEnv) return findLineByPathEnv(segments, lines)
|
|
61
67
|
if (isYaml) return findLineByPathYaml(segments, lines)
|
|
62
68
|
return findLineByPathJson(segments, lines)
|
|
63
69
|
}
|
|
64
70
|
|
|
71
|
+
/**
|
|
72
|
+
* Find a dotenv key's line. .env is flat, so the key is the first path segment.
|
|
73
|
+
* Handles leading whitespace and an optional `export ` prefix.
|
|
74
|
+
* @param {string[]} segments
|
|
75
|
+
* @param {string[]} lines
|
|
76
|
+
* @returns {number}
|
|
77
|
+
*/
|
|
78
|
+
function findLineByPathEnv(segments, lines) {
|
|
79
|
+
const key = segments[0]
|
|
80
|
+
const escaped = key.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
81
|
+
const pattern = new RegExp(`^\\s*(?:export\\s+)?${escaped}\\s*=`)
|
|
82
|
+
for (let li = 0; li < lines.length; li++) {
|
|
83
|
+
if (pattern.test(lines[li])) return li + 1
|
|
84
|
+
}
|
|
85
|
+
return 0
|
|
86
|
+
}
|
|
87
|
+
|
|
65
88
|
/**
|
|
66
89
|
* @param {string[]} segments
|
|
67
90
|
* @param {string[]} lines
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
const { test } = require('uvu')
|
|
5
5
|
const assert = require('uvu/assert')
|
|
6
|
-
const { findLineForKey } = require('./findLineForKey')
|
|
6
|
+
const { findLineForKey, findLineByPath } = require('./findLineForKey')
|
|
7
7
|
|
|
8
8
|
// YAML tests
|
|
9
9
|
test('YAML - finds key at start of line', () => {
|
|
@@ -123,4 +123,23 @@ test('unknown file type falls back to YAML-style', () => {
|
|
|
123
123
|
assert.equal(findLineForKey('foo', lines, '.unknown'), 1)
|
|
124
124
|
})
|
|
125
125
|
|
|
126
|
+
// dotenv
|
|
127
|
+
test('dotenv - finds KEY= line', () => {
|
|
128
|
+
const lines = ['API_URL=https://x', 'stage=${opt:stage}']
|
|
129
|
+
assert.equal(findLineForKey('stage', lines, '.env'), 2)
|
|
130
|
+
assert.equal(findLineForKey('API_URL', lines, '.env'), 1)
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
test('dotenv - finds export-prefixed and whitespace-padded keys', () => {
|
|
134
|
+
const lines = ['# comment', 'export TOKEN=abc', ' PADDED = x']
|
|
135
|
+
assert.equal(findLineForKey('TOKEN', lines, '.env'), 2)
|
|
136
|
+
assert.equal(findLineForKey('PADDED', lines, '.env'), 3)
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
test('findLineByPath - dotenv key lookup', () => {
|
|
140
|
+
const lines = ['A=1', 'stage=${opt:stage}', 'B=2']
|
|
141
|
+
assert.equal(findLineByPath('stage', lines, '.env'), 2)
|
|
142
|
+
assert.equal(findLineByPath('missing', lines, '.env'), 0)
|
|
143
|
+
})
|
|
144
|
+
|
|
126
145
|
test.run()
|