configorama 0.4.6 → 0.4.8
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/lib/main.js +18 -13
- package/lib/parsers/yaml.js +121 -0
- package/package.json +9 -9
package/lib/main.js
CHANGED
|
@@ -77,6 +77,18 @@ class Configorama {
|
|
|
77
77
|
allowUndefinedValues: false,
|
|
78
78
|
}, options)
|
|
79
79
|
|
|
80
|
+
|
|
81
|
+
const defaultSyntax = '\\${((?!AWS)[ ~:a-zA-Z0-9=+!@#%*<>?._\'",|\\-\\/\\(\\)\\\\]+?)}'
|
|
82
|
+
const variableSyntax = options.syntax || defaultSyntax
|
|
83
|
+
let varRegex
|
|
84
|
+
if (typeof variableSyntax === 'string') {
|
|
85
|
+
varRegex = RegExp(variableSyntax, 'g')
|
|
86
|
+
// this.variableSyntax = /\${((?!AWS)([ ~:a-zA-Z0-9=+!@#%*<>?._'",|\-\/\(\)\\]+?|(\w+)\s*\(((?:[^()]+)*)?\s*\)\s*))}/
|
|
87
|
+
} else if (variableSyntax instanceof RegExp) {
|
|
88
|
+
varRegex = variableSyntax
|
|
89
|
+
}
|
|
90
|
+
this.variableSyntax = varRegex
|
|
91
|
+
|
|
80
92
|
// Set initial config object to populate
|
|
81
93
|
if (typeof fileOrObject === 'object') {
|
|
82
94
|
// set config objects
|
|
@@ -94,11 +106,14 @@ class Configorama {
|
|
|
94
106
|
let configObject
|
|
95
107
|
if (fileType.match(/\.(yml|yaml)/)) {
|
|
96
108
|
try {
|
|
97
|
-
|
|
109
|
+
const ymlText = YAML.preProcess(fileContents, varRegex)
|
|
110
|
+
// console.log('ymlText', ymlText)
|
|
111
|
+
configObject = YAML.parse(ymlText)
|
|
98
112
|
} catch (err) {
|
|
99
113
|
// Attempt to fix cloudformation refs
|
|
100
114
|
if (err.message.match(/YAMLException/)) {
|
|
101
|
-
const
|
|
115
|
+
const ymlText = YAML.preProcess(fileContents, varRegex)
|
|
116
|
+
const result = YAML.load(ymlText, {
|
|
102
117
|
filename: fileOrObject,
|
|
103
118
|
schema: cloudFormationSchema.schema
|
|
104
119
|
})
|
|
@@ -140,16 +155,6 @@ class Configorama {
|
|
|
140
155
|
// Track promise resolution
|
|
141
156
|
this.tracker = new PromiseTracker()
|
|
142
157
|
|
|
143
|
-
const defaultSyntax = '\\${((?!AWS)[ ~:a-zA-Z0-9=+!@#%*<>?._\'",|\\-\\/\\(\\)\\\\]+?)}'
|
|
144
|
-
const variableSyntax = options.syntax || defaultSyntax
|
|
145
|
-
|
|
146
|
-
if (typeof variableSyntax === 'string') {
|
|
147
|
-
this.variableSyntax = RegExp(variableSyntax, 'g')
|
|
148
|
-
// this.variableSyntax = /\${((?!AWS)([ ~:a-zA-Z0-9=+!@#%*<>?._'",|\-\/\(\)\\]+?|(\w+)\s*\(((?:[^()]+)*)?\s*\)\s*))}/
|
|
149
|
-
} else if (variableSyntax instanceof RegExp) {
|
|
150
|
-
this.variableSyntax = variableSyntax
|
|
151
|
-
}
|
|
152
|
-
|
|
153
158
|
// Variable Sources
|
|
154
159
|
this.variableTypes = [
|
|
155
160
|
/**
|
|
@@ -1671,7 +1676,7 @@ Please use ":" to reference sub properties`
|
|
|
1671
1676
|
|
|
1672
1677
|
function findNestedVariable(split, originalSource) {
|
|
1673
1678
|
return split.find((thing) => {
|
|
1674
|
-
if (originalSource) {
|
|
1679
|
+
if (originalSource && typeof originalSource === 'string') {
|
|
1675
1680
|
return originalSource.indexOf(`\${${thing}}`) > -1
|
|
1676
1681
|
}
|
|
1677
1682
|
return false
|
package/lib/parsers/yaml.js
CHANGED
|
@@ -57,7 +57,128 @@ function toJson(ymlContents) {
|
|
|
57
57
|
return json
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
// TODO only works for default var syntax ${}. Maybe fix?
|
|
61
|
+
function findOutermostVariables(text) {
|
|
62
|
+
let matches = [];
|
|
63
|
+
let depth = 0;
|
|
64
|
+
let startIndex = -1;
|
|
65
|
+
|
|
66
|
+
for (let i = 0; i < text.length; i++) {
|
|
67
|
+
if (text[i] === '$' && text[i + 1] === '{') {
|
|
68
|
+
if (depth === 0) {
|
|
69
|
+
startIndex = i;
|
|
70
|
+
}
|
|
71
|
+
depth++;
|
|
72
|
+
i++; // Skip '{'
|
|
73
|
+
} else if (text[i] === '}') {
|
|
74
|
+
depth--;
|
|
75
|
+
if (depth === 0 && startIndex !== -1) {
|
|
76
|
+
matches.push(text.substring(startIndex, i + 1));
|
|
77
|
+
startIndex = -1;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return matches;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
function matchOutermostBraces(text) {
|
|
86
|
+
let depth = 0;
|
|
87
|
+
let startIndex = -1;
|
|
88
|
+
let results = [];
|
|
89
|
+
|
|
90
|
+
for (let i = 0; i < text.length; i++) {
|
|
91
|
+
if (text[i] === '{') {
|
|
92
|
+
if (depth === 0) {
|
|
93
|
+
startIndex = i;
|
|
94
|
+
}
|
|
95
|
+
depth++;
|
|
96
|
+
} else if (text[i] === '}') {
|
|
97
|
+
depth--;
|
|
98
|
+
if (depth === 0 && startIndex !== -1) {
|
|
99
|
+
results.push(text.substring(startIndex, i + 1));
|
|
100
|
+
startIndex = -1;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return results;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function preProcess(ymlStr = '') {
|
|
109
|
+
/*
|
|
110
|
+
return ymlStr
|
|
111
|
+
/** */
|
|
112
|
+
|
|
113
|
+
// Fix nested variables in array brackets
|
|
114
|
+
// in -> y: !Not [!Equals [!Join ['', ${param:xyz}]]]
|
|
115
|
+
// out -> y: !Not [!Equals [!Join ['', "${param:xyz}"]]]
|
|
116
|
+
const arrayBracketMatches = ymlStr && ymlStr.match(
|
|
117
|
+
// /\[(?:[^\[\]]+|)*\]/gm
|
|
118
|
+
/\[(?:[^\[\]])*\]/g
|
|
119
|
+
)
|
|
120
|
+
if (arrayBracketMatches) {
|
|
121
|
+
// console.log('arrayBracketMatches', arrayBracketMatches)
|
|
122
|
+
arrayBracketMatches.forEach((txt) => {
|
|
123
|
+
// console.log('txt', txt)
|
|
124
|
+
const hasNestedVars = txt && findOutermostVariables(txt)
|
|
125
|
+
/*
|
|
126
|
+
console.log(varRegex)
|
|
127
|
+
console.log('findOutermostVariables(txt)', findOutermostVariables(txt))
|
|
128
|
+
console.log('hasNested', hasNested)
|
|
129
|
+
/** */
|
|
130
|
+
if (hasNestedVars && hasNestedVars.length) {
|
|
131
|
+
let fixedText = txt
|
|
132
|
+
hasNestedVars.forEach((nested) => {
|
|
133
|
+
// console.log('nested', nested)
|
|
134
|
+
if (txt.indexOf(`"${nested}"`) > -1) {
|
|
135
|
+
return
|
|
136
|
+
}
|
|
137
|
+
if (txt.indexOf(`'${nested}'`) > -1) {
|
|
138
|
+
return
|
|
139
|
+
}
|
|
140
|
+
/* Replace variable wrapped in quotes */
|
|
141
|
+
fixedText = fixedText.replace(nested, `"${nested}"`)
|
|
142
|
+
})
|
|
143
|
+
ymlStr = ymlStr.replace(txt, fixedText)
|
|
144
|
+
}
|
|
145
|
+
})
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/* If have yaml object and vars not wrapped in quotes, wrap them */
|
|
149
|
+
if (ymlStr.match(/^[ \t]*[^:\n]*:\s*\{/gm)) {
|
|
150
|
+
const hasObjects = matchOutermostBraces(ymlStr)
|
|
151
|
+
// console.log('hasObjects', hasObjects)
|
|
152
|
+
if (hasObjects && hasObjects.length) {
|
|
153
|
+
hasObjects.forEach((txt) => {
|
|
154
|
+
// console.log('obj text', txt)
|
|
155
|
+
const hasNestedVars = txt && findOutermostVariables(txt)
|
|
156
|
+
if (hasNestedVars && hasNestedVars.length) {
|
|
157
|
+
let fixedText = txt
|
|
158
|
+
hasNestedVars.forEach((nested) => {
|
|
159
|
+
// console.log('nested', nested)
|
|
160
|
+
if (txt.indexOf(`"${nested}"`) > -1) {
|
|
161
|
+
return
|
|
162
|
+
}
|
|
163
|
+
if (txt.indexOf(`'${nested}'`) > -1) {
|
|
164
|
+
return
|
|
165
|
+
}
|
|
166
|
+
/* Replace variable wrapped in quotes */
|
|
167
|
+
fixedText = fixedText.replace(nested, `"${nested}"`)
|
|
168
|
+
})
|
|
169
|
+
ymlStr = ymlStr.replace(txt, fixedText)
|
|
170
|
+
}
|
|
171
|
+
})
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// console.log('ymlStr', ymlStr)
|
|
176
|
+
|
|
177
|
+
return ymlStr
|
|
178
|
+
}
|
|
179
|
+
|
|
60
180
|
module.exports = {
|
|
181
|
+
preProcess: preProcess,
|
|
61
182
|
parse: parse,
|
|
62
183
|
load: load,
|
|
63
184
|
dump: dump,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "configorama",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.8",
|
|
4
4
|
"description": "Variable support for configuration files",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"files": [
|
|
@@ -31,18 +31,18 @@
|
|
|
31
31
|
"dot-prop": "^5.3.0",
|
|
32
32
|
"find-up": "^3.0.0",
|
|
33
33
|
"git-url-parse": "^14.0.0",
|
|
34
|
-
"js-yaml": "^3.14.
|
|
35
|
-
"json5": "^2.
|
|
36
|
-
"lodash": "^4.17.
|
|
37
|
-
"promise.prototype.finally": "^3.1.
|
|
34
|
+
"js-yaml": "^3.14.1",
|
|
35
|
+
"json5": "^2.2.3",
|
|
36
|
+
"lodash": "^4.17.21",
|
|
37
|
+
"promise.prototype.finally": "^3.1.8",
|
|
38
38
|
"replaceall": "^0.1.6",
|
|
39
39
|
"sync-rpc": "^1.3.6",
|
|
40
|
-
"traverse": "^0.6.
|
|
40
|
+
"traverse": "^0.6.8"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"ava": "^2.
|
|
44
|
-
"markdown-magic": "^
|
|
45
|
-
"minimist": "^1.2.
|
|
43
|
+
"ava": "^2.4.0",
|
|
44
|
+
"markdown-magic": "^2.6.1",
|
|
45
|
+
"minimist": "^1.2.8"
|
|
46
46
|
},
|
|
47
47
|
"ava": {
|
|
48
48
|
"files": [
|