configorama 0.6.5 → 0.6.7

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/main.js +50 -12
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "configorama",
3
- "version": "0.6.5",
3
+ "version": "0.6.7",
4
4
  "description": "Variable support for configuration files",
5
5
  "main": "src/index.js",
6
6
  "types": "index.d.ts",
package/src/main.js CHANGED
@@ -76,6 +76,7 @@ const deepIndexReplacePattern = new RegExp(/^deep:|(\.[^}]+)*$/g)
76
76
  const deepIndexPattern = /deep\:(\d*)/
77
77
  const deepPrefixReplacePattern = /(?:^deep:)\d+\.?/g
78
78
  const fileRefSyntax = RegExp(/^file\((~?[@\{\}\:\$a-zA-Z0-9._\-\/,'" ]+?)\)/g)
79
+ const textRefSyntax = RegExp(/^text\((~?[@\{\}\:\$a-zA-Z0-9._\-\/,'" ]+?)\)/g)
79
80
  // TODO update file regex ^file\((~?[a-zA-Z0-9._\-\/, ]+?)\)
80
81
  // To match file(asyncValue.js, lol) input params
81
82
  const envRefSyntax = RegExp(/^env:/g)
@@ -230,6 +231,16 @@ class Configorama {
230
231
  },
231
232
  },
232
233
 
234
+
235
+ {
236
+ type: 'text',
237
+ prefix: 'text',
238
+ match: textRefSyntax,
239
+ resolver: (varString, o, x, pathValue) => {
240
+ return this.getValueFromFile(varString, { asRawText: true })
241
+ },
242
+ },
243
+
233
244
  // Git refs
234
245
  createGitResolver(this.configPath),
235
246
  /* Internal Resolvers */
@@ -818,6 +829,7 @@ class Configorama {
818
829
  throw new Error(errorMessage)
819
830
  }
820
831
  if (typeof rawValue === 'string') {
832
+ // console.log('rawValue', rawValue)
821
833
  /* Process inline functions like merge() */
822
834
  if (ENABLE_FUNCTIONS && rawValue.match(/> function /)) {
823
835
  // console.log('RAW FUNCTION', rawFunction)
@@ -838,6 +850,13 @@ class Configorama {
838
850
  }
839
851
  }
840
852
 
853
+ /* fix for file(JS-ref.js, raw) to keep parens and inline code */
854
+ const OPEN_PAREN_PLACEHOLDER_PATTERN = /__PH_PAREN_OPEN__/g
855
+ if (rawValue.match(OPEN_PAREN_PLACEHOLDER_PATTERN)) {
856
+ rawValue = rawValue.replace(OPEN_PAREN_PLACEHOLDER_PATTERN, '(')
857
+ this.update(rawValue)
858
+ }
859
+
841
860
  /* Allow for unknown variables to pass through */
842
861
  if (rawValue.match(/>passthrough/)) {
843
862
  const newValues = decodeUnknown(rawValue)
@@ -871,6 +890,7 @@ class Configorama {
871
890
  })
872
891
  }
873
892
  runFunction(variableString) {
893
+ // console.log('runFunction', variableString)
874
894
  /* If json object value return it */
875
895
  if (variableString.match(/^\s*{/) && variableString.match(/}\s*$/)) {
876
896
  return variableString
@@ -1480,7 +1500,12 @@ Missing Value ${missingValue} - ${matchedString}
1480
1500
  // @TODO fix this for eval refs
1481
1501
  // console.log('prop', prop)
1482
1502
  // console.log('func', func)
1483
- if (!prop.match(fileRefSyntax) && !prop.match(getValueFromEval.match) && func) {
1503
+
1504
+ if (
1505
+ !prop.match(fileRefSyntax)
1506
+ && !prop.match(getValueFromEval.match)
1507
+ // AND is not multiline value
1508
+ && (func && prop.split('\n').length < 3)) {
1484
1509
  // console.log('IS FUNCTION')
1485
1510
  /* if matches function signature like ${merge('foo', 'bar')}
1486
1511
  rewrite the variable to run the function after inputs resolved
@@ -1984,15 +2009,19 @@ Unable to resolve configuration variable
1984
2009
  return res
1985
2010
  })
1986
2011
  }
1987
- async getValueFromFile(variableString) {
2012
+ async getValueFromFile(variableString, options) {
2013
+ const opts = options || {}
2014
+ const syntax = opts.asRawText ? textRefSyntax : fileRefSyntax
1988
2015
  // console.log('From file', `"${variableString}"`)
1989
- let matchedFileString = variableString.match(fileRefSyntax)[0]
2016
+ let matchedFileString = variableString.match(syntax)[0]
1990
2017
  // console.log('matchedFileString', matchedFileString)
1991
2018
 
1992
- // Get function input params if any supplied
1993
- var funcParamsRegex = /(\w+)\s*\(((?:[^()]+)*)?\s*\)\s*/g
2019
+ // Get function input params if any supplied https://regex101.com/r/qlNFVm/1
2020
+ // var funcParamsRegex = /(\w+)\s*\(((?:[^()]+)*)?\s*\)\s*/g
2021
+ var funcParamsRegex = /(\w+)\s*\(((?:[^()]+)*)?\s*\)/g
2022
+ // tighter (?<![.\w-])\b(\w+)\s*\(((?:[^()]+)*)?\s*\)\s*
1994
2023
  var hasParams = funcParamsRegex.exec(matchedFileString)
1995
- // console.log('args', hasParams)
2024
+
1996
2025
  let argsToPass = []
1997
2026
  if (hasParams) {
1998
2027
  const splitter = splitCsv(hasParams[2])
@@ -2000,6 +2029,7 @@ Unable to resolve configuration variable
2000
2029
  const cleanArg = trim(arg).replace(/^'|"/, '').replace(/'|"$/, '')
2001
2030
  return cleanArg
2002
2031
  })
2032
+ // console.log('argsFound', argsFound)
2003
2033
 
2004
2034
  // If function has more arguments than file path
2005
2035
  if (argsFound.length && argsFound.length > 1) {
@@ -2012,7 +2042,7 @@ Unable to resolve configuration variable
2012
2042
  // console.log('argsToPass', argsToPass)
2013
2043
 
2014
2044
  const relativePath = trimSurroundingQuotes(
2015
- matchedFileString.replace(fileRefSyntax, (match, varName) => varName.trim()).replace('~', os.homedir()),
2045
+ matchedFileString.replace(syntax, (match, varName) => varName.trim()).replace('~', os.homedir()),
2016
2046
  )
2017
2047
 
2018
2048
  // Resolve alias if the path contains alias syntax
@@ -2059,8 +2089,16 @@ ${logLines}
2059
2089
 
2060
2090
  let valueToPopulate
2061
2091
 
2092
+ const variableFileContents = fs.readFileSync(fullFilePath, 'utf-8')
2093
+
2094
+ /* handle case for referencing raw JS files to inline them */
2095
+ if (argsToPass.length && (argsToPass && argsToPass[0] && argsToPass[0].toLowerCase() === 'raw') || opts.asRawText) {
2096
+ valueToPopulate = variableFileContents.replace(/\(/g, '__PH_PAREN_OPEN__')
2097
+ return Promise.resolve(valueToPopulate)
2098
+ }
2099
+
2062
2100
  // Process JS files
2063
- if (fileExtension === 'js') {
2101
+ if (fileExtension === 'js' || fileExtension === 'cjs') {
2064
2102
  const jsFile = require(fullFilePath)
2065
2103
  let returnValueFunction = jsFile
2066
2104
  // TODO change how exported functions are referenced
@@ -2084,8 +2122,7 @@ Check if your javascript is exporting a function that returns a value.`
2084
2122
  config: this.config,
2085
2123
  opts: this.opts,
2086
2124
  }
2087
-
2088
-
2125
+
2089
2126
  valueToPopulate = returnValueFunction.call(jsFile, valueForFunction, ...argsToPass)
2090
2127
 
2091
2128
  return Promise.resolve(valueToPopulate).then((valueToPopulateResolved) => {
@@ -2107,7 +2144,6 @@ Check if your javascript is returning the correct data.`
2107
2144
  })
2108
2145
  }
2109
2146
 
2110
-
2111
2147
  if (fileExtension === 'ts') {
2112
2148
  const { executeTypeScriptFile } = require('./parsers/typescript')
2113
2149
  let returnValueFunction
@@ -2217,7 +2253,7 @@ Check if your ESM is returning the correct data.`
2217
2253
  // Process everything except JS, TS, and ESM
2218
2254
  if (fileExtension !== 'js' && fileExtension !== 'ts' && fileExtension !== 'mjs' && fileExtension !== 'esm') {
2219
2255
  /* Read initial file */
2220
- valueToPopulate = fs.readFileSync(fullFilePath, 'utf-8')
2256
+ valueToPopulate = variableFileContents
2221
2257
 
2222
2258
  // File reference has :subKey lookup. Must dig deeper
2223
2259
  if (matchedFileString !== variableString) {
@@ -2400,6 +2436,8 @@ Please use ":" to reference sub properties`
2400
2436
  varType = 'file'
2401
2437
  } else if (variableString.match(deepRefSyntax)) {
2402
2438
  varType = 'deep'
2439
+ } else if (variableString.match(textRefSyntax)) {
2440
+ varType = 'text'
2403
2441
  }
2404
2442
  if (!isValidValue(valueToPopulate)) {
2405
2443
  // console.log("MISSING", variableString)