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 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.
@@ -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('splitterz', splitter)
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('funcValuex', funcValue)
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, cntxt, rslts) {
529
- let context = cntxt
546
+ getProperties(root, atRoot, current, _context, _results) {
547
+ let context = _context
530
548
  if (!context) {
531
549
  context = []
532
550
  }
533
- let results = rslts
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 (_.isArray(current)) {
541
- _.map(current, addContext)
542
- } 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)) {
543
561
  if (atRoot || current !== root) {
544
- _.mapValues(current, addContext)
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 && _.isString(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 _.isString(property.value) && property.value.match(this.variableSyntax)
606
+ return isString(property.value) && property.value.match(this.variableSyntax)
589
607
  })
590
- return _.map(variables, (valueObject) => {
608
+ return map(variables, (valueObject) => {
591
609
  // console.log('valueObject', valueObject)
592
610
  return this.populateValue(valueObject, false)
593
611
  .then((populated) => {
594
- return _.assign({}, valueObject, { populated: populated.value })
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
- _.set(target, result.path, result.populated)
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 _.map(matches, match => {
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 _.map(matches, (match) => {
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('REDNER MATCHES', results[i])
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 populator and thereby whether to recursively
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 (!_.isArray(matches)) {
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.length) {
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 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
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('MAJAJAAJJAAJAJJAJA', this.deep)
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 (_.isString(valueToPopulate)) {
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 = replaceall(currentMatchedString, valueToPopulate, 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 (_.isNumber(valueToPopulate)) {
884
- property = replaceall(matchedString, String(valueToPopulate), 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 (_.isArray(valueToPopulate) && valueToPopulate.length === 1) {
887
- // property = replaceall(matchedString, String(valueToPopulate[0]), property)
888
- } 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)) {
889
907
  // console.log('OBJECT MATCH', valueToPopulate)
890
- property = replaceall(matchedString, JSON.stringify(valueToPopulate), property)// .replace(/}$/, '').replace(/^\$\{/, '')
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('othere new propetry', property)
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('PRPOpropertyproperty', property)
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('valuevaluevaluevaluevaluevaluevaluevalue', value)
1032
- if (_.isString(value) && value.match(this.variableSyntax)) {
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 _.trim(f)
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 = _.trim(t[0])
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' && _.isEmpty(val) && variableString.match(/deep\:/))
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 += `| ${_.trim(currentFilter)}`
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] || split[0]
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 = _.trim(arg).replace(/^'|"/, '').replace(/'|"$/, '')
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 _.trim(prop)
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('variablex', variable)
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 (_.isString(result.value) && result.value.match(this.variableSyntax)) {
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 (_.isString(reducedValue) && reducedValue.match(deepRefSyntax)) { // build mode
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 (_.isString(reducedValue)) {
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 _ = 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.9",
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
  }