configorama 0.4.7 → 0.4.9
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 +21 -12
- package/lib/parsers/yaml.js +124 -0
- package/package.json +1 -1
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
|
/**
|
|
@@ -433,6 +438,10 @@ class Configorama {
|
|
|
433
438
|
})
|
|
434
439
|
}
|
|
435
440
|
runFunction(variableString) {
|
|
441
|
+
/* If json object value return it */
|
|
442
|
+
if (variableString.match(/^\s*{/) && variableString.match(/}\s*$/)) {
|
|
443
|
+
return variableString
|
|
444
|
+
}
|
|
436
445
|
// console.log('runFunction', variableString)
|
|
437
446
|
var hasFunc = funcRegex.exec(variableString)
|
|
438
447
|
// TODO finish Function handling. Need to move this down below resolver to resolve inner refs first
|
package/lib/parsers/yaml.js
CHANGED
|
@@ -57,7 +57,131 @@ 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
|
+
// https://regex101.com/r/XIltbc/1
|
|
109
|
+
const KEY_OBJECT = /^[ \t]*[^":\s]*:\s+\{/gm
|
|
110
|
+
|
|
111
|
+
const INNER_ARRAY = /\[(?:[^\[\]])*\]/g
|
|
112
|
+
|
|
113
|
+
function preProcess(ymlStr = '') {
|
|
114
|
+
/*
|
|
115
|
+
return ymlStr
|
|
116
|
+
/** */
|
|
117
|
+
|
|
118
|
+
// Fix nested variables in array brackets
|
|
119
|
+
// in -> y: !Not [!Equals [!Join ['', ${param:xyz}]]]
|
|
120
|
+
// out -> y: !Not [!Equals [!Join ['', "${param:xyz}"]]]
|
|
121
|
+
const arrayBracketMatches = ymlStr && ymlStr.match(
|
|
122
|
+
// /\[(?:[^\[\]]+|)*\]/gm
|
|
123
|
+
INNER_ARRAY
|
|
124
|
+
)
|
|
125
|
+
if (arrayBracketMatches) {
|
|
126
|
+
// console.log('arrayBracketMatches', arrayBracketMatches)
|
|
127
|
+
arrayBracketMatches.forEach((txt) => {
|
|
128
|
+
// console.log('txt', txt)
|
|
129
|
+
const hasNestedVars = txt && findOutermostVariables(txt)
|
|
130
|
+
/*
|
|
131
|
+
console.log(varRegex)
|
|
132
|
+
console.log('findOutermostVariables(txt)', findOutermostVariables(txt))
|
|
133
|
+
console.log('hasNested', hasNested)
|
|
134
|
+
/** */
|
|
135
|
+
if (hasNestedVars && hasNestedVars.length) {
|
|
136
|
+
let fixedText = txt
|
|
137
|
+
hasNestedVars.forEach((nested) => {
|
|
138
|
+
// console.log('nested', nested)
|
|
139
|
+
if (txt.indexOf(`"${nested}"`) > -1) {
|
|
140
|
+
return
|
|
141
|
+
}
|
|
142
|
+
if (txt.indexOf(`'${nested}'`) > -1) {
|
|
143
|
+
return
|
|
144
|
+
}
|
|
145
|
+
/* Replace variable wrapped in quotes */
|
|
146
|
+
fixedText = fixedText.replace(nested, `"${nested}"`)
|
|
147
|
+
})
|
|
148
|
+
ymlStr = ymlStr.replace(txt, fixedText)
|
|
149
|
+
}
|
|
150
|
+
})
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/* If have yaml object and vars not wrapped in quotes, wrap them */
|
|
154
|
+
if (ymlStr.match(KEY_OBJECT)) {
|
|
155
|
+
const hasObjects = matchOutermostBraces(ymlStr)
|
|
156
|
+
// console.log('hasObjects', hasObjects)
|
|
157
|
+
if (hasObjects && hasObjects.length) {
|
|
158
|
+
hasObjects.forEach((txt) => {
|
|
159
|
+
// console.log('obj text', txt)
|
|
160
|
+
const hasNestedVars = txt && findOutermostVariables(txt)
|
|
161
|
+
if (hasNestedVars && hasNestedVars.length) {
|
|
162
|
+
let fixedText = txt
|
|
163
|
+
hasNestedVars.forEach((nested) => {
|
|
164
|
+
// console.log('nested', nested)
|
|
165
|
+
if (txt.indexOf(`"${nested}"`) > -1) {
|
|
166
|
+
return
|
|
167
|
+
}
|
|
168
|
+
if (txt.indexOf(`'${nested}'`) > -1) {
|
|
169
|
+
return
|
|
170
|
+
}
|
|
171
|
+
/* Replace variable wrapped in quotes */
|
|
172
|
+
fixedText = fixedText.replace(nested, `"${nested}"`)
|
|
173
|
+
})
|
|
174
|
+
ymlStr = ymlStr.replace(txt, fixedText)
|
|
175
|
+
}
|
|
176
|
+
})
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// console.log('ymlStr', ymlStr)
|
|
180
|
+
return ymlStr
|
|
181
|
+
}
|
|
182
|
+
|
|
60
183
|
module.exports = {
|
|
184
|
+
preProcess: preProcess,
|
|
61
185
|
parse: parse,
|
|
62
186
|
load: load,
|
|
63
187
|
dump: dump,
|