configorama 0.7.1 → 0.8.0

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.
@@ -197,7 +197,13 @@ async function getValueFromFile(ctx, variableString, options) {
197
197
  // console.log('NO FILE FOUND', fullFilePath)
198
198
  // console.log('variableString', variableString)
199
199
 
200
- if (!hasFallback && !ctx.opts.allowUnknownFileRefs) {
200
+ // Check if file refs are allowed to pass through unresolved
201
+ const allowUnresolved = ctx.opts.allowUnresolvedVariables
202
+ const isFileAllowed = allowUnresolved === true ||
203
+ (Array.isArray(allowUnresolved) && allowUnresolved.includes('file')) ||
204
+ ctx.opts.allowUnknownFileRefs // backward compat
205
+
206
+ if (!hasFallback && !isFileAllowed) {
201
207
  const errorMsg = makeBox({
202
208
  title: `File Not Found in ${originalVar}`,
203
209
  minWidth: '100%',
@@ -0,0 +1,91 @@
1
+
2
+ const paramRefSyntax = RegExp(/^param:/g)
3
+
4
+ /**
5
+ * Resolves parameter values following the Serverless Framework parameter resolution hierarchy:
6
+ * 1. CLI params (--param="key=value")
7
+ * 2. Stage-specific params (stages.<stage>.params)
8
+ * 3. Default params (stages.default.params)
9
+ *
10
+ * @param {string} variableString - The variable string (e.g., "param:domain")
11
+ * @param {Object} options - CLI options that may contain params
12
+ * @param {Object} config - The full config object for stage-specific params
13
+ * @returns {Promise<any>} The resolved parameter value
14
+ */
15
+ function getValueFromParam(variableString, options = {}, config = {}) {
16
+ const requestedParam = variableString.split(':')[1]
17
+
18
+ if (requestedParam === '') {
19
+ throw new Error(`Invalid variable syntax for parameter reference "${variableString}".
20
+
21
+ \${param} variable must have a key path.
22
+
23
+ Example: \${param:domain}
24
+ `)
25
+ }
26
+
27
+ let valueToPopulate
28
+
29
+ // 1. First, check CLI params (--param="key=value")
30
+ // The param option can be either a string or an array of strings
31
+ if (options.param) {
32
+ const params = Array.isArray(options.param) ? options.param : [options.param]
33
+
34
+ // Parse param flags in the format "key=value"
35
+ for (const param of params) {
36
+ const [key, ...valueParts] = param.split('=')
37
+ if (key === requestedParam) {
38
+ valueToPopulate = valueParts.join('=') // rejoin in case value contains =
39
+ return Promise.resolve(valueToPopulate)
40
+ }
41
+ }
42
+ }
43
+
44
+ // 2. Check for stage-specific params (stages.<stage>.params)
45
+ const stage = options.stage || 'dev'
46
+ if (config.stages && config.stages[stage] && config.stages[stage].params) {
47
+ valueToPopulate = config.stages[stage].params[requestedParam]
48
+ if (valueToPopulate !== undefined) {
49
+ return Promise.resolve(valueToPopulate)
50
+ }
51
+ }
52
+
53
+ // 3. Check for default params (stages.default.params)
54
+ if (config.stages && config.stages.default && config.stages.default.params) {
55
+ valueToPopulate = config.stages.default.params[requestedParam]
56
+ if (valueToPopulate !== undefined) {
57
+ return Promise.resolve(valueToPopulate)
58
+ }
59
+ }
60
+
61
+ // 4. Check top-level params property (for backwards compatibility)
62
+ if (config.params) {
63
+ // Check stage-specific params first
64
+ if (config.params[stage]) {
65
+ valueToPopulate = config.params[stage][requestedParam]
66
+ if (valueToPopulate !== undefined) {
67
+ return Promise.resolve(valueToPopulate)
68
+ }
69
+ }
70
+
71
+ // Then check default params
72
+ if (config.params.default) {
73
+ valueToPopulate = config.params.default[requestedParam]
74
+ if (valueToPopulate !== undefined) {
75
+ return Promise.resolve(valueToPopulate)
76
+ }
77
+ }
78
+ }
79
+
80
+ // If not found, return undefined (will trigger fallback if specified)
81
+ return Promise.resolve(valueToPopulate)
82
+ }
83
+
84
+ module.exports = {
85
+ type: 'param',
86
+ source: 'user',
87
+ syntax: '${param:paramName}',
88
+ description: 'Resolves parameter values from CLI flags, stage-specific params, or default params. Examples: ${param:domain}, ${param:key, "fallbackValue"}',
89
+ match: paramRefSyntax,
90
+ resolver: getValueFromParam
91
+ }
@@ -0,0 +1,207 @@
1
+ const { test } = require('uvu')
2
+ const assert = require('uvu/assert')
3
+ const { resolver } = require('./valueFromParam')
4
+
5
+ test('Resolves parameter from CLI flag', async () => {
6
+ const options = { param: 'domain=myapp.com' }
7
+ const result = await resolver('param:domain', options)
8
+ assert.is(result, 'myapp.com')
9
+ })
10
+
11
+ test('Resolves parameter from multiple CLI flags', async () => {
12
+ const options = { param: ['domain=myapp.com', 'key=value'] }
13
+ const result = await resolver('param:key', options)
14
+ assert.is(result, 'value')
15
+ })
16
+
17
+ test('Resolves parameter with equals sign in value', async () => {
18
+ const options = { param: 'connectionString=Server=localhost;Port=5432' }
19
+ const result = await resolver('param:connectionString', options)
20
+ assert.is(result, 'Server=localhost;Port=5432')
21
+ })
22
+
23
+ test('Resolves parameter from stage-specific params', async () => {
24
+ const options = { stage: 'prod' }
25
+ const config = {
26
+ stages: {
27
+ prod: {
28
+ params: {
29
+ domain: 'production.myapp.com'
30
+ }
31
+ }
32
+ }
33
+ }
34
+ const result = await resolver('param:domain', options, config)
35
+ assert.is(result, 'production.myapp.com')
36
+ })
37
+
38
+ test('Resolves parameter from default stage params', async () => {
39
+ const options = { stage: 'dev' }
40
+ const config = {
41
+ stages: {
42
+ default: {
43
+ params: {
44
+ domain: 'default.myapp.com'
45
+ }
46
+ }
47
+ }
48
+ }
49
+ const result = await resolver('param:domain', options, config)
50
+ assert.is(result, 'default.myapp.com')
51
+ })
52
+
53
+ test('CLI params override stage params', async () => {
54
+ const options = {
55
+ stage: 'prod',
56
+ param: 'domain=cli-override.com'
57
+ }
58
+ const config = {
59
+ stages: {
60
+ prod: {
61
+ params: {
62
+ domain: 'production.myapp.com'
63
+ }
64
+ }
65
+ }
66
+ }
67
+ const result = await resolver('param:domain', options, config)
68
+ assert.is(result, 'cli-override.com')
69
+ })
70
+
71
+ test('Stage-specific params override default params', async () => {
72
+ const options = { stage: 'prod' }
73
+ const config = {
74
+ stages: {
75
+ default: {
76
+ params: {
77
+ domain: 'default.myapp.com'
78
+ }
79
+ },
80
+ prod: {
81
+ params: {
82
+ domain: 'production.myapp.com'
83
+ }
84
+ }
85
+ }
86
+ }
87
+ const result = await resolver('param:domain', options, config)
88
+ assert.is(result, 'production.myapp.com')
89
+ })
90
+
91
+ test('Returns undefined for non-existent parameter', async () => {
92
+ const options = { stage: 'dev' }
93
+ const config = { stages: { dev: { params: {} } } }
94
+ const result = await resolver('param:nonExistent', options, config)
95
+ assert.is(result, undefined)
96
+ })
97
+
98
+ test('Throws error for empty parameter name', async () => {
99
+ try {
100
+ await resolver('param:')
101
+ assert.unreachable('Should have thrown an error')
102
+ } catch (error) {
103
+ assert.ok(error.message.includes('Invalid variable syntax'))
104
+ assert.ok(error.message.includes('must have a key path'))
105
+ }
106
+ })
107
+
108
+ test('Defaults to dev stage when no stage specified', async () => {
109
+ const options = {}
110
+ const config = {
111
+ stages: {
112
+ dev: {
113
+ params: {
114
+ domain: 'dev.myapp.com'
115
+ }
116
+ }
117
+ }
118
+ }
119
+ const result = await resolver('param:domain', options, config)
120
+ assert.is(result, 'dev.myapp.com')
121
+ })
122
+
123
+ test('Supports top-level params property (backwards compatibility)', async () => {
124
+ const options = { stage: 'prod' }
125
+ const config = {
126
+ params: {
127
+ prod: {
128
+ domain: 'production.myapp.com'
129
+ }
130
+ }
131
+ }
132
+ const result = await resolver('param:domain', options, config)
133
+ assert.is(result, 'production.myapp.com')
134
+ })
135
+
136
+ test('Supports top-level params default property', async () => {
137
+ const options = { stage: 'dev' }
138
+ const config = {
139
+ params: {
140
+ default: {
141
+ domain: 'default.myapp.com'
142
+ }
143
+ }
144
+ }
145
+ const result = await resolver('param:domain', options, config)
146
+ assert.is(result, 'default.myapp.com')
147
+ })
148
+
149
+ test('Prefers stages property over params property', async () => {
150
+ const options = { stage: 'prod' }
151
+ const config = {
152
+ stages: {
153
+ prod: {
154
+ params: {
155
+ domain: 'stages.prod.myapp.com'
156
+ }
157
+ }
158
+ },
159
+ params: {
160
+ prod: {
161
+ domain: 'params.prod.myapp.com'
162
+ }
163
+ }
164
+ }
165
+ const result = await resolver('param:domain', options, config)
166
+ assert.is(result, 'stages.prod.myapp.com')
167
+ })
168
+
169
+ test('Returns Promise that resolves to value', async () => {
170
+ const options = { param: 'test=promise-value' }
171
+ const promise = resolver('param:test', options)
172
+ assert.ok(promise instanceof Promise)
173
+ const result = await promise
174
+ assert.is(result, 'promise-value')
175
+ })
176
+
177
+ test('Handles parameter with special characters in value', async () => {
178
+ const options = { param: 'special=value-with-special-chars-!@#$%' }
179
+ const result = await resolver('param:special', options)
180
+ assert.is(result, 'value-with-special-chars-!@#$%')
181
+ })
182
+
183
+ test('Handles empty string parameter value', async () => {
184
+ const options = { param: 'empty=' }
185
+ const result = await resolver('param:empty', options)
186
+ assert.is(result, '')
187
+ })
188
+
189
+ test('Handles numeric parameter value', async () => {
190
+ const options = { param: 'port=3000' }
191
+ const result = await resolver('param:port', options)
192
+ assert.is(result, '3000')
193
+ })
194
+
195
+ test('Handles parameter with underscore', async () => {
196
+ const options = { param: 'my_param=underscore-value' }
197
+ const result = await resolver('param:my_param', options)
198
+ assert.is(result, 'underscore-value')
199
+ })
200
+
201
+ test('Handles parameter with numbers', async () => {
202
+ const options = { param: 'param123=numeric-value' }
203
+ const result = await resolver('param:param123', options)
204
+ assert.is(result, 'numeric-value')
205
+ })
206
+
207
+ test.run()
@@ -34,20 +34,44 @@ function normalizePath(filePath) {
34
34
  }
35
35
 
36
36
  /**
37
- * Extract file path from a file() or text() variable string
37
+ * Extract file path from a file() or text() variable string using balanced paren matching
38
38
  * @param {string} variableString - The variable string (with or without ${} wrapper)
39
39
  * @returns {object|null} Object with filePath, or null if no match
40
40
  */
41
41
  function extractFilePath(variableString) {
42
- // Match both ${file(...)} and file(...) formats
43
- const fileMatch = variableString.match(/^(?:\$\{)?(?:file|text)\((.*?)\)/)
44
- if (!fileMatch || !fileMatch[1]) {
42
+ // Match the file( or text( prefix
43
+ const prefixMatch = variableString.match(/^(?:\$\{)?(file|text)\(/)
44
+ if (!prefixMatch) {
45
+ return null
46
+ }
47
+
48
+ // Find matching closing paren using depth tracking
49
+ const startIndex = prefixMatch[0].length - 1 // Position of opening (
50
+ let depth = 1
51
+ let i = startIndex + 1
52
+
53
+ while (i < variableString.length && depth > 0) {
54
+ if (variableString[i] === '(') {
55
+ depth++
56
+ } else if (variableString[i] === ')') {
57
+ depth--
58
+ }
59
+ i++
60
+ }
61
+
62
+ if (depth !== 0) {
63
+ return null
64
+ }
65
+
66
+ // Extract content between balanced parens
67
+ const fileContent = variableString.substring(startIndex + 1, i - 1).trim()
68
+ if (!fileContent) {
45
69
  return null
46
70
  }
47
71
 
48
72
  const { trimSurroundingQuotes } = require('../strings/quoteUtils')
49
- const fileContent = fileMatch[1].trim()
50
- const parts = splitCsv(fileContent)
73
+ // Protect ${} variables from being split (e.g., file paths with default values)
74
+ const parts = splitCsv(fileContent, undefined, { protectVariables: true })
51
75
  let filePath = parts[0].trim()
52
76
 
53
77
  // Remove quotes if present
@@ -103,6 +103,22 @@ test('extractFilePath - handles bare filename', () => {
103
103
  assert.is(result.filePath, 'config.json')
104
104
  })
105
105
 
106
+ test('extractFilePath - handles nested variable with default value in path', () => {
107
+ // This is the bug case: ${self:provider.stage, 'dev'} has a comma inside
108
+ const result = extractFilePath("file(./env.${self:provider.stage, 'dev'}.yml):FOO")
109
+ assert.is(result.filePath, "./env.${self:provider.stage, 'dev'}.yml")
110
+ })
111
+
112
+ test('extractFilePath - handles nested variable without default in path', () => {
113
+ const result = extractFilePath("file(./env.${self:provider.stage}.yml):FOO")
114
+ assert.is(result.filePath, "./env.${self:provider.stage}.yml")
115
+ })
116
+
117
+ test('extractFilePath - handles multiple nested variables in path', () => {
118
+ const result = extractFilePath("file(./config-${self:stage, 'dev'}-${self:region}.yml)")
119
+ assert.is(result.filePath, "./config-${self:stage, 'dev'}-${self:region}.yml")
120
+ })
121
+
106
122
  // normalizeFileVariable tests
107
123
 
108
124
  test('normalizeFileVariable - returns non-file strings unchanged', () => {
@@ -1,14 +1,19 @@
1
1
  const { splitByComma } = require('./splitByComma')
2
2
 
3
+ // Regex to match ${...} variables (used for protection during file path splitting)
4
+ const VARIABLE_SYNTAX = /\${[^}]+}/g
5
+
3
6
  /**
4
7
  * Split a string by comma while preserving quoted content
5
8
  * NOTE: This is a simpler version that delegates to splitByComma for consistency.
6
9
  * For advanced use cases with bracket depth tracking and regex protection, use splitByComma directly.
7
10
  * @param {string} str - String to split
8
11
  * @param {string} [splitter] - Optional custom splitter (defaults to ',')
12
+ * @param {object} [options] - Options object
13
+ * @param {boolean} [options.protectVariables] - If true, protect ${} variables from splitting
9
14
  * @returns {string[]} Array of split strings
10
15
  */
11
- function splitCsv(str, splitter) {
16
+ function splitCsv(str, splitter, options = {}) {
12
17
  // If custom splitter is provided, fall back to original simple implementation
13
18
  if (splitter && splitter !== ',') {
14
19
  const splitSyntax = splitter
@@ -32,6 +37,10 @@ function splitCsv(str, splitter) {
32
37
  }
33
38
 
34
39
  // For standard comma splitting, use the more robust splitByComma
40
+ // Pass VARIABLE_SYNTAX if protectVariables is true to protect ${} from splitting
41
+ if (options.protectVariables) {
42
+ return splitByComma(str, VARIABLE_SYNTAX)
43
+ }
35
44
  return splitByComma(str)
36
45
  }
37
46
 
@@ -88,8 +88,61 @@ Remove or update the \${${variableString}} to fix
88
88
  return isRealVariable
89
89
  }
90
90
 
91
+ /**
92
+ * Build default variable syntax regex with dynamic character class
93
+ * Excludes suffix characters from the allowed set to prevent parsing issues
94
+ * @param {string} [prefix='${'] - Variable prefix
95
+ * @param {string} [suffix='}'] - Variable suffix
96
+ * @param {string[]} [excludePatterns=['AWS', 'stageVariables']] - Patterns to exclude via negative lookahead
97
+ * @returns {string} Regex source string
98
+ */
99
+ function buildVariableSyntax(prefix = '${', suffix = '}', excludePatterns = ['AWS', 'stageVariables']) {
100
+ // All allowed characters, stored as individual escaped entries for regex character class
101
+ // Each entry is how it appears in a regex character class
102
+ // NOTE: { and } are intentionally excluded - they break nested variable matching
103
+ // NOTE: $ is intentionally excluded - it's part of variable prefix and breaks nesting
104
+ const allChars = [
105
+ ' ', '~', ':', 'a-z', 'A-Z', '0-9', '=', '+', '!', '@', '#', '%',
106
+ '\\^', '&', ';', '`', '\\*', '<', '>', '\\?', '\\.', '_', "'", '"', ',',
107
+ '\\|', '\\-', '\\/', '\\(', '\\)', '\\[', '\\]', '\\\\'
108
+ ]
109
+
110
+ // Map of unescaped char to its escaped form in regex character class
111
+ const charEscapeMap = {
112
+ '^': '\\^', '*': '\\*', '?': '\\?', '.': '\\.', '|': '\\|',
113
+ '-': '\\-', '/': '\\/', '(': '\\(', ')': '\\)', '[': '\\[', ']': '\\]',
114
+ '\\': '\\\\'
115
+ }
116
+
117
+ // Get unique characters from suffix that need to be excluded
118
+ const suffixChars = [...new Set(suffix.split(''))]
119
+
120
+ // Filter out chars that appear in suffix
121
+ const allowedChars = allChars.filter(charEntry => {
122
+ for (const sc of suffixChars) {
123
+ const escaped = charEscapeMap[sc] || sc
124
+ if (charEntry === escaped || charEntry === sc) {
125
+ return false
126
+ }
127
+ }
128
+ return true
129
+ })
130
+
131
+ // Escape prefix and suffix for regex
132
+ const escapedPrefix = prefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
133
+ const escapedSuffix = suffix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
134
+
135
+ // Build negative lookahead for excluded patterns
136
+ const lookahead = excludePatterns.length > 0
137
+ ? `(?!${excludePatterns.join('|')})`
138
+ : ''
139
+
140
+ return `${escapedPrefix}(${lookahead}[${allowedChars.join('')}]+?)${escapedSuffix}`
141
+ }
142
+
91
143
  module.exports = {
92
144
  extractVariableWrapper,
93
145
  getFallbackString,
94
- verifyVariable
146
+ verifyVariable,
147
+ buildVariableSyntax
95
148
  }
@@ -150,5 +150,49 @@ test('extractVariableWrapper - strips non-capturing group prefix', () => {
150
150
  assert.equal(result.suffix, '}')
151
151
  })
152
152
 
153
+ // Tests for buildVariableSyntax
154
+ const { buildVariableSyntax } = require('./variableUtils')
155
+
156
+ test('buildVariableSyntax - default ${} syntax excludes $ {', () => {
157
+ const syntax = buildVariableSyntax('${', '}')
158
+ const regex = new RegExp(syntax, 'g')
159
+ // $ and { in value cause no match (they're not in character class)
160
+ assert.not.ok("${env:FOO, 'test$value'}".match(regex))
161
+ assert.not.ok("${env:FOO, 'test{value'}".match(regex))
162
+ // } causes partial match (ends early at the } in value)
163
+ const partialMatch = "${env:FOO, 'test}value'}".match(regex)
164
+ assert.ok(partialMatch)
165
+ assert.is(partialMatch[0], "${env:FOO, 'test}")
166
+ })
167
+
168
+ test('buildVariableSyntax - supports backslash in values', () => {
169
+ const syntax = buildVariableSyntax('${', '}')
170
+ const regex = new RegExp(syntax, 'g')
171
+ const match = "${env:FOO, 'path\\to\\file'}".match(regex)
172
+ assert.is(match[0], "${env:FOO, 'path\\to\\file'}")
173
+ })
174
+
175
+ test('buildVariableSyntax - double brace ${{}} syntax excludes }', () => {
176
+ const syntax = buildVariableSyntax('${{', '}}')
177
+ const regex = new RegExp(syntax, 'g')
178
+ const match = "${{env:FOO, 'value'}}".match(regex)
179
+ assert.is(match[0], "${{env:FOO, 'value'}}")
180
+ })
181
+
182
+ test('buildVariableSyntax - angle bracket <> syntax excludes >', () => {
183
+ const syntax = buildVariableSyntax('<', '>')
184
+ const regex = new RegExp(syntax, 'g')
185
+ // > in value causes partial match
186
+ const match = "<env:FOO, 'a>b'>".match(regex)
187
+ assert.is(match[0], "<env:FOO, 'a>")
188
+ })
189
+
190
+ test('buildVariableSyntax - bracket [[]] syntax excludes ]', () => {
191
+ const syntax = buildVariableSyntax('[[', ']]')
192
+ const regex = new RegExp(syntax, 'g')
193
+ const match = "[[env:FOO, 'value']]".match(regex)
194
+ assert.is(match[0], "[[env:FOO, 'value']]")
195
+ })
196
+
153
197
  // Run all tests
154
198
  test.run()
@@ -3,10 +3,11 @@ declare namespace _exports {
3
3
  }
4
4
  declare function _exports<T = any>(configPathOrObject: string | any, settings?: ConfigoramaSettings): Promise<T | ConfigoramaResult<T>>;
5
5
  declare namespace _exports {
6
- export { Configorama };
7
6
  export function sync<T = any>(configPathOrObject: string | any, settings?: ConfigoramaSettings): T;
8
7
  export function analyze(configPathOrObject: string | object, settings?: object): Promise<any>;
9
8
  export { parsers as format };
9
+ export { Configorama };
10
+ export { buildVariableSyntax };
10
11
  }
11
12
  export = _exports;
12
13
  type ConfigoramaSettings = {
@@ -95,6 +96,7 @@ type ConfigoramaResult<T = any> = {
95
96
  */
96
97
  resolutionHistory: any;
97
98
  };
98
- import Configorama = require("./main");
99
99
  import parsers = require("./parsers");
100
+ import Configorama = require("./main");
101
+ import { buildVariableSyntax } from "./utils/variables/variableUtils";
100
102
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.js"],"names":[],"mappings":";;;AAwCiB,0BALH,CAAC,4BACJ,MAAM,MAAO,aACb,mBAAmB,GACjB,OAAO,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAiD7C;;;IASqB,qBALR,CAAC,4BACJ,MAAM,MAAO,aACb,mBAAmB,GACjB,CAAC,CAgBb;IAQwB,4CAJb,MAAM,GAAC,MAAM,aACd,MAAM,gBAUhB;;;;;;;;;;;;;;aApHa,MAAM;;;;gBACN,MAAM;;;;;;;;;;;;;;;;;;;;uBAIN,OAAO;;;;2BACP,OAAO;;;;kBACP,cAAe;;;;qBACf,OAAO;;;;gBACP,MAAM,EAAE;;;;;;;;uBAKR,CAAC;;;;oBAED,MAAM;;;;;;;;;;YAEN,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.js"],"names":[],"mappings":";;;AAuCiB,0BALH,CAAC,4BACJ,MAAM,MAAO,aACb,mBAAmB,GACjB,OAAO,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAiD7C;;IASqB,qBALR,CAAC,4BACJ,MAAM,MAAO,aACb,mBAAmB,GACjB,CAAC,CAgBb;IAQwB,4CAJb,MAAM,GAAC,MAAM,aACd,MAAM,gBAUhB;;;;;;;;;;;;;;;;aApHa,MAAM;;;;gBACN,MAAM;;;;;;;;;;;;;;;;;;;;uBAIN,OAAO;;;;2BACP,OAAO;;;;kBACP,cAAe;;;;qBACf,OAAO;;;;gBACP,MAAM,EAAE;;;;;;;;uBAKR,CAAC;;;;oBAED,MAAM;;;;;;;;;;YAEN,CAAC"}
@@ -27,6 +27,24 @@ declare class Configorama {
27
27
  deep: any[];
28
28
  leaves: any[];
29
29
  callCount: number;
30
+ /**
31
+ * Check if unresolved variables of a given type should pass through
32
+ * @param {string} type - The resolver type (e.g., 'param', 'file', 'env')
33
+ * @returns {boolean}
34
+ */
35
+ isUnresolvedAllowed(type: string): boolean;
36
+ /**
37
+ * Extract type prefix from a variable string
38
+ * @param {string} varString - Variable string like 'ssm:path/to/thing' or 'custom:value'
39
+ * @returns {string|null} The type prefix or null if not found
40
+ */
41
+ extractTypePrefix(varString: string): string | null;
42
+ /**
43
+ * Check if unknown variable types should pass through
44
+ * @param {string} varString - Variable string like 'ssm:path' or full '${ssm:path}'
45
+ * @returns {boolean}
46
+ */
47
+ isUnknownTypeAllowed(varString: string): boolean;
30
48
  /**
31
49
  * Populate all variables in the service, conveniently remove and restore the service attributes
32
50
  * that confuse the population methods.
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/main.js"],"names":[],"mappings":";AA6HA;IACE,0CAgaC;IAxZC,cAaW;IAOX,gBAAqB;IAErB,sBAAwB;IACxB,qBAAuB;IAGvB,uBAA4B;IAc5B,uBAAoC;IAIpC,kBAAqC;IACrC,kBAAqC;IAErC,yBAA+F;IAC/F,yBAAuD;IACvD,kCAAyE;IAKvE,YAA0B;IAE1B,oBAA6C;IAE7C,gBAAoD;IAOpD,uBAAkC;IAElC,uBAA8B;IAE9B,uBAAkC;IASpC,wBAAmC;IAGnC,mBAsGC;IAoED,4BAA8C;IAO9C,aA2EC;IAUD,oBAEC;IAGD,eAkDC;IAOD,YAAc;IACd,cAAgB;IAChB,kBAAkB;IAMpB;;;;;OAKG;IACH,oBAFa,OAAO,CAAC,GAAG,CAAC,CAqsBxB;IAlsBC,aAA4B;IAc1B,2BAA4B;IAQ5B,uBAAgD;IA8qBpD;;;OAGG;IACH,2BAFa,MAAM,CA8alB;IAvBC;;;;;;;;;;;;;;;MAoBC;IAIH;;;;OAIG;IACH,uCAFa,OAAO,CAAC,GAAG,CAAC,CAIxB;IACD,+CAsBC;IAKD;;;;;;;;;;;;;;;;;;;OAmBG;IACH;;;;;;;;;;;OAWG;IACH,mFAHa;;;;cAZC,QAAQ;;;;eACR,IAAI,GAAC,MAAM,SAAO;OAWD,CA+D9B;IACD;;;OAGG;IACH;;;;;OAKG;IACH,oCAHa,OAAO,CAAC;;;;cAnFP,QAAQ;;;;eACR,IAAI,GAAC,MAAM,SAAO;OAkFgB,CAAC,EAAE,CA6BlD;IACD;;;;;OAKG;IACH,iDAFa,OAAO,CAAC,IAAI,CAAC,CAWzB;IAID;;;;;OAKG;IACH;;;;OAIG;IACH,2BAFa,eAAc;;;;;;;;;;OAAa,CAavC;IACD;;;;;OAKG;IACH,yBAHW;;;;;;;;;;OAAa,gCACX,cAAS,CAOrB;IACD;;;;;;OAMG;IACH,6DAFa,GAAC,CA+Kb;IAKD;;;;;;;OAOG;IACH,yDAHa,OAAO,CAAC,GAAG,CAAC,CAiCxB;IACD;;;;OAIG;IAOH;;;;;;OAMG;IACH,wFA2BC;IACD;;;;;;;;;;;OAWG;IACH,8BARG;QAAyB,KAAK,EAAtB,GAAG;QACoB,IAAI,GAA3B,MAAM,EAAE;QACa,cAAc,GAAnC,MAAM;QACc,iBAAiB;KAC7C,6CAEU;QAAC,KAAK,EAAE,GAAG,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,QAAQ;QAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAC,CAmY9J;IAID;;;;;;;;OAQG;IACH,qEAHa,OAAO,CAAC,GAAG,CAAC,CAoExB;IAKD;;;;;;;OAOG;IACH,0FAFa,OAAO,CAAC,GAAG,CAAC,CAofxB;IACD,+EA8BC;IACD,yDAeC;IACD,oEA6BC;IAKD,8CAQC;IACD,kDAyBC;IACD;;;;;;;;;;;;;OAaG;IACH,wEAoDC;IAKD,4BAOC;IACD,sCAoDC;CACF"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/main.js"],"names":[],"mappings":";AA0GA;IACE,0CAwbC;IAhbC,cAaW;IAuBX,gBAAqB;IAErB,sBAAwB;IACxB,qBAAuB;IAGvB,uBAA4B;IAc5B,uBAAoC;IAIpC,kBAAqC;IACrC,kBAAqC;IAErC,yBAA+F;IAC/F,yBAAuD;IACvD,kCAAyE;IAKvE,YAA0B;IAE1B,oBAA6C;IAE7C,gBAAoD;IAOpD,uBAAkC;IAElC,uBAA8B;IAE9B,uBAAkC;IASpC,wBAAmC;IAGnC,mBA8GC;IAoED,4BAA8C;IAO9C,aA2EC;IAUD,oBAEC;IAGD,eAkDC;IAOD,YAAc;IACd,cAAgB;IAChB,kBAAkB;IAGpB;;;;OAIG;IACH,0BAHW,MAAM,GACJ,OAAO,CAQnB;IAED;;;;OAIG;IACH,6BAHW,MAAM,GACJ,MAAM,GAAC,IAAI,CAOvB;IAED;;;;OAIG;IACH,gCAHW,MAAM,GACJ,OAAO,CAoBnB;IAKD;;;;;OAKG;IACH,oBAFa,OAAO,CAAC,GAAG,CAAC,CAqsBxB;IAlsBC,aAA4B;IAc1B,2BAA4B;IAQ5B,uBAAgD;IA8qBpD;;;OAGG;IACH,2BAFa,MAAM,CA8alB;IAvBC;;;;;;;;;;;;;;;MAoBC;IAIH;;;;OAIG;IACH,uCAFa,OAAO,CAAC,GAAG,CAAC,CAIxB;IACD,+CAsBC;IAKD;;;;;;;;;;;;;;;;;;;OAmBG;IACH;;;;;;;;;;;OAWG;IACH,mFAHa;;;;cAZC,QAAQ;;;;eACR,IAAI,GAAC,MAAM,SAAO;OAWD,CA+D9B;IACD;;;OAGG;IACH;;;;;OAKG;IACH,oCAHa,OAAO,CAAC;;;;cAnFP,QAAQ;;;;eACR,IAAI,GAAC,MAAM,SAAO;OAkFgB,CAAC,EAAE,CA6BlD;IACD;;;;;OAKG;IACH,iDAFa,OAAO,CAAC,IAAI,CAAC,CAWzB;IAID;;;;;OAKG;IACH;;;;OAIG;IACH,2BAFa,eAAc;;;;;;;;;;OAAa,CAavC;IACD;;;;;OAKG;IACH,yBAHW;;;;;;;;;;OAAa,gCACX,cAAS,CAOrB;IACD;;;;;;OAMG;IACH,6DAFa,GAAC,CA+Kb;IAKD;;;;;;;OAOG;IACH,yDAHa,OAAO,CAAC,GAAG,CAAC,CAiCxB;IACD;;;;OAIG;IAOH;;;;;;OAMG;IACH,wFA2BC;IACD;;;;;;;;;;;OAWG;IACH,8BARG;QAAyB,KAAK,EAAtB,GAAG;QACoB,IAAI,GAA3B,MAAM,EAAE;QACa,cAAc,GAAnC,MAAM;QACc,iBAAiB;KAC7C,6CAEU;QAAC,KAAK,EAAE,GAAG,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,iBAAiB,CAAC,QAAQ;QAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAC,CAmY9J;IAID;;;;;;;;OAQG;IACH,qEAHa,OAAO,CAAC,GAAG,CAAC,CAoExB;IAKD;;;;;;;OAOG;IACH,0FAFa,OAAO,CAAC,GAAG,CAAC,CA0fxB;IACD,+EA8BC;IACD,yDAeC;IACD,oEA6BC;IAKD,8CAQC;IACD,kDAyBC;IACD;;;;;;;;;;;;;OAaG;IACH,wEAoDC;IAKD,4BAOC;IACD,sCAoDC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"valueFromFile.d.ts","sourceRoot":"","sources":["../../../src/resolvers/valueFromFile.js"],"names":[],"mappings":"AAkEA;;;;;;;;;;;;;;;;;GAiBG;AACH,sCAfG;IAAoB,UAAU,EAAtB,MAAM;IACK,aAAa;IACZ,cAAc,EAA1B,MAAM;IACM,mBAAmB,EAA/B,MAAM;IACM,aAAa,EAAzB,MAAM;IACM,IAAI,EAAhB,MAAM;IACM,cAAc,EAA1B,MAAM;IACM,MAAM,EAAlB,MAAM;IACQ,cAAc;IAChB,aAAa,EAAzB,MAAM;IACM,aAAa,EAAzB,MAAM;CACd,kBAAQ,MAAM,WACN,MAAM,GACJ,OAAO,CAAC,GAAG,CAAC,CA8SxB;AAxVD;;;;;GAKG;AACH,2CAJW,MAAM,YACN,MAAM,GACJ,GAAC,CAoBb;AAkUD;;;;;;GAMG;AACH,qDAJW,MAAM,qBACN,MAAM,GACJ;IAAE,aAAa,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,GAAC,IAAI,CAAA;CAAE,CAkBhE;AAED;;;;;;GAMG;AACH,sDALW,MAAM,qBACN,MAAM,yBACN,OAAO,GACL,MAAM,EAAE,CAcpB"}
1
+ {"version":3,"file":"valueFromFile.d.ts","sourceRoot":"","sources":["../../../src/resolvers/valueFromFile.js"],"names":[],"mappings":"AAkEA;;;;;;;;;;;;;;;;;GAiBG;AACH,sCAfG;IAAoB,UAAU,EAAtB,MAAM;IACK,aAAa;IACZ,cAAc,EAA1B,MAAM;IACM,mBAAmB,EAA/B,MAAM;IACM,aAAa,EAAzB,MAAM;IACM,IAAI,EAAhB,MAAM;IACM,cAAc,EAA1B,MAAM;IACM,MAAM,EAAlB,MAAM;IACQ,cAAc;IAChB,aAAa,EAAzB,MAAM;IACM,aAAa,EAAzB,MAAM;CACd,kBAAQ,MAAM,WACN,MAAM,GACJ,OAAO,CAAC,GAAG,CAAC,CAoTxB;AA9VD;;;;;GAKG;AACH,2CAJW,MAAM,YACN,MAAM,GACJ,GAAC,CAoBb;AAwUD;;;;;;GAMG;AACH,qDAJW,MAAM,qBACN,MAAM,GACJ;IAAE,aAAa,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,EAAE,MAAM,GAAC,IAAI,CAAA;CAAE,CAkBhE;AAED;;;;;;GAMG;AACH,sDALW,MAAM,qBACN,MAAM,yBACN,OAAO,GACL,MAAM,EAAE,CAcpB"}
@@ -0,0 +1,19 @@
1
+ declare const paramRefSyntax: RegExp;
2
+ /**
3
+ * Resolves parameter values following the Serverless Framework parameter resolution hierarchy:
4
+ * 1. CLI params (--param="key=value")
5
+ * 2. Stage-specific params (stages.<stage>.params)
6
+ * 3. Default params (stages.default.params)
7
+ *
8
+ * @param {string} variableString - The variable string (e.g., "param:domain")
9
+ * @param {Object} options - CLI options that may contain params
10
+ * @param {Object} config - The full config object for stage-specific params
11
+ * @returns {Promise<any>} The resolved parameter value
12
+ */
13
+ declare function getValueFromParam(variableString: string, options?: any, config?: any): Promise<any>;
14
+ export declare let type: string;
15
+ export declare let source: string;
16
+ export declare let syntax: string;
17
+ export declare let description: string;
18
+ export { paramRefSyntax as match, getValueFromParam as resolver };
19
+ //# sourceMappingURL=valueFromParam.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"valueFromParam.d.ts","sourceRoot":"","sources":["../../../src/resolvers/valueFromParam.js"],"names":[],"mappings":"AACA,qCAAyC;AAEzC;;;;;;;;;;GAUG;AACH,mDALW,MAAM,gCAGJ,OAAO,CAAC,GAAG,CAAC,CAqExB"}
@@ -5,7 +5,7 @@
5
5
  */
6
6
  export function normalizePath(filePath: string): string | null;
7
7
  /**
8
- * Extract file path from a file() or text() variable string
8
+ * Extract file path from a file() or text() variable string using balanced paren matching
9
9
  * @param {string} variableString - The variable string (with or without ${} wrapper)
10
10
  * @returns {object|null} Object with filePath, or null if no match
11
11
  */
@@ -1 +1 @@
1
- {"version":3,"file":"filePathUtils.d.ts","sourceRoot":"","sources":["../../../../src/utils/paths/filePathUtils.js"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wCAHW,MAAM,GACJ,MAAM,GAAC,IAAI,CA0BvB;AAED;;;;GAIG;AACH,gDAHW,MAAM,GACJ,MAAM,GAAC,IAAI,CAkBvB;AAED;;;;;GAKG;AACH,sDAHW,MAAM,GACJ,MAAM,CAkBlB;AAED;;;;;;;GAOG;AACH,2CANW,MAAM,kBACN,MAAM,UACN,MAAM,sBAEJ;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAC,CAwCnD"}
1
+ {"version":3,"file":"filePathUtils.d.ts","sourceRoot":"","sources":["../../../../src/utils/paths/filePathUtils.js"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wCAHW,MAAM,GACJ,MAAM,GAAC,IAAI,CA0BvB;AAED;;;;GAIG;AACH,gDAHW,MAAM,GACJ,MAAM,GAAC,IAAI,CA0CvB;AAED;;;;;GAKG;AACH,sDAHW,MAAM,GACJ,MAAM,CAkBlB;AAED;;;;;;;GAOG;AACH,2CANW,MAAM,kBACN,MAAM,UACN,MAAM,sBAEJ;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAC,CAwCnD"}
@@ -4,7 +4,11 @@
4
4
  * For advanced use cases with bracket depth tracking and regex protection, use splitByComma directly.
5
5
  * @param {string} str - String to split
6
6
  * @param {string} [splitter] - Optional custom splitter (defaults to ',')
7
+ * @param {object} [options] - Options object
8
+ * @param {boolean} [options.protectVariables] - If true, protect ${} variables from splitting
7
9
  * @returns {string[]} Array of split strings
8
10
  */
9
- export function splitCsv(str: string, splitter?: string): string[];
11
+ export function splitCsv(str: string, splitter?: string, options?: {
12
+ protectVariables?: boolean;
13
+ }): string[];
10
14
  //# sourceMappingURL=splitCsv.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"splitCsv.d.ts","sourceRoot":"","sources":["../../../../src/utils/strings/splitCsv.js"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,8BAJW,MAAM,aACN,MAAM,GACJ,MAAM,EAAE,CA2BpB"}
1
+ {"version":3,"file":"splitCsv.d.ts","sourceRoot":"","sources":["../../../../src/utils/strings/splitCsv.js"],"names":[],"mappings":"AAKA;;;;;;;;;GASG;AACH,8BANW,MAAM,aACN,MAAM,YAEd;IAA0B,gBAAgB,GAAlC,OAAO;CACf,GAAU,MAAM,EAAE,CA+BpB"}