configorama 0.6.9 → 0.6.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.
@@ -245,6 +245,8 @@ Examples:
245
245
  module.exports = {
246
246
  type: 'cron',
247
247
  prefix: 'cron',
248
+ syntax: '${cron(expression)}',
249
+ description: 'Resolves cron expressions. Examples: ${cron("every 5 minutes"}, ${cron("weekdays")}, ${cron("at 9:30")}',
248
250
  match: cronRefSyntax,
249
251
  resolver: getValueFromCron,
250
252
  // Export the parser for testing
@@ -24,6 +24,8 @@ Example: \${env:MY_ENV_VAR}
24
24
 
25
25
  module.exports = {
26
26
  type: 'env',
27
+ syntax: '${env:ENV_VAR}',
28
+ description: 'Resolves environment variables. Examples: ${env:MY_ENV_VAR}, ${env:MY_ENV_VAR_TWO, "fallbackValue"}',
27
29
  match: envRefSyntax,
28
30
  resolver: getValueFromEnv
29
31
  }
@@ -0,0 +1,78 @@
1
+ const { test } = require('uvu')
2
+ const assert = require('uvu/assert')
3
+ const { resolver } = require('./valueFromEnv')
4
+
5
+ test('Resolves existing environment variable', async () => {
6
+ process.env.TEST_ENV_VAR = 'test-value-123'
7
+ const result = await resolver('env:TEST_ENV_VAR')
8
+ assert.is(result, 'test-value-123')
9
+ delete process.env.TEST_ENV_VAR
10
+ })
11
+
12
+ test('Returns undefined for non-existent environment variable', async () => {
13
+ const result = await resolver('env:NON_EXISTENT_VAR_XYZ')
14
+ assert.is(result, undefined)
15
+ })
16
+
17
+ test('Throws error for empty environment variable name', async () => {
18
+ try {
19
+ await resolver('env:')
20
+ assert.unreachable('Should have thrown an error')
21
+ } catch (error) {
22
+ assert.ok(error.message.includes('Invalid variable syntax'))
23
+ assert.ok(error.message.includes('must have a key path'))
24
+ }
25
+ })
26
+
27
+ test('Resolves environment variable with underscore', async () => {
28
+ process.env.MY_TEST_VAR = 'underscore-value'
29
+ const result = await resolver('env:MY_TEST_VAR')
30
+ assert.is(result, 'underscore-value')
31
+ delete process.env.MY_TEST_VAR
32
+ })
33
+
34
+ test('Resolves environment variable with numbers', async () => {
35
+ process.env.VAR123 = 'numeric-value'
36
+ const result = await resolver('env:VAR123')
37
+ assert.is(result, 'numeric-value')
38
+ delete process.env.VAR123
39
+ })
40
+
41
+ test('Resolves environment variable with mixed case', async () => {
42
+ process.env.MixedCaseVar = 'mixed-case-value'
43
+ const result = await resolver('env:MixedCaseVar')
44
+ assert.is(result, 'mixed-case-value')
45
+ delete process.env.MixedCaseVar
46
+ })
47
+
48
+ test('Returns Promise that resolves to value', async () => {
49
+ process.env.PROMISE_TEST = 'promise-value'
50
+ const promise = resolver('env:PROMISE_TEST')
51
+ assert.ok(promise instanceof Promise)
52
+ const result = await promise
53
+ assert.is(result, 'promise-value')
54
+ delete process.env.PROMISE_TEST
55
+ })
56
+
57
+ test('Handles environment variable with special characters in value', async () => {
58
+ process.env.SPECIAL_VAR = 'value-with-special-chars-!@#$%'
59
+ const result = await resolver('env:SPECIAL_VAR')
60
+ assert.is(result, 'value-with-special-chars-!@#$%')
61
+ delete process.env.SPECIAL_VAR
62
+ })
63
+
64
+ test('Handles empty string environment variable value', async () => {
65
+ process.env.EMPTY_VAR = ''
66
+ const result = await resolver('env:EMPTY_VAR')
67
+ assert.is(result, '')
68
+ delete process.env.EMPTY_VAR
69
+ })
70
+
71
+ test('Handles numeric environment variable value', async () => {
72
+ process.env.NUMERIC_VAR = '12345'
73
+ const result = await resolver('env:NUMERIC_VAR')
74
+ assert.is(result, '12345')
75
+ delete process.env.NUMERIC_VAR
76
+ })
77
+
78
+ test.run()
@@ -32,6 +32,7 @@ async function getValueFromEval(variableString) {
32
32
 
33
33
  module.exports = {
34
34
  type: 'eval',
35
+ description: '${eval(expression)} - Evaluates mathematical expressions',
35
36
  match: evalRefSyntax,
36
37
  resolver: getValueFromEval
37
38
  }
@@ -41,6 +41,19 @@ async function _exec(cmd, options = { timeout: 1000 }) {
41
41
  }
42
42
  */
43
43
 
44
+ const GIT_KEYS = {
45
+ repo: 'repo',
46
+ name: 'name',
47
+ org: 'org',
48
+ dir: 'dir',
49
+ url: 'url',
50
+ sha: 'sha',
51
+ commit: 'commit',
52
+ branch: 'branch',
53
+ message: 'message',
54
+ tag: 'tag',
55
+ }
56
+
44
57
  function createResolver(cwd) {
45
58
  async function _getValueFromGit(variableString) {
46
59
  const variable = variableString.split(`${GIT_PREFIX}:`)[1]
@@ -69,7 +82,7 @@ function createResolver(cwd) {
69
82
 
70
83
  switch (normalizedVar) {
71
84
  // Repo owner/name
72
- case 'repo':
85
+ case GIT_KEYS.repo:
73
86
  case 'repository':
74
87
  case 'reposlug':
75
88
  case 'repo-slug':
@@ -78,13 +91,13 @@ function createResolver(cwd) {
78
91
  value = parseda.full_name
79
92
  break;
80
93
  // Repo name
81
- case 'name':
94
+ case GIT_KEYS.name:
82
95
  case 'reponame': // repoName
83
96
  case 'repo-name':
84
97
  value = await _exec('basename `git rev-parse --show-toplevel`')
85
98
  break;
86
99
  // Repo org or owner
87
- case 'org':
100
+ case GIT_KEYS.org:
88
101
  case 'owner':
89
102
  case 'organization':
90
103
  case 'repoowner': // repoOwner
@@ -94,7 +107,7 @@ function createResolver(cwd) {
94
107
  value = parsed.organization || parsed.owner
95
108
  break;
96
109
  // Repo name
97
- case 'dir':
110
+ case GIT_KEYS.dir:
98
111
  case 'directory':
99
112
  case 'dirpath': // dirPath
100
113
  case 'dir-path':
@@ -108,7 +121,7 @@ function createResolver(cwd) {
108
121
  }
109
122
  break;
110
123
  // Repo url
111
- case 'url':
124
+ case GIT_KEYS.url:
112
125
  case 'repourl': // repoUrl
113
126
  case 'repo-url':
114
127
  value = await getGitRemote()
@@ -123,7 +136,7 @@ function createResolver(cwd) {
123
136
  }
124
137
  break
125
138
  // Current commit full sha
126
- case 'commit':
139
+ case GIT_KEYS.commit:
127
140
  case 'commitsha':
128
141
  case 'commit-sha':
129
142
  case 'commithash':
@@ -135,7 +148,7 @@ function createResolver(cwd) {
135
148
  }
136
149
  break
137
150
  // Branches
138
- case 'branch':
151
+ case GIT_KEYS.branch:
139
152
  case 'branchname':
140
153
  case 'branch-name':
141
154
  case 'currentbranch': // currentBranch
@@ -147,8 +160,8 @@ function createResolver(cwd) {
147
160
  }
148
161
  break
149
162
  // Commit msg
163
+ case GIT_KEYS.message:
150
164
  case 'msg':
151
- case 'message':
152
165
  case 'commitmessage': // commitMessage
153
166
  case 'commit-message':
154
167
  case 'commitmsg': // commitMsg
@@ -160,7 +173,7 @@ function createResolver(cwd) {
160
173
  }
161
174
  break;
162
175
  // Git tags
163
- case 'tag':
176
+ case GIT_KEYS.tag:
164
177
  case 'describe':
165
178
  try {
166
179
  value = await _exec('git describe --always')
@@ -318,6 +331,8 @@ module.exports = function createGitResolver(cwd) {
318
331
  return {
319
332
  type: 'git',
320
333
  prefix: 'git',
334
+ syntax: '${git:valueType}',
335
+ description: `Resolves Git variables. Available valueTypes: ${Object.values(GIT_KEYS).join(', ')}`,
321
336
  match: gitVariableSyntax,
322
337
  resolver: createResolver(cwd)
323
338
  }
@@ -11,6 +11,7 @@ function getValueFromNumber(variableString) {
11
11
 
12
12
  module.exports = {
13
13
  type: 'number',
14
+ internal: true,
14
15
  match: isNumberVariable,
15
16
  resolver: getValueFromNumber
16
17
  }
@@ -15,6 +15,8 @@ function getValueFromOptions(variableString, options) {
15
15
  module.exports = {
16
16
  type: 'options',
17
17
  prefix: 'opt',
18
+ syntax: '${opt:flagName}',
19
+ description: 'Resolves CLI option flags. Examples: ${opt:stage}, ${opt:other, "fallbackValue"}',
18
20
  match: optRefSyntax,
19
21
  resolver: getValueFromOptions
20
22
  }
@@ -8,6 +8,7 @@ function getValueFromString(variableString) {
8
8
 
9
9
  module.exports = {
10
10
  type: 'string',
11
+ internal: true,
11
12
  match: stringRefSyntax,
12
13
  resolver: getValueFromString
13
14
  }
package/src/sync.js CHANGED
@@ -5,10 +5,10 @@ const getFullPath = require('./utils/getFullFilePath')
5
5
  const enrichMetadata = require('./utils/enrichMetadata')
6
6
 
7
7
  /**
8
- * Force syncronous invocation of async API
8
+ * Force synchronous invocation of async API
9
9
  */
10
- module.exports = function configoramaSync(varSrcs = []) {
11
- const customVariableSources = varSrcs.map((varSrc) => {
10
+ module.exports = function configoramaSync(variableSources = []) {
11
+ const customVariableSources = variableSources.map((varSrc) => {
12
12
  if (!varSrc.match || typeof varSrc.match !== 'string') {
13
13
  throw new Error('Variable source must be string for .sync usage')
14
14
  }
@@ -33,6 +33,7 @@ module.exports = function configoramaSync(varSrcs = []) {
33
33
  }
34
34
 
35
35
  return {
36
+ type: varSrc.type,
36
37
  /* Create regex in sync context */
37
38
  match: RegExp(varSrc.match, 'g'),
38
39
  resolver: resolverFunction
@@ -53,7 +54,15 @@ module.exports = function configoramaSync(varSrcs = []) {
53
54
  const metadata = instance.collectVariableMetadata()
54
55
 
55
56
  // Enrich metadata with resolution tracking data collected during execution
56
- const enrichedMetadata = enrichMetadata(metadata, instance.resolutionTracking, instance.variableSyntax)
57
+ const enrichedMetadata = enrichMetadata(
58
+ metadata,
59
+ instance.resolutionTracking,
60
+ instance.variableSyntax,
61
+ instance.fileRefsFound,
62
+ instance.originalConfig,
63
+ instance.configFilePath,
64
+ Object.keys(instance.filters)
65
+ )
57
66
 
58
67
  return {
59
68
  config: result,
@@ -1,4 +1,5 @@
1
1
  const { findNestedVariables } = require('./find-nested-variables')
2
+ const { functionRegex } = require('./regex')
2
3
 
3
4
  const DEBUG = false
4
5
  /**
@@ -9,7 +10,6 @@ const DEBUG = false
9
10
  */
10
11
 
11
12
  const fileRefSyntax = RegExp(/^file\((~?[a-zA-Z0-9._\-\/,'" ]+?)\)/g)
12
- const funcRegex = /(\w+)\s*\(((?:[^()]+)*)?\s*\)\s*/
13
13
  module.exports = function cleanVariable(
14
14
  match,
15
15
  variableSyntax,
@@ -42,7 +42,7 @@ module.exports = function cleanVariable(
42
42
  console.log('index', index)
43
43
  console.log('nestedVar', nestedVar)
44
44
  console.log('nestedVar[index]', nestedVar[index])
45
- varToClean = lastMatch.varString.replace(/__VAR_(\d+)__/g, nestedVar[index].fullMatch)
45
+ varToClean = lastMatch.varString.replace(/__VAR_(\d+)__/g, nestedVar[index].varMatch)
46
46
  return varToClean
47
47
  }
48
48
  }
@@ -67,7 +67,7 @@ module.exports = function cleanVariable(
67
67
  }
68
68
 
69
69
  // Support for function matches that dont need space alterations
70
- if (!clean.match(fileRefSyntax) && funcRegex.exec(clean)) {
70
+ if (!clean.match(fileRefSyntax) && functionRegex.exec(clean)) {
71
71
  return clean
72
72
  }
73
73