configorama 0.4.8 → 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 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 _ = require('lodash')
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 replaceall = require('replaceall')
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 = _.cloneDeep(fileOrObject)
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 = _.cloneDeep(configObject)
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 _.camelCase(val)
304
+ return camelCase(val)
287
305
  },
288
306
  toKebabCase: (val) => {
289
- return _.kebabCase(val)
307
+ return kebabCase(val)
290
308
  },
291
309
  capitalize: (val) => {
292
- return _.capitalize(val)
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 = _.split(value, delimit)
322
+ const splitVal = split(value, delimit)
305
323
  return splitVal
306
324
  },
307
325
  join: (value, delimiter) => {
308
- if (_.isString(value)) {
326
+ if (isString(value)) {
309
327
  value = [value]
310
328
  }
311
- if (!Array.isArray(value)) {
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 (Array.isArray(value) && Array.isArray(otherValue)) {
355
+ if (isArray(value) && isArray(otherValue)) {
338
356
  return otherValue.concat(value)
339
357
  }
340
- return Object.assign({}, value, otherValue)
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, conviently remove and restore the service attributes
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.
@@ -438,6 +456,10 @@ class Configorama {
438
456
  })
439
457
  }
440
458
  runFunction(variableString) {
459
+ /* If json object value return it */
460
+ if (variableString.match(/^\s*{/) && variableString.match(/}\s*$/)) {
461
+ return variableString
462
+ }
441
463
  // console.log('runFunction', variableString)
442
464
  var hasFunc = funcRegex.exec(variableString)
443
465
  // TODO finish Function handling. Need to move this down below resolver to resolve inner refs first
@@ -458,7 +480,7 @@ class Configorama {
458
480
  } else {
459
481
  // TODO fix how commas + spaces are ned
460
482
  const splitter = splitCsv(rawArgs, ', ')
461
- // console.log('splitterz', splitter)
483
+ // console.log('splitter', splitter)
462
484
  argsToPass = formatFunctionArgs(splitter)
463
485
  }
464
486
  // console.log('argsToPass runFunction', argsToPass)
@@ -471,7 +493,7 @@ class Configorama {
471
493
  }
472
494
 
473
495
  const funcValue = theFunction(...argsToPass)
474
- // console.log('funcValuex', funcValue)
496
+ // console.log('funcValue', funcValue)
475
497
  // console.log('typeof funcValue', typeof funcValue)
476
498
  let replaceVal = funcValue
477
499
  if (typeof funcValue === 'string') {
@@ -521,23 +543,23 @@ class Configorama {
521
543
  * @returns {TerminalProperty[]} The terminal properties of the given root object, with the path
522
544
  * and value of each
523
545
  */
524
- getProperties(root, atRoot, current, cntxt, rslts) {
525
- let context = cntxt
546
+ getProperties(root, atRoot, current, _context, _results) {
547
+ let context = _context
526
548
  if (!context) {
527
549
  context = []
528
550
  }
529
- let results = rslts
551
+ let results = _results
530
552
  if (!results) {
531
553
  results = []
532
554
  }
533
555
  const addContext = (value, key) => {
534
556
  return this.getProperties(root, false, value, context.concat(key), results)
535
557
  }
536
- if (_.isArray(current)) {
537
- _.map(current, addContext)
538
- } else if (_.isObject(current) && !_.isDate(current) && !_.isRegExp(current) && !_.isFunction(current)) {
558
+ if (isArray(current)) {
559
+ map(current, addContext)
560
+ } else if (isObject(current) && !isDate(current) && !isRegExp(current) && !isFunction(current)) {
539
561
  if (atRoot || current !== root) {
540
- _.mapValues(current, addContext)
562
+ mapValues(current, addContext)
541
563
  }
542
564
  } else {
543
565
  // TODO Add values to leaves here
@@ -555,7 +577,7 @@ class Configorama {
555
577
  originalValue = dotProp.get(this.originalConfig, parentPath)
556
578
  }
557
579
  leaf.originalSource = originalValue
558
- if (originalValue && _.isString(originalValue)) {
580
+ if (originalValue && isString(originalValue)) {
559
581
  const varString = cleanVariable(originalValue, this.variableSyntax)
560
582
  if (varString.match(fileRefSyntax)) {
561
583
  leaf.isFileRef = true
@@ -581,13 +603,13 @@ class Configorama {
581
603
  // console.log('properties', properties)
582
604
  const variables = properties.filter((property) => {
583
605
  // Initial check if value has variable string in it
584
- return _.isString(property.value) && property.value.match(this.variableSyntax)
606
+ return isString(property.value) && property.value.match(this.variableSyntax)
585
607
  })
586
- return _.map(variables, (valueObject) => {
608
+ return map(variables, (valueObject) => {
587
609
  // console.log('valueObject', valueObject)
588
610
  return this.populateValue(valueObject, false)
589
611
  .then((populated) => {
590
- return _.assign({}, valueObject, { populated: populated.value })
612
+ return assign({}, valueObject, { populated: populated.value })
591
613
  })
592
614
  })
593
615
  }
@@ -602,7 +624,7 @@ class Configorama {
602
624
  return Promise.all(populations)
603
625
  .then((results) => results.forEach((result) => {
604
626
  if (result.value !== result.populated) {
605
- _.set(target, result.path, result.populated)
627
+ set(target, result.path, result.populated)
606
628
  }
607
629
  }))
608
630
  }
@@ -660,7 +682,7 @@ class Configorama {
660
682
  if (!matches || !matches.length) {
661
683
  return property
662
684
  }
663
- return _.map(matches, match => {
685
+ return map(matches, match => {
664
686
  // console.log('match', match)
665
687
  return ({
666
688
  match: match,
@@ -676,7 +698,7 @@ class Configorama {
676
698
  */
677
699
  populateMatches(matches, valueObject, root) {
678
700
  // console.log('matches', matches)
679
- return _.map(matches, (match) => {
701
+ return map(matches, (match) => {
680
702
  return this.splitAndGet(match.variable, valueObject, root)
681
703
  })
682
704
  }
@@ -695,7 +717,7 @@ class Configorama {
695
717
  let result = valueObject.value
696
718
  for (let i = 0; i < matches.length; i += 1) {
697
719
  this.warnIfNotFound(matches[i].variable, results[i])
698
- // console.log('REDNER MATCHES', results[i])
720
+ // console.log('Render MATCHES', results[i])
699
721
  let valueToPop = results[i]
700
722
  // TODO refactor this. __internal_only_flag needed to stop clash with sync/async file resolution
701
723
  if (results[i] && typeof results[i] === 'object' && results[i].__internal_only_flag) {
@@ -715,7 +737,7 @@ class Configorama {
715
737
  /**
716
738
  * Populate the given value, recursively if root is true
717
739
  * @param valueObject The value to populate variables within
718
- * @param root Whether the caller is the root populator and thereby whether to recursively
740
+ * @param root Whether the caller is the root populater and thereby whether to recursively
719
741
  * populate
720
742
  * @returns {PromiseLike<T>} A promise that resolves to the populated value, recursively if root
721
743
  * is true
@@ -731,7 +753,7 @@ class Configorama {
731
753
  /*
732
754
  console.log('matchesmatches', matches)
733
755
  /** */
734
- if (!_.isArray(matches)) {
756
+ if (!isArray(matches)) {
735
757
  return Promise.resolve(property)
736
758
  }
737
759
  const populations = this.populateMatches(matches, valueObject, root)
@@ -742,7 +764,7 @@ class Configorama {
742
764
  console.log('renderMatches result', result)
743
765
  /** */
744
766
 
745
- if (root && matches.length) {
767
+ if (root && isArray(matches)) {
746
768
  return this.populateValue({ value: result.value }, root)
747
769
  }
748
770
  return result
@@ -762,7 +784,7 @@ class Configorama {
762
784
  /**
763
785
  * Split the cleaned variable string containing one or more comma delimited variables and get a
764
786
  * final value for the entirety of the string
765
- * @param varible The variable string to split and get a final value for
787
+ * @param variable The variable string to split and get a final value for
766
788
  * @param property The original property string the given variable was extracted from
767
789
  * @returns {Promise} A promise resolving to the final value of the given variable
768
790
  */
@@ -822,7 +844,7 @@ class Configorama {
822
844
  property = valueToPopulate
823
845
  /* Handle ${self:custom.ref, ''} with deep values */
824
846
  if (v.match(deepRefSyntax) && originalSrc.match(this.variableSyntax) && !v.match(/deep\:(\d*)\..*}$/)) {
825
- // console.log('MAJAJAAJJAAJAJJAJA', this.deep)
847
+ // console.log('deep var', this.deep)
826
848
  // console.log('originalSrc', originalSrc)
827
849
  // console.log('value', v)
828
850
  let deepIndex = Number(v.match(/deep\:(\d*)/)[1])
@@ -835,7 +857,7 @@ class Configorama {
835
857
  property = this.deep[deepIndex]
836
858
  }
837
859
  // partial replacement, string
838
- } else if (_.isString(valueToPopulate)) {
860
+ } else if (isString(valueToPopulate)) {
839
861
  // if (property.match(/^> function /g)) {
840
862
  //
841
863
  // const innerFunc = /> function (\w+)\s*\(((?:[^()]+)*)?\s*\)\s*/
@@ -868,7 +890,7 @@ class Configorama {
868
890
  /** */
869
891
 
870
892
  // (replaceThis, withThis, inThis)
871
- property = replaceall(currentMatchedString, valueToPopulate, property)
893
+ property = replaceAll(currentMatchedString, valueToPopulate, property)
872
894
  // console.log('property', property)
873
895
 
874
896
  // if (property.match(/^> function /g)) {
@@ -876,17 +898,17 @@ class Configorama {
876
898
  // }
877
899
 
878
900
  // partial replacement, number
879
- } else if (_.isNumber(valueToPopulate)) {
880
- property = replaceall(matchedString, String(valueToPopulate), property)
901
+ } else if (isNumber(valueToPopulate)) {
902
+ property = replaceAll(matchedString, String(valueToPopulate), property)
881
903
  // TODO This was temp fix for array value mismatch from filters. This fixes filterInner: ${commas | split(${self:inner}, 2) }
882
- // } else if (_.isArray(valueToPopulate) && valueToPopulate.length === 1) {
883
- // property = replaceall(matchedString, String(valueToPopulate[0]), property)
884
- } else if (_.isObject(valueToPopulate)) {
904
+ // } else if (isArray(valueToPopulate) && valueToPopulate.length === 1) {
905
+ // property = replaceAll(matchedString, String(valueToPopulate[0]), property)
906
+ } else if (isObject(valueToPopulate)) {
885
907
  // console.log('OBJECT MATCH', valueToPopulate)
886
- property = replaceall(matchedString, JSON.stringify(valueToPopulate), property)// .replace(/}$/, '').replace(/^\$\{/, '')
908
+ property = replaceAll(matchedString, JSON.stringify(valueToPopulate), property)// .replace(/}$/, '').replace(/^\$\{/, '')
887
909
  // console.log('property', property)
888
910
  // TODO run functions here
889
- // console.log('othere new propetry', property)
911
+ // console.log('other new prop', property)
890
912
  } else {
891
913
  let missingValue = matchedString
892
914
 
@@ -934,7 +956,7 @@ ${valueObject.path}: ${valueObject.originalSource}
934
956
  const prop = cleanVariable(property, this.variableSyntax)
935
957
  // console.log('prop', prop)
936
958
  if (property.match(/^> function /g) && prop) {
937
- // console.log('PRPOpropertyproperty', property)
959
+ // console.log('func prop', property)
938
960
  // console.log('Prop', prop)
939
961
  }
940
962
  const func = funcRegex.exec(property)
@@ -1024,8 +1046,8 @@ ${valueObject.path}: ${valueObject.originalSource}
1024
1046
  let deepPropertyStr = propertyString
1025
1047
  let deepProperties = 0
1026
1048
  values.forEach((value, index) => {
1027
- // console.log('valuevaluevaluevaluevaluevaluevaluevalue', value)
1028
- if (_.isString(value) && value.match(this.variableSyntax)) {
1049
+ // console.log('───────────────────────────────> value', value)
1050
+ if (isString(value) && value.match(this.variableSyntax)) {
1029
1051
  deepProperties += 1
1030
1052
  // console.log('makeDeepVariable overwrite', value)
1031
1053
  const deepVariable = this.makeDeepVariable(value)
@@ -1078,7 +1100,7 @@ ${valueObject.path}: ${valueObject.originalSource}
1078
1100
  const filterz = string.split('|').filter((value, index, arr) => {
1079
1101
  return index > 0
1080
1102
  }).map((f) => {
1081
- return _.trim(f)
1103
+ return trim(f)
1082
1104
  })
1083
1105
  // console.log('filters to run', filterz)
1084
1106
 
@@ -1089,7 +1111,7 @@ ${valueObject.path}: ${valueObject.originalSource}
1089
1111
  }
1090
1112
  // console.log('HAS FILTERS', filters)
1091
1113
  // console.log('t', t)
1092
- variableString = _.trim(t[0])
1114
+ variableString = trim(t[0])
1093
1115
  }
1094
1116
 
1095
1117
  let resolverFunction
@@ -1123,7 +1145,7 @@ ${valueObject.path}: ${valueObject.originalSource}
1123
1145
  // console.log('VALUE', val)
1124
1146
  if (val === null || typeof val === 'undefined' ||
1125
1147
  /* match deep refs as empty {}, they need resolving via functions */
1126
- (typeof val === 'object' && _.isEmpty(val) && variableString.match(/deep\:/))
1148
+ (typeof val === 'object' && isEmpty(val) && variableString.match(/deep\:/))
1127
1149
  ) {
1128
1150
  // console.log('variableString', variableString)
1129
1151
  const cleanV = cleanVariable(propertyString, this.variableSyntax)
@@ -1185,7 +1207,7 @@ Like so: \${${variableString}, "fallbackValue"\}.`)
1185
1207
  if (i === 0) {
1186
1208
  return acc
1187
1209
  }
1188
- acc += `| ${_.trim(currentFilter)}`
1210
+ acc += `| ${trim(currentFilter)}`
1189
1211
  return acc
1190
1212
  }, '')
1191
1213
 
@@ -1265,7 +1287,7 @@ Like so: \${${variableString}, "fallbackValue"\}.`)
1265
1287
  }, 'cleanClean.match(fileRefSyntax)')
1266
1288
  }
1267
1289
  }
1268
- // const fallbackValue = split[1] || split[0]
1290
+ // const fallbackValue = split[1]
1269
1291
  // console.log('variableString', variableString)
1270
1292
  // console.log('propertyString', propertyString)
1271
1293
  // console.log('fallbackValue', fallbackValue)
@@ -1374,7 +1396,7 @@ Like so: \${${variableString}, "fallbackValue"\}.`)
1374
1396
  if (hasParams) {
1375
1397
  const splitter = splitCsv(hasParams[2])
1376
1398
  const argsFound = splitter.map((arg) => {
1377
- const cleanArg = _.trim(arg).replace(/^'|"/, '').replace(/'|"$/, '')
1399
+ const cleanArg = trim(arg).replace(/^'|"/, '').replace(/'|"$/, '')
1378
1400
  return cleanArg
1379
1401
  })
1380
1402
 
@@ -1467,7 +1489,7 @@ Check if your javascript is exporting a function that returns a value.`
1467
1489
  deepProperties.splice(0, 1)
1468
1490
  // Trim prop keys for starting/trailing spaces
1469
1491
  deepProperties = deepProperties.map((prop) => {
1470
- return _.trim(prop)
1492
+ return trim(prop)
1471
1493
  })
1472
1494
  return this.getDeeperValue(deepProperties, valueToPopulateResolved)
1473
1495
  .then((deepValueToPopulateResolved) => {
@@ -1543,14 +1565,14 @@ Please use ":" to reference sub properties`
1543
1565
  /*
1544
1566
  console.log("GET getValueFromDeep", variableString)
1545
1567
  console.log('deepRef', deepRef)
1546
- console.log('variablex', variable)
1568
+ console.log('getValueFromDeep variable', variable)
1547
1569
  /** */
1548
1570
  let ret = this.populateValue({ value: variable })
1549
1571
  // console.log('variable ret', ret)
1550
1572
  if (deepRef.length) { // if there is a deep reference remaining
1551
1573
  ret = ret.then((result) => {
1552
1574
  // console.log('DEEP RESULT', result)
1553
- if (_.isString(result.value) && result.value.match(this.variableSyntax)) {
1575
+ if (isString(result.value) && result.value.match(this.variableSyntax)) {
1554
1576
  // console.log('makeDeepVariable getValueFromDeep', result.value)
1555
1577
  const deepVariable = this.makeDeepVariable(result.value)
1556
1578
  return Promise.resolve(appendDeepVariable(deepVariable, deepRef))
@@ -1604,7 +1626,7 @@ Please use ":" to reference sub properties`
1604
1626
  // console.log(typeof reducedValue)
1605
1627
  // console.log('subProperty', `"${subProperty}"`)
1606
1628
 
1607
- if (_.isString(reducedValue) && reducedValue.match(deepRefSyntax)) { // build mode
1629
+ if (isString(reducedValue) && reducedValue.match(deepRefSyntax)) { // build mode
1608
1630
  reducedValue = appendDeepVariable(reducedValue, subProperty)
1609
1631
  } else { // get mode
1610
1632
  if (typeof reducedValue === 'undefined') {
@@ -1625,7 +1647,7 @@ Please use ":" to reference sub properties`
1625
1647
  } catch (e) {}
1626
1648
 
1627
1649
  reducedValue = reducedValue[subProperty]
1628
- } else if (_.isString(reducedValue)) {
1650
+ } else if (isString(reducedValue)) {
1629
1651
  try {
1630
1652
  // if JSON parse it
1631
1653
  reducedValue = JSON.parse(reducedValue)
@@ -105,6 +105,11 @@ function matchOutermostBraces(text) {
105
105
  return results;
106
106
  }
107
107
 
108
+ // https://regex101.com/r/XIltbc/1
109
+ const KEY_OBJECT = /^[ \t]*[^":\s]*:\s+\{/gm
110
+
111
+ const INNER_ARRAY = /\[(?:[^\[\]])*\]/g
112
+
108
113
  function preProcess(ymlStr = '') {
109
114
  /*
110
115
  return ymlStr
@@ -115,7 +120,7 @@ function preProcess(ymlStr = '') {
115
120
  // out -> y: !Not [!Equals [!Join ['', "${param:xyz}"]]]
116
121
  const arrayBracketMatches = ymlStr && ymlStr.match(
117
122
  // /\[(?:[^\[\]]+|)*\]/gm
118
- /\[(?:[^\[\]])*\]/g
123
+ INNER_ARRAY
119
124
  )
120
125
  if (arrayBracketMatches) {
121
126
  // console.log('arrayBracketMatches', arrayBracketMatches)
@@ -146,7 +151,7 @@ function preProcess(ymlStr = '') {
146
151
  }
147
152
 
148
153
  /* If have yaml object and vars not wrapped in quotes, wrap them */
149
- if (ymlStr.match(/^[ \t]*[^:\n]*:\s*\{/gm)) {
154
+ if (ymlStr.match(KEY_OBJECT)) {
150
155
  const hasObjects = matchOutermostBraces(ymlStr)
151
156
  // console.log('hasObjects', hasObjects)
152
157
  if (hasObjects && hasObjects.length) {
@@ -171,9 +176,7 @@ function preProcess(ymlStr = '') {
171
176
  })
172
177
  }
173
178
  }
174
-
175
179
  // console.log('ymlStr', ymlStr)
176
-
177
180
  return ymlStr
178
181
  }
179
182
 
@@ -1,8 +1,8 @@
1
- const _ = require('lodash')
1
+ const isNumber = require('lodash.isnumber')
2
2
 
3
3
  function isNumberVariable(variableString) {
4
4
  const num = Number(variableString)
5
- return !isNaN(num) && _.isNumber(num)
5
+ return !isNaN(num) && isNumber(num)
6
6
  }
7
7
 
8
8
  function getValueFromNumber(variableString) {
@@ -1,4 +1,4 @@
1
- const _ = require('lodash')
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 = dotdotdot(this.cursor++, 100, '...')
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, prms, specifier, hasFilter) {
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 += `|${_.trim(currentFilter)}`
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 dotdotdot(cursor, times, string) {
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 _ = require('lodash');
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 = _.includes(['Ref', 'Condition'], name) ? name : `Fn::${name}`;
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]: _.isString(data) ? _.split(data, '.', 2) : data };
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 = _.flatten(
40
- _.map(functionNames, functionName =>
41
- _.map(['mapping', 'scalar', 'sequence'], kind => yamlType(functionName, kind))
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 _ = require('lodash')
1
+ const trim = require('lodash.trim')
2
2
 
3
3
  function formatArg(arg) {
4
- const cleanArg = _.trim(arg).replace(/^('|")/, '').replace(/('|")$/, '')
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
- let msg = `
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
- rl.on('SIGINT', () => {
24
- process.emit('SIGINT')
25
- })
26
- rl.on('SIGTERM', () => {
27
- process.emit('SIGTERM')
28
- })
29
- rl.on('SIGBREAK', () => {
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
- msg = `${msg} Press CTRL + C again to force an exit\nNOTE: Doing so might corrupt the applications state information!`
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) // eslint-disable-line no-console
50
+ console.log(msg)
48
51
  })
49
52
 
50
53
  process.on('SIGBREAK', () => {
51
54
  global.signalEventHandling.shouldExitGracefully = true
52
- console.log(msg) // eslint-disable-line no-console
55
+ console.log(msg)
53
56
  })
54
57
  }
55
58
 
@@ -1,8 +1,8 @@
1
- const _ = require('lodash')
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' && _.isEmpty(val))
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.8",
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": "ava -v",
15
- "test:api": "ava ./tests/api/api.test.js -v",
16
- "watch": "npm test -- --watch -v",
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.17.21",
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
- "ava": {
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
  }