configorama 0.4.9 → 0.4.10
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 +77 -59
- package/lib/resolvers/valueFromNumber.js +2 -2
- package/lib/utils/PromiseTracker.js +5 -6
- package/lib/utils/cloudformationSchema.js +10 -6
- package/lib/utils/formatFunctionArgs.js +2 -2
- package/lib/utils/handleSignalEvents.js +17 -14
- package/lib/utils/isValidValue.js +2 -2
- package/package.json +27 -18
package/lib/main.js
CHANGED
|
@@ -3,9 +3,26 @@ const path = require('path')
|
|
|
3
3
|
const fs = require('fs')
|
|
4
4
|
const promiseFinallyShim = require('promise.prototype.finally').shim()
|
|
5
5
|
// @TODO only import lodash we need
|
|
6
|
-
const
|
|
6
|
+
const isArray = require('lodash.isarray')
|
|
7
|
+
const isString = require('lodash.isstring')
|
|
8
|
+
const isNumber = require('lodash.isnumber')
|
|
9
|
+
const isObject = require('lodash.isobject')
|
|
10
|
+
const isDate = require('lodash.isdate')
|
|
11
|
+
const isRegExp = require('lodash.isregexp')
|
|
12
|
+
const isFunction = require('lodash.isfunction')
|
|
13
|
+
const isEmpty = require('lodash.isempty')
|
|
14
|
+
const trim = require('lodash.trim')
|
|
15
|
+
const camelCase = require('lodash.camelcase')
|
|
16
|
+
const kebabCase = require('lodash.kebabcase')
|
|
17
|
+
const capitalize = require('lodash.capitalize')
|
|
18
|
+
const split = require('lodash.split')
|
|
19
|
+
const map = require('lodash.map')
|
|
20
|
+
const mapValues = require('lodash.mapvalues')
|
|
21
|
+
const assign = require('lodash.assign')
|
|
22
|
+
const set = require('lodash.set')
|
|
23
|
+
const cloneDeep = require('lodash.clonedeep')
|
|
7
24
|
const findUp = require('find-up')
|
|
8
|
-
const
|
|
25
|
+
const replaceAll = require('replaceall')
|
|
9
26
|
const traverse = require('traverse')
|
|
10
27
|
const dotProp = require('dot-prop')
|
|
11
28
|
/* Default Value resolvers */
|
|
@@ -78,7 +95,7 @@ class Configorama {
|
|
|
78
95
|
}, options)
|
|
79
96
|
|
|
80
97
|
|
|
81
|
-
const defaultSyntax = '\\${((?!AWS)[ ~:a-zA-Z0-9=+!@#%*<>?._\'",|\\-\\/\\(\\)\\\\]+?)}'
|
|
98
|
+
const defaultSyntax = '\\${((?!AWS|stageVariables)[ ~:a-zA-Z0-9=+!@#%*<>?._\'",|\\-\\/\\(\\)\\\\]+?)}'
|
|
82
99
|
const variableSyntax = options.syntax || defaultSyntax
|
|
83
100
|
let varRegex
|
|
84
101
|
if (typeof variableSyntax === 'string') {
|
|
@@ -87,6 +104,7 @@ class Configorama {
|
|
|
87
104
|
} else if (variableSyntax instanceof RegExp) {
|
|
88
105
|
varRegex = variableSyntax
|
|
89
106
|
}
|
|
107
|
+
// console.log('varRegex', varRegex)
|
|
90
108
|
this.variableSyntax = varRegex
|
|
91
109
|
|
|
92
110
|
// Set initial config object to populate
|
|
@@ -94,7 +112,7 @@ class Configorama {
|
|
|
94
112
|
// set config objects
|
|
95
113
|
this.config = fileOrObject
|
|
96
114
|
// Keep a copy
|
|
97
|
-
this.originalConfig =
|
|
115
|
+
this.originalConfig = cloneDeep(fileOrObject)
|
|
98
116
|
// Set configPath for file references
|
|
99
117
|
this.configPath = options.configDir || process.cwd()
|
|
100
118
|
} else if (typeof fileOrObject === 'string') {
|
|
@@ -147,7 +165,7 @@ class Configorama {
|
|
|
147
165
|
// set config objects
|
|
148
166
|
this.config = configObject
|
|
149
167
|
// Keep a copy
|
|
150
|
-
this.originalConfig =
|
|
168
|
+
this.originalConfig = cloneDeep(configObject)
|
|
151
169
|
// Set configPath for file references
|
|
152
170
|
this.configPath = fileDirectory
|
|
153
171
|
}
|
|
@@ -283,13 +301,13 @@ class Configorama {
|
|
|
283
301
|
}
|
|
284
302
|
},
|
|
285
303
|
toCamelCase: (val) => {
|
|
286
|
-
return
|
|
304
|
+
return camelCase(val)
|
|
287
305
|
},
|
|
288
306
|
toKebabCase: (val) => {
|
|
289
|
-
return
|
|
307
|
+
return kebabCase(val)
|
|
290
308
|
},
|
|
291
309
|
capitalize: (val) => {
|
|
292
|
-
return
|
|
310
|
+
return capitalize(val)
|
|
293
311
|
}
|
|
294
312
|
}
|
|
295
313
|
|
|
@@ -301,14 +319,14 @@ class Configorama {
|
|
|
301
319
|
this.functions = {
|
|
302
320
|
split: (value, delimiter, limit) => {
|
|
303
321
|
const delimit = delimiter || ','
|
|
304
|
-
const splitVal =
|
|
322
|
+
const splitVal = split(value, delimit)
|
|
305
323
|
return splitVal
|
|
306
324
|
},
|
|
307
325
|
join: (value, delimiter) => {
|
|
308
|
-
if (
|
|
326
|
+
if (isString(value)) {
|
|
309
327
|
value = [value]
|
|
310
328
|
}
|
|
311
|
-
if (!
|
|
329
|
+
if (!isArray(value)) {
|
|
312
330
|
throw new Error('value must be array for join() function')
|
|
313
331
|
}
|
|
314
332
|
const delimit = delimiter || ','
|
|
@@ -334,10 +352,10 @@ class Configorama {
|
|
|
334
352
|
if (typeof value === 'string' && typeof otherValue === 'string') {
|
|
335
353
|
return value + otherValue
|
|
336
354
|
}
|
|
337
|
-
if (
|
|
355
|
+
if (isArray(value) && isArray(otherValue)) {
|
|
338
356
|
return otherValue.concat(value)
|
|
339
357
|
}
|
|
340
|
-
return
|
|
358
|
+
return assign({}, value, otherValue)
|
|
341
359
|
},
|
|
342
360
|
math: () => {},
|
|
343
361
|
upperKeys: (o) => {
|
|
@@ -365,7 +383,7 @@ class Configorama {
|
|
|
365
383
|
}
|
|
366
384
|
|
|
367
385
|
/**
|
|
368
|
-
* Populate all variables in the service,
|
|
386
|
+
* Populate all variables in the service, conveniently remove and restore the service attributes
|
|
369
387
|
* that confuse the population methods.
|
|
370
388
|
* @param cliOpts An options hive to use for ${opt:...} variables.
|
|
371
389
|
* @returns {Promise.<TResult>|*} A promise resolving to the populated service.
|
|
@@ -462,7 +480,7 @@ class Configorama {
|
|
|
462
480
|
} else {
|
|
463
481
|
// TODO fix how commas + spaces are ned
|
|
464
482
|
const splitter = splitCsv(rawArgs, ', ')
|
|
465
|
-
// console.log('
|
|
483
|
+
// console.log('splitter', splitter)
|
|
466
484
|
argsToPass = formatFunctionArgs(splitter)
|
|
467
485
|
}
|
|
468
486
|
// console.log('argsToPass runFunction', argsToPass)
|
|
@@ -475,7 +493,7 @@ class Configorama {
|
|
|
475
493
|
}
|
|
476
494
|
|
|
477
495
|
const funcValue = theFunction(...argsToPass)
|
|
478
|
-
// console.log('
|
|
496
|
+
// console.log('funcValue', funcValue)
|
|
479
497
|
// console.log('typeof funcValue', typeof funcValue)
|
|
480
498
|
let replaceVal = funcValue
|
|
481
499
|
if (typeof funcValue === 'string') {
|
|
@@ -525,23 +543,23 @@ class Configorama {
|
|
|
525
543
|
* @returns {TerminalProperty[]} The terminal properties of the given root object, with the path
|
|
526
544
|
* and value of each
|
|
527
545
|
*/
|
|
528
|
-
getProperties(root, atRoot, current,
|
|
529
|
-
let context =
|
|
546
|
+
getProperties(root, atRoot, current, _context, _results) {
|
|
547
|
+
let context = _context
|
|
530
548
|
if (!context) {
|
|
531
549
|
context = []
|
|
532
550
|
}
|
|
533
|
-
let results =
|
|
551
|
+
let results = _results
|
|
534
552
|
if (!results) {
|
|
535
553
|
results = []
|
|
536
554
|
}
|
|
537
555
|
const addContext = (value, key) => {
|
|
538
556
|
return this.getProperties(root, false, value, context.concat(key), results)
|
|
539
557
|
}
|
|
540
|
-
if (
|
|
541
|
-
|
|
542
|
-
} else if (
|
|
558
|
+
if (isArray(current)) {
|
|
559
|
+
map(current, addContext)
|
|
560
|
+
} else if (isObject(current) && !isDate(current) && !isRegExp(current) && !isFunction(current)) {
|
|
543
561
|
if (atRoot || current !== root) {
|
|
544
|
-
|
|
562
|
+
mapValues(current, addContext)
|
|
545
563
|
}
|
|
546
564
|
} else {
|
|
547
565
|
// TODO Add values to leaves here
|
|
@@ -559,7 +577,7 @@ class Configorama {
|
|
|
559
577
|
originalValue = dotProp.get(this.originalConfig, parentPath)
|
|
560
578
|
}
|
|
561
579
|
leaf.originalSource = originalValue
|
|
562
|
-
if (originalValue &&
|
|
580
|
+
if (originalValue && isString(originalValue)) {
|
|
563
581
|
const varString = cleanVariable(originalValue, this.variableSyntax)
|
|
564
582
|
if (varString.match(fileRefSyntax)) {
|
|
565
583
|
leaf.isFileRef = true
|
|
@@ -585,13 +603,13 @@ class Configorama {
|
|
|
585
603
|
// console.log('properties', properties)
|
|
586
604
|
const variables = properties.filter((property) => {
|
|
587
605
|
// Initial check if value has variable string in it
|
|
588
|
-
return
|
|
606
|
+
return isString(property.value) && property.value.match(this.variableSyntax)
|
|
589
607
|
})
|
|
590
|
-
return
|
|
608
|
+
return map(variables, (valueObject) => {
|
|
591
609
|
// console.log('valueObject', valueObject)
|
|
592
610
|
return this.populateValue(valueObject, false)
|
|
593
611
|
.then((populated) => {
|
|
594
|
-
return
|
|
612
|
+
return assign({}, valueObject, { populated: populated.value })
|
|
595
613
|
})
|
|
596
614
|
})
|
|
597
615
|
}
|
|
@@ -606,7 +624,7 @@ class Configorama {
|
|
|
606
624
|
return Promise.all(populations)
|
|
607
625
|
.then((results) => results.forEach((result) => {
|
|
608
626
|
if (result.value !== result.populated) {
|
|
609
|
-
|
|
627
|
+
set(target, result.path, result.populated)
|
|
610
628
|
}
|
|
611
629
|
}))
|
|
612
630
|
}
|
|
@@ -664,7 +682,7 @@ class Configorama {
|
|
|
664
682
|
if (!matches || !matches.length) {
|
|
665
683
|
return property
|
|
666
684
|
}
|
|
667
|
-
return
|
|
685
|
+
return map(matches, match => {
|
|
668
686
|
// console.log('match', match)
|
|
669
687
|
return ({
|
|
670
688
|
match: match,
|
|
@@ -680,7 +698,7 @@ class Configorama {
|
|
|
680
698
|
*/
|
|
681
699
|
populateMatches(matches, valueObject, root) {
|
|
682
700
|
// console.log('matches', matches)
|
|
683
|
-
return
|
|
701
|
+
return map(matches, (match) => {
|
|
684
702
|
return this.splitAndGet(match.variable, valueObject, root)
|
|
685
703
|
})
|
|
686
704
|
}
|
|
@@ -699,7 +717,7 @@ class Configorama {
|
|
|
699
717
|
let result = valueObject.value
|
|
700
718
|
for (let i = 0; i < matches.length; i += 1) {
|
|
701
719
|
this.warnIfNotFound(matches[i].variable, results[i])
|
|
702
|
-
// console.log('
|
|
720
|
+
// console.log('Render MATCHES', results[i])
|
|
703
721
|
let valueToPop = results[i]
|
|
704
722
|
// TODO refactor this. __internal_only_flag needed to stop clash with sync/async file resolution
|
|
705
723
|
if (results[i] && typeof results[i] === 'object' && results[i].__internal_only_flag) {
|
|
@@ -719,7 +737,7 @@ class Configorama {
|
|
|
719
737
|
/**
|
|
720
738
|
* Populate the given value, recursively if root is true
|
|
721
739
|
* @param valueObject The value to populate variables within
|
|
722
|
-
* @param root Whether the caller is the root
|
|
740
|
+
* @param root Whether the caller is the root populater and thereby whether to recursively
|
|
723
741
|
* populate
|
|
724
742
|
* @returns {PromiseLike<T>} A promise that resolves to the populated value, recursively if root
|
|
725
743
|
* is true
|
|
@@ -735,7 +753,7 @@ class Configorama {
|
|
|
735
753
|
/*
|
|
736
754
|
console.log('matchesmatches', matches)
|
|
737
755
|
/** */
|
|
738
|
-
if (!
|
|
756
|
+
if (!isArray(matches)) {
|
|
739
757
|
return Promise.resolve(property)
|
|
740
758
|
}
|
|
741
759
|
const populations = this.populateMatches(matches, valueObject, root)
|
|
@@ -746,7 +764,7 @@ class Configorama {
|
|
|
746
764
|
console.log('renderMatches result', result)
|
|
747
765
|
/** */
|
|
748
766
|
|
|
749
|
-
if (root && matches
|
|
767
|
+
if (root && isArray(matches)) {
|
|
750
768
|
return this.populateValue({ value: result.value }, root)
|
|
751
769
|
}
|
|
752
770
|
return result
|
|
@@ -766,7 +784,7 @@ class Configorama {
|
|
|
766
784
|
/**
|
|
767
785
|
* Split the cleaned variable string containing one or more comma delimited variables and get a
|
|
768
786
|
* final value for the entirety of the string
|
|
769
|
-
* @param
|
|
787
|
+
* @param variable The variable string to split and get a final value for
|
|
770
788
|
* @param property The original property string the given variable was extracted from
|
|
771
789
|
* @returns {Promise} A promise resolving to the final value of the given variable
|
|
772
790
|
*/
|
|
@@ -826,7 +844,7 @@ class Configorama {
|
|
|
826
844
|
property = valueToPopulate
|
|
827
845
|
/* Handle ${self:custom.ref, ''} with deep values */
|
|
828
846
|
if (v.match(deepRefSyntax) && originalSrc.match(this.variableSyntax) && !v.match(/deep\:(\d*)\..*}$/)) {
|
|
829
|
-
// console.log('
|
|
847
|
+
// console.log('deep var', this.deep)
|
|
830
848
|
// console.log('originalSrc', originalSrc)
|
|
831
849
|
// console.log('value', v)
|
|
832
850
|
let deepIndex = Number(v.match(/deep\:(\d*)/)[1])
|
|
@@ -839,7 +857,7 @@ class Configorama {
|
|
|
839
857
|
property = this.deep[deepIndex]
|
|
840
858
|
}
|
|
841
859
|
// partial replacement, string
|
|
842
|
-
} else if (
|
|
860
|
+
} else if (isString(valueToPopulate)) {
|
|
843
861
|
// if (property.match(/^> function /g)) {
|
|
844
862
|
//
|
|
845
863
|
// const innerFunc = /> function (\w+)\s*\(((?:[^()]+)*)?\s*\)\s*/
|
|
@@ -872,7 +890,7 @@ class Configorama {
|
|
|
872
890
|
/** */
|
|
873
891
|
|
|
874
892
|
// (replaceThis, withThis, inThis)
|
|
875
|
-
property =
|
|
893
|
+
property = replaceAll(currentMatchedString, valueToPopulate, property)
|
|
876
894
|
// console.log('property', property)
|
|
877
895
|
|
|
878
896
|
// if (property.match(/^> function /g)) {
|
|
@@ -880,17 +898,17 @@ class Configorama {
|
|
|
880
898
|
// }
|
|
881
899
|
|
|
882
900
|
// partial replacement, number
|
|
883
|
-
} else if (
|
|
884
|
-
property =
|
|
901
|
+
} else if (isNumber(valueToPopulate)) {
|
|
902
|
+
property = replaceAll(matchedString, String(valueToPopulate), property)
|
|
885
903
|
// TODO This was temp fix for array value mismatch from filters. This fixes filterInner: ${commas | split(${self:inner}, 2) }
|
|
886
|
-
// } else if (
|
|
887
|
-
// property =
|
|
888
|
-
} else if (
|
|
904
|
+
// } else if (isArray(valueToPopulate) && valueToPopulate.length === 1) {
|
|
905
|
+
// property = replaceAll(matchedString, String(valueToPopulate[0]), property)
|
|
906
|
+
} else if (isObject(valueToPopulate)) {
|
|
889
907
|
// console.log('OBJECT MATCH', valueToPopulate)
|
|
890
|
-
property =
|
|
908
|
+
property = replaceAll(matchedString, JSON.stringify(valueToPopulate), property)// .replace(/}$/, '').replace(/^\$\{/, '')
|
|
891
909
|
// console.log('property', property)
|
|
892
910
|
// TODO run functions here
|
|
893
|
-
// console.log('
|
|
911
|
+
// console.log('other new prop', property)
|
|
894
912
|
} else {
|
|
895
913
|
let missingValue = matchedString
|
|
896
914
|
|
|
@@ -938,7 +956,7 @@ ${valueObject.path}: ${valueObject.originalSource}
|
|
|
938
956
|
const prop = cleanVariable(property, this.variableSyntax)
|
|
939
957
|
// console.log('prop', prop)
|
|
940
958
|
if (property.match(/^> function /g) && prop) {
|
|
941
|
-
// console.log('
|
|
959
|
+
// console.log('func prop', property)
|
|
942
960
|
// console.log('Prop', prop)
|
|
943
961
|
}
|
|
944
962
|
const func = funcRegex.exec(property)
|
|
@@ -1028,8 +1046,8 @@ ${valueObject.path}: ${valueObject.originalSource}
|
|
|
1028
1046
|
let deepPropertyStr = propertyString
|
|
1029
1047
|
let deepProperties = 0
|
|
1030
1048
|
values.forEach((value, index) => {
|
|
1031
|
-
// console.log('
|
|
1032
|
-
if (
|
|
1049
|
+
// console.log('───────────────────────────────> value', value)
|
|
1050
|
+
if (isString(value) && value.match(this.variableSyntax)) {
|
|
1033
1051
|
deepProperties += 1
|
|
1034
1052
|
// console.log('makeDeepVariable overwrite', value)
|
|
1035
1053
|
const deepVariable = this.makeDeepVariable(value)
|
|
@@ -1082,7 +1100,7 @@ ${valueObject.path}: ${valueObject.originalSource}
|
|
|
1082
1100
|
const filterz = string.split('|').filter((value, index, arr) => {
|
|
1083
1101
|
return index > 0
|
|
1084
1102
|
}).map((f) => {
|
|
1085
|
-
return
|
|
1103
|
+
return trim(f)
|
|
1086
1104
|
})
|
|
1087
1105
|
// console.log('filters to run', filterz)
|
|
1088
1106
|
|
|
@@ -1093,7 +1111,7 @@ ${valueObject.path}: ${valueObject.originalSource}
|
|
|
1093
1111
|
}
|
|
1094
1112
|
// console.log('HAS FILTERS', filters)
|
|
1095
1113
|
// console.log('t', t)
|
|
1096
|
-
variableString =
|
|
1114
|
+
variableString = trim(t[0])
|
|
1097
1115
|
}
|
|
1098
1116
|
|
|
1099
1117
|
let resolverFunction
|
|
@@ -1127,7 +1145,7 @@ ${valueObject.path}: ${valueObject.originalSource}
|
|
|
1127
1145
|
// console.log('VALUE', val)
|
|
1128
1146
|
if (val === null || typeof val === 'undefined' ||
|
|
1129
1147
|
/* match deep refs as empty {}, they need resolving via functions */
|
|
1130
|
-
(typeof val === 'object' &&
|
|
1148
|
+
(typeof val === 'object' && isEmpty(val) && variableString.match(/deep\:/))
|
|
1131
1149
|
) {
|
|
1132
1150
|
// console.log('variableString', variableString)
|
|
1133
1151
|
const cleanV = cleanVariable(propertyString, this.variableSyntax)
|
|
@@ -1189,7 +1207,7 @@ Like so: \${${variableString}, "fallbackValue"\}.`)
|
|
|
1189
1207
|
if (i === 0) {
|
|
1190
1208
|
return acc
|
|
1191
1209
|
}
|
|
1192
|
-
acc += `| ${
|
|
1210
|
+
acc += `| ${trim(currentFilter)}`
|
|
1193
1211
|
return acc
|
|
1194
1212
|
}, '')
|
|
1195
1213
|
|
|
@@ -1269,7 +1287,7 @@ Like so: \${${variableString}, "fallbackValue"\}.`)
|
|
|
1269
1287
|
}, 'cleanClean.match(fileRefSyntax)')
|
|
1270
1288
|
}
|
|
1271
1289
|
}
|
|
1272
|
-
// const fallbackValue = split[1]
|
|
1290
|
+
// const fallbackValue = split[1]
|
|
1273
1291
|
// console.log('variableString', variableString)
|
|
1274
1292
|
// console.log('propertyString', propertyString)
|
|
1275
1293
|
// console.log('fallbackValue', fallbackValue)
|
|
@@ -1378,7 +1396,7 @@ Like so: \${${variableString}, "fallbackValue"\}.`)
|
|
|
1378
1396
|
if (hasParams) {
|
|
1379
1397
|
const splitter = splitCsv(hasParams[2])
|
|
1380
1398
|
const argsFound = splitter.map((arg) => {
|
|
1381
|
-
const cleanArg =
|
|
1399
|
+
const cleanArg = trim(arg).replace(/^'|"/, '').replace(/'|"$/, '')
|
|
1382
1400
|
return cleanArg
|
|
1383
1401
|
})
|
|
1384
1402
|
|
|
@@ -1471,7 +1489,7 @@ Check if your javascript is exporting a function that returns a value.`
|
|
|
1471
1489
|
deepProperties.splice(0, 1)
|
|
1472
1490
|
// Trim prop keys for starting/trailing spaces
|
|
1473
1491
|
deepProperties = deepProperties.map((prop) => {
|
|
1474
|
-
return
|
|
1492
|
+
return trim(prop)
|
|
1475
1493
|
})
|
|
1476
1494
|
return this.getDeeperValue(deepProperties, valueToPopulateResolved)
|
|
1477
1495
|
.then((deepValueToPopulateResolved) => {
|
|
@@ -1547,14 +1565,14 @@ Please use ":" to reference sub properties`
|
|
|
1547
1565
|
/*
|
|
1548
1566
|
console.log("GET getValueFromDeep", variableString)
|
|
1549
1567
|
console.log('deepRef', deepRef)
|
|
1550
|
-
console.log('
|
|
1568
|
+
console.log('getValueFromDeep variable', variable)
|
|
1551
1569
|
/** */
|
|
1552
1570
|
let ret = this.populateValue({ value: variable })
|
|
1553
1571
|
// console.log('variable ret', ret)
|
|
1554
1572
|
if (deepRef.length) { // if there is a deep reference remaining
|
|
1555
1573
|
ret = ret.then((result) => {
|
|
1556
1574
|
// console.log('DEEP RESULT', result)
|
|
1557
|
-
if (
|
|
1575
|
+
if (isString(result.value) && result.value.match(this.variableSyntax)) {
|
|
1558
1576
|
// console.log('makeDeepVariable getValueFromDeep', result.value)
|
|
1559
1577
|
const deepVariable = this.makeDeepVariable(result.value)
|
|
1560
1578
|
return Promise.resolve(appendDeepVariable(deepVariable, deepRef))
|
|
@@ -1608,7 +1626,7 @@ Please use ":" to reference sub properties`
|
|
|
1608
1626
|
// console.log(typeof reducedValue)
|
|
1609
1627
|
// console.log('subProperty', `"${subProperty}"`)
|
|
1610
1628
|
|
|
1611
|
-
if (
|
|
1629
|
+
if (isString(reducedValue) && reducedValue.match(deepRefSyntax)) { // build mode
|
|
1612
1630
|
reducedValue = appendDeepVariable(reducedValue, subProperty)
|
|
1613
1631
|
} else { // get mode
|
|
1614
1632
|
if (typeof reducedValue === 'undefined') {
|
|
@@ -1629,7 +1647,7 @@ Please use ":" to reference sub properties`
|
|
|
1629
1647
|
} catch (e) {}
|
|
1630
1648
|
|
|
1631
1649
|
reducedValue = reducedValue[subProperty]
|
|
1632
|
-
} else if (
|
|
1650
|
+
} else if (isString(reducedValue)) {
|
|
1633
1651
|
try {
|
|
1634
1652
|
// if JSON parse it
|
|
1635
1653
|
reducedValue = JSON.parse(reducedValue)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const
|
|
1
|
+
const isNumber = require('lodash.isnumber')
|
|
2
2
|
|
|
3
3
|
function isNumberVariable(variableString) {
|
|
4
4
|
const num = Number(variableString)
|
|
5
|
-
return !isNaN(num) &&
|
|
5
|
+
return !isNaN(num) && isNumber(num)
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
function getValueFromNumber(variableString) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const trim = require('lodash.trim')
|
|
2
2
|
|
|
3
3
|
// Track promise resolution
|
|
4
4
|
class PromiseTracker {
|
|
@@ -18,7 +18,7 @@ class PromiseTracker {
|
|
|
18
18
|
report() {
|
|
19
19
|
const delta = Date.now() - this.startTime
|
|
20
20
|
const pending = this.getPending()
|
|
21
|
-
const dots =
|
|
21
|
+
const dots = dotDotDot(this.cursor++, 100, '...')
|
|
22
22
|
console.log([
|
|
23
23
|
`Fetching Async values${dots}`,
|
|
24
24
|
].concat(
|
|
@@ -41,8 +41,7 @@ class PromiseTracker {
|
|
|
41
41
|
clearInterval(this.interval)
|
|
42
42
|
this.reset()
|
|
43
43
|
}
|
|
44
|
-
add(variable,
|
|
45
|
-
const promise = prms
|
|
44
|
+
add(variable, promise, specifier, hasFilter) {
|
|
46
45
|
// Refactor promise tracker to account for multiple instances of a given variable
|
|
47
46
|
|
|
48
47
|
// console.log(`${specifier} hasFilter`, hasFilter)
|
|
@@ -51,7 +50,7 @@ class PromiseTracker {
|
|
|
51
50
|
let uniqueId = ''
|
|
52
51
|
if (hasFilter) {
|
|
53
52
|
uniqueId = hasFilter.reduce((acc, currentFilter, i) => {
|
|
54
|
-
acc += `|${
|
|
53
|
+
acc += `|${trim(currentFilter)}`
|
|
55
54
|
return acc
|
|
56
55
|
}, '')
|
|
57
56
|
}
|
|
@@ -89,7 +88,7 @@ class PromiseTracker {
|
|
|
89
88
|
}
|
|
90
89
|
}
|
|
91
90
|
|
|
92
|
-
function
|
|
91
|
+
function dotDotDot(cursor, times, string) {
|
|
93
92
|
return Array(times - Math.abs(cursor % (times * 2) - times) + 1).join(string)
|
|
94
93
|
}
|
|
95
94
|
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
const YAML = require('js-yaml');
|
|
2
|
-
const
|
|
2
|
+
const includes = require('lodash.includes');
|
|
3
|
+
const isString = require('lodash.isstring');
|
|
4
|
+
const split = require('lodash.split');
|
|
5
|
+
const flatten = require('lodash.flatten');
|
|
6
|
+
const map = require('lodash.map');
|
|
3
7
|
|
|
4
8
|
const functionNames = [
|
|
5
9
|
'And',
|
|
@@ -22,13 +26,13 @@ const functionNames = [
|
|
|
22
26
|
];
|
|
23
27
|
|
|
24
28
|
const yamlType = (name, kind) => {
|
|
25
|
-
const functionName =
|
|
29
|
+
const functionName = includes(['Ref', 'Condition'], name) ? name : `Fn::${name}`;
|
|
26
30
|
return new YAML.Type(`!${name}`, {
|
|
27
31
|
kind,
|
|
28
32
|
construct: data => {
|
|
29
33
|
if (name === 'GetAtt') {
|
|
30
34
|
// special GetAtt dot syntax
|
|
31
|
-
return { [functionName]:
|
|
35
|
+
return { [functionName]: isString(data) ? split(data, '.', 2) : data };
|
|
32
36
|
}
|
|
33
37
|
return { [functionName]: data };
|
|
34
38
|
},
|
|
@@ -36,9 +40,9 @@ const yamlType = (name, kind) => {
|
|
|
36
40
|
};
|
|
37
41
|
|
|
38
42
|
const createSchema = () => {
|
|
39
|
-
const types =
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
const types = flatten(
|
|
44
|
+
map(functionNames, functionName =>
|
|
45
|
+
map(['mapping', 'scalar', 'sequence'], kind => yamlType(functionName, kind))
|
|
42
46
|
)
|
|
43
47
|
);
|
|
44
48
|
return YAML.Schema.create(types);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
const
|
|
1
|
+
const trim = require('lodash.trim')
|
|
2
2
|
|
|
3
3
|
function formatArg(arg) {
|
|
4
|
-
const cleanArg =
|
|
4
|
+
const cleanArg = trim(arg).replace(/^('|")/, '').replace(/('|")$/, '')
|
|
5
5
|
if (cleanArg.match(/^{([^}]+)}$/)) {
|
|
6
6
|
return JSON.parse(cleanArg)
|
|
7
7
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const readline = require('readline')
|
|
2
2
|
|
|
3
3
|
function handleSignalEvents() {
|
|
4
|
+
if (global.signalEventHandling) return // Only set up handlers once
|
|
4
5
|
// NOTE: instantiating this global variable here to keep track of the state
|
|
5
6
|
// usually global variables should be "considered harmful" but are a good fit in this case
|
|
6
7
|
global.signalEventHandling = {
|
|
@@ -8,7 +9,7 @@ function handleSignalEvents() {
|
|
|
8
9
|
shouldExitGracefully: false
|
|
9
10
|
}
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
const msg = `
|
|
12
13
|
───────────────────────────────────────────────────────────
|
|
13
14
|
Exit received. Waiting for current operation to finish...
|
|
14
15
|
───────────────────────────────────────────────────────────
|
|
@@ -20,23 +21,25 @@ Exit received. Waiting for current operation to finish...
|
|
|
20
21
|
output: process.stdout
|
|
21
22
|
})
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
rl.
|
|
30
|
-
process.emit('SIGBREAK')
|
|
31
|
-
})
|
|
24
|
+
// Clean up readline interface when done
|
|
25
|
+
process.once('exit', () => rl.close())
|
|
26
|
+
|
|
27
|
+
// Use once() instead of on()
|
|
28
|
+
rl.once('SIGINT', () => process.emit('SIGINT'))
|
|
29
|
+
rl.once('SIGTERM', () => process.emit('SIGTERM'))
|
|
30
|
+
rl.once('SIGBREAK', () => process.emit('SIGBREAK'))
|
|
32
31
|
}
|
|
33
32
|
|
|
33
|
+
// Remove any existing listeners before adding new ones
|
|
34
|
+
process.removeAllListeners('SIGINT')
|
|
35
|
+
process.removeAllListeners('SIGTERM')
|
|
36
|
+
process.removeAllListeners('SIGBREAK')
|
|
37
|
+
|
|
34
38
|
process.on('SIGINT', () => {
|
|
35
39
|
global.signalEventHandling.SIGINTCount += 1
|
|
36
40
|
global.signalEventHandling.shouldExitGracefully = true
|
|
37
41
|
if (global.signalEventHandling.SIGINTCount < 2) {
|
|
38
|
-
|
|
39
|
-
console.log(msg) // eslint-disable-line no-console
|
|
42
|
+
console.log(`${msg} Press CTRL + C again to force an exit\nNOTE: Doing so might corrupt the applications state information!`)
|
|
40
43
|
} else {
|
|
41
44
|
process.exit(1)
|
|
42
45
|
}
|
|
@@ -44,12 +47,12 @@ Exit received. Waiting for current operation to finish...
|
|
|
44
47
|
|
|
45
48
|
process.on('SIGTERM', () => {
|
|
46
49
|
global.signalEventHandling.shouldExitGracefully = true
|
|
47
|
-
console.log(msg)
|
|
50
|
+
console.log(msg)
|
|
48
51
|
})
|
|
49
52
|
|
|
50
53
|
process.on('SIGBREAK', () => {
|
|
51
54
|
global.signalEventHandling.shouldExitGracefully = true
|
|
52
|
-
console.log(msg)
|
|
55
|
+
console.log(msg)
|
|
53
56
|
})
|
|
54
57
|
}
|
|
55
58
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const
|
|
1
|
+
const isEmpty = require('lodash.isempty')
|
|
2
2
|
|
|
3
3
|
module.exports = function isValidValue(val) {
|
|
4
4
|
if (typeof val === 'object' && val.hasOwnProperty('__internal_only_flag')) {
|
|
5
5
|
return false
|
|
6
6
|
}
|
|
7
|
-
return val !== null && typeof val !== 'undefined' && !(typeof val === 'object' &&
|
|
7
|
+
return val !== null && typeof val !== 'undefined' && !(typeof val === 'object' && isEmpty(val))
|
|
8
8
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "configorama",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.10",
|
|
4
4
|
"description": "Variable support for configuration files",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"files": [
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
],
|
|
12
12
|
"scripts": {
|
|
13
13
|
"docs": "node ./scripts/docs.js",
|
|
14
|
-
"test": "
|
|
15
|
-
"test:api": "
|
|
16
|
-
"watch": "
|
|
14
|
+
"test": "uvu tests \".*\\.test.js$\"",
|
|
15
|
+
"test:api": "uvu tests/api api.test.js",
|
|
16
|
+
"watch": "watchlist tests -- npm test",
|
|
17
17
|
"publish": "git push origin && git push origin --tags",
|
|
18
18
|
"release:patch": "npm version patch && npm publish",
|
|
19
19
|
"release:minor": "npm version minor && npm publish",
|
|
@@ -33,26 +33,35 @@
|
|
|
33
33
|
"git-url-parse": "^14.0.0",
|
|
34
34
|
"js-yaml": "^3.14.1",
|
|
35
35
|
"json5": "^2.2.3",
|
|
36
|
-
"lodash": "^4.
|
|
36
|
+
"lodash.isarray": "^4.0.0",
|
|
37
|
+
"lodash.isstring": "^4.0.1",
|
|
38
|
+
"lodash.isnumber": "^3.0.3",
|
|
39
|
+
"lodash.isobject": "^3.0.2",
|
|
40
|
+
"lodash.isdate": "^4.0.1",
|
|
41
|
+
"lodash.isregexp": "^4.0.1",
|
|
42
|
+
"lodash.isfunction": "^3.0.9",
|
|
43
|
+
"lodash.isempty": "^4.4.0",
|
|
44
|
+
"lodash.trim": "^4.5.1",
|
|
45
|
+
"lodash.camelcase": "^4.3.0",
|
|
46
|
+
"lodash.kebabcase": "^4.1.1",
|
|
47
|
+
"lodash.capitalize": "^4.2.1",
|
|
48
|
+
"lodash.split": "^4.4.2",
|
|
49
|
+
"lodash.map": "^4.6.0",
|
|
50
|
+
"lodash.mapvalues": "^4.6.0",
|
|
51
|
+
"lodash.assign": "^4.2.0",
|
|
52
|
+
"lodash.set": "^4.3.2",
|
|
53
|
+
"lodash.clonedeep": "^4.5.0",
|
|
54
|
+
"lodash.includes": "^4.3.0",
|
|
55
|
+
"lodash.flatten": "^4.4.0",
|
|
37
56
|
"promise.prototype.finally": "^3.1.8",
|
|
38
57
|
"replaceall": "^0.1.6",
|
|
39
58
|
"sync-rpc": "^1.3.6",
|
|
40
59
|
"traverse": "^0.6.8"
|
|
41
60
|
},
|
|
42
61
|
"devDependencies": {
|
|
43
|
-
"ava": "^2.4.0",
|
|
44
62
|
"markdown-magic": "^2.6.1",
|
|
45
|
-
"minimist": "^1.2.8"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
"files": [
|
|
49
|
-
"tests/**/*.test.js"
|
|
50
|
-
],
|
|
51
|
-
"sources": [
|
|
52
|
-
"**/*.{js,jsx}",
|
|
53
|
-
"*.yml",
|
|
54
|
-
"**/*.yml"
|
|
55
|
-
],
|
|
56
|
-
"verbose": true
|
|
63
|
+
"minimist": "^1.2.8",
|
|
64
|
+
"uvu": "^0.5.6",
|
|
65
|
+
"watchlist": "^0.3.1"
|
|
57
66
|
}
|
|
58
67
|
}
|