configorama 0.8.0 → 0.9.3

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 (34) hide show
  1. package/README.md +38 -3
  2. package/package.json +1 -1
  3. package/src/main.js +53 -21
  4. package/src/parsers/yaml.js +4 -4
  5. package/src/parsers/yaml.test.js +52 -0
  6. package/src/resolvers/valueFromFile.js +15 -2
  7. package/src/utils/PromiseTracker.js +54 -0
  8. package/src/utils/encoders/unknown-values.js +1 -1
  9. package/src/utils/encoders/unknown-values.test.js +146 -0
  10. package/src/utils/lodash.js +5 -4
  11. package/src/utils/lodash.test.js +172 -0
  12. package/src/utils/parsing/cloudformationSchema.js +24 -2
  13. package/src/utils/parsing/cloudformationSchema.test.js +236 -0
  14. package/src/utils/parsing/mergeByKeys.js +9 -8
  15. package/src/utils/parsing/mergeByKeys.test.js +189 -0
  16. package/src/utils/parsing/parse.js +5 -2
  17. package/src/utils/paths/getFullFilePath.js +2 -2
  18. package/src/utils/paths/getFullFilePath.test.js +152 -0
  19. package/src/utils/regex/index.js +65 -1
  20. package/src/utils/regex/index.test.js +195 -0
  21. package/src/utils/strings/formatFunctionArgs.js +4 -0
  22. package/src/utils/strings/splitCsv.js +46 -19
  23. package/types/src/main.d.ts.map +1 -1
  24. package/types/src/resolvers/valueFromFile.d.ts.map +1 -1
  25. package/types/src/utils/PromiseTracker.d.ts +4 -0
  26. package/types/src/utils/PromiseTracker.d.ts.map +1 -1
  27. package/types/src/utils/lodash.d.ts.map +1 -1
  28. package/types/src/utils/parsing/mergeByKeys.d.ts.map +1 -1
  29. package/types/src/utils/parsing/parse.d.ts.map +1 -1
  30. package/types/src/utils/regex/index.d.ts +15 -1
  31. package/types/src/utils/regex/index.d.ts.map +1 -1
  32. package/types/src/utils/strings/formatFunctionArgs.d.ts.map +1 -1
  33. package/types/src/utils/strings/splitCsv.d.ts +1 -1
  34. package/types/src/utils/strings/splitCsv.d.ts.map +1 -1
@@ -17,8 +17,8 @@ function resolveFilePath(pathToResolve, basePath) {
17
17
  if (fs.existsSync(fullFilePath)) {
18
18
  // Get real path to handle potential symlinks (but don't fatal error)
19
19
  fullFilePath = fs.realpathSync(fullFilePath)
20
- // Only match files that are relative
21
- } else if (pathToResolve.match(/\.\//)) {
20
+ // Only use findUp for relative paths (not absolute paths)
21
+ } else if (!path.isAbsolute(pathToResolve)) {
22
22
  const cleanName = path.basename(pathToResolve)
23
23
  const findUpResult = findUp.sync(cleanName, { cwd: basePath })
24
24
  if (findUpResult) {
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Tests for getFullFilePath.js - file path resolution with findUp support
3
+ */
4
+ const { test } = require('uvu')
5
+ const assert = require('uvu/assert')
6
+ const path = require('path')
7
+ const fs = require('fs')
8
+ const getFullPath = require('./getFullFilePath')
9
+ const { resolveFilePath, resolveFilePathFromMatch } = require('./getFullFilePath')
10
+
11
+ // ==========================================
12
+ // Test directory setup/teardown
13
+ // ==========================================
14
+
15
+ const testDir = path.join(__dirname, '_test-getFullFilePath')
16
+ const subDir = path.join(testDir, 'subdir')
17
+ const deepDir = path.join(subDir, 'deepdir')
18
+
19
+ test.before(() => {
20
+ // Cleanup any existing test directory
21
+ if (fs.existsSync(testDir)) {
22
+ fs.rmSync(testDir, { recursive: true })
23
+ }
24
+
25
+ // Create directory structure:
26
+ // _test-getFullFilePath/
27
+ // config.yml <- file at root
28
+ // subdir/
29
+ // local.yml <- file in subdir
30
+ // deepdir/
31
+ // (empty - for testing findUp from here)
32
+ fs.mkdirSync(testDir, { recursive: true })
33
+ fs.mkdirSync(subDir, { recursive: true })
34
+ fs.mkdirSync(deepDir, { recursive: true })
35
+
36
+ // Create test files
37
+ fs.writeFileSync(path.join(testDir, 'config.yml'), 'root: true')
38
+ fs.writeFileSync(path.join(subDir, 'local.yml'), 'local: true')
39
+ })
40
+
41
+ test.after(() => {
42
+ // Cleanup
43
+ if (fs.existsSync(testDir)) {
44
+ fs.rmSync(testDir, { recursive: true })
45
+ }
46
+ })
47
+
48
+ // ==========================================
49
+ // resolveFilePath - basic functionality
50
+ // ==========================================
51
+
52
+ test('resolveFilePath - returns file when it exists at computed path', () => {
53
+ const result = resolveFilePath('./config.yml', testDir)
54
+ assert.is(result, path.join(testDir, 'config.yml'))
55
+ })
56
+
57
+ test('resolveFilePath - handles absolute paths', () => {
58
+ const absolutePath = path.join(testDir, 'config.yml')
59
+ const result = resolveFilePath(absolutePath, '/some/other/path')
60
+ assert.is(result, absolutePath)
61
+ })
62
+
63
+ test('resolveFilePath - returns computed path when file does not exist', () => {
64
+ const result = resolveFilePath('./nonexistent.yml', testDir)
65
+ assert.is(result, path.join(testDir, 'nonexistent.yml'))
66
+ })
67
+
68
+ // ==========================================
69
+ // resolveFilePath - findUp with "./" prefix
70
+ // ==========================================
71
+
72
+ test('resolveFilePath - with "./" prefix triggers findUp and finds file in parent directory', () => {
73
+ // From deepDir, look for config.yml which is in testDir (grandparent)
74
+ const result = resolveFilePath('./config.yml', deepDir)
75
+ const expected = path.join(testDir, 'config.yml')
76
+ assert.is(result, expected)
77
+ })
78
+
79
+ test('resolveFilePath - with "./" prefix finds file in immediate parent', () => {
80
+ // From deepDir, look for local.yml which is in subDir (parent)
81
+ const result = resolveFilePath('./local.yml', deepDir)
82
+ const expected = path.join(subDir, 'local.yml')
83
+ assert.is(result, expected)
84
+ })
85
+
86
+ // ==========================================
87
+ // resolveFilePath - findUp WITHOUT "./" prefix (bug fix tests)
88
+ // ==========================================
89
+
90
+ test('resolveFilePath - bare filename should also trigger findUp', () => {
91
+ // From deepDir, look for config.yml (bare filename) which is in testDir
92
+ const result = resolveFilePath('config.yml', deepDir)
93
+ const expected = path.join(testDir, 'config.yml')
94
+ assert.is(result, expected,
95
+ `Bare filename should trigger findUp. Got ${result} instead of ${expected}`)
96
+ })
97
+
98
+ test('resolveFilePath - bare filename finds file in immediate parent', () => {
99
+ // From deepDir, look for local.yml (bare filename) which is in subDir
100
+ const result = resolveFilePath('local.yml', deepDir)
101
+ const expected = path.join(subDir, 'local.yml')
102
+ assert.is(result, expected)
103
+ })
104
+
105
+ test('resolveFilePath - relative path without ./ prefix triggers findUp', () => {
106
+ // Path like "subdir/file.yml" should also trigger findUp if not found
107
+ const result = resolveFilePath('config.yml', deepDir)
108
+ const expected = path.join(testDir, 'config.yml')
109
+ assert.is(result, expected)
110
+ })
111
+
112
+ // ==========================================
113
+ // getFullPath - wrapper function
114
+ // ==========================================
115
+
116
+ test('getFullPath - resolves file path using cwd', () => {
117
+ const result = getFullPath('./config.yml', testDir)
118
+ assert.is(result, path.join(testDir, 'config.yml'))
119
+ })
120
+
121
+ test('getFullPath - expands ~ to home directory', () => {
122
+ const os = require('os')
123
+ const result = getFullPath('~/somefile.yml', testDir)
124
+ assert.ok(result.startsWith(os.homedir()))
125
+ })
126
+
127
+ // ==========================================
128
+ // resolveFilePathFromMatch - file() syntax parsing
129
+ // ==========================================
130
+
131
+ const fileRefSyntax = /^file\((~?[@\{\}\:\$a-zA-Z0-9._\-\/,'" =+]+?)\)/g
132
+
133
+ test('resolveFilePathFromMatch - extracts path from file() syntax', () => {
134
+ const result = resolveFilePathFromMatch('file(./config.yml)', fileRefSyntax, testDir)
135
+ assert.is(result.relativePath, './config.yml')
136
+ assert.is(result.fullFilePath, path.join(testDir, 'config.yml'))
137
+ })
138
+
139
+ test('resolveFilePathFromMatch - handles quoted paths', () => {
140
+ const result = resolveFilePathFromMatch("file('./config.yml')", fileRefSyntax, testDir)
141
+ assert.is(result.relativePath, './config.yml')
142
+ })
143
+
144
+ test('resolveFilePathFromMatch - handles bare filename in file() syntax', () => {
145
+ // This tests the bug fix - bare filename should work with findUp
146
+ const result = resolveFilePathFromMatch('file(config.yml)', fileRefSyntax, deepDir)
147
+ const expected = path.join(testDir, 'config.yml')
148
+ assert.is(result.fullFilePath, expected,
149
+ `file(config.yml) should find file via findUp. Got ${result.fullFilePath}`)
150
+ })
151
+
152
+ test.run()
@@ -2,10 +2,72 @@
2
2
  * Shared regex patterns and utilities
3
3
  */
4
4
 
5
- const funcRegex = /(\w+)\s*\(((?:[^()]+)*)?\s*\)\s*/
5
+ // Legacy regex patterns (can't handle nested parentheses properly)
6
+ const funcRegexSimple = /(\w+)\s*\(((?:[^()]+)*)?\s*\)\s*/
6
7
  const funcStartOfLineRegex = /^(\w+)\s*\(((?:[^()]+)*)?\s*\)\s*/
7
8
  const subFunctionRegex = /(\w+):(\w+)\s*\(((?:[^()]+)*)?\s*\)\s*/
8
9
 
10
+ /**
11
+ * Parse a function call with balanced parentheses support
12
+ * Returns a regex-exec-like array: [fullMatch, funcName, args] with index and input properties
13
+ * or null if no function found
14
+ * @param {string} str - String to search for function call
15
+ * @returns {any} Regex-like result array or null
16
+ */
17
+ function parseFunctionCall(str) {
18
+ if (!str || typeof str !== 'string') return null
19
+
20
+ // Find function name followed by opening paren
21
+ const funcMatch = str.match(/(\w+)\s*\(/)
22
+ if (!funcMatch) return null
23
+
24
+ const funcName = funcMatch[1]
25
+ const openParenIndex = funcMatch.index + funcMatch[0].length - 1
26
+ const startPos = openParenIndex + 1
27
+
28
+ let depth = 1
29
+ let pos = startPos
30
+
31
+ // Track parenthesis depth to find matching closing paren
32
+ while (pos < str.length && depth > 0) {
33
+ const char = str[pos]
34
+ if (char === '(') depth++
35
+ else if (char === ')') depth--
36
+ pos++
37
+ }
38
+
39
+ if (depth !== 0) return null // Unbalanced parens
40
+
41
+ const args = str.substring(startPos, pos - 1).trim()
42
+
43
+ // Skip trailing whitespace for fullMatch
44
+ let endPos = pos
45
+ while (endPos < str.length && /\s/.test(str[endPos])) {
46
+ endPos++
47
+ }
48
+
49
+ const fullMatch = str.substring(funcMatch.index, endPos)
50
+
51
+ // Create regex-exec-like result array with index and input properties
52
+ /** @type {any} */
53
+ const result = [fullMatch, funcName, args || undefined]
54
+ result.index = funcMatch.index
55
+ result.input = str
56
+ return result
57
+ }
58
+
59
+ /**
60
+ * Enhanced funcRegex that handles nested parentheses
61
+ * Mimics RegExp interface with exec() method
62
+ */
63
+ const funcRegex = {
64
+ exec: parseFunctionCall,
65
+ test: (str) => parseFunctionCall(str) !== null,
66
+ // Keep source for compatibility (shows what pattern we're conceptually matching)
67
+ source: '(\\w+)\\s*\\((.*)\\)\\s*',
68
+ toString: () => '/(\\w+)\\s*\\((.*)\\)\\s*/'
69
+ }
70
+
9
71
  /**
10
72
  * Combine multiple regex patterns into single OR pattern
11
73
  * @param {RegExp[]} regexes - Array of regex patterns to combine
@@ -18,9 +80,11 @@ function combineRegexes(regexes) {
18
80
 
19
81
  module.exports = {
20
82
  funcRegex,
83
+ funcRegexSimple,
21
84
  funcStartOfLineRegex,
22
85
  subFunctionRegex,
23
86
  combineRegexes,
87
+ parseFunctionCall,
24
88
  // Keep old export name for backwards compat
25
89
  functionRegex: funcRegex
26
90
  }
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Tests for regex utilities - especially funcRegex with nested parentheses
3
+ */
4
+ const { test } = require('uvu')
5
+ const assert = require('uvu/assert')
6
+ const { funcRegex, parseFunctionCall } = require('./index')
7
+
8
+ // ==========================================
9
+ // parseFunctionCall - basic functionality
10
+ // ==========================================
11
+
12
+ test('parseFunctionCall - simple function with no args', () => {
13
+ const result = parseFunctionCall('myFunc()')
14
+ assert.ok(result)
15
+ assert.is(result[1], 'myFunc')
16
+ assert.is(result[2], undefined)
17
+ })
18
+
19
+ test('parseFunctionCall - simple function with string arg', () => {
20
+ const result = parseFunctionCall("help('some text')")
21
+ assert.ok(result)
22
+ assert.is(result[1], 'help')
23
+ assert.is(result[2], "'some text'")
24
+ })
25
+
26
+ test('parseFunctionCall - function with multiple args', () => {
27
+ const result = parseFunctionCall("merge('a', 'b')")
28
+ assert.ok(result)
29
+ assert.is(result[1], 'merge')
30
+ assert.is(result[2], "'a', 'b'")
31
+ })
32
+
33
+ test('parseFunctionCall - returns null for non-function string', () => {
34
+ const result = parseFunctionCall('not a function')
35
+ assert.is(result, null)
36
+ })
37
+
38
+ test('parseFunctionCall - returns null for null input', () => {
39
+ const result = parseFunctionCall(null)
40
+ assert.is(result, null)
41
+ })
42
+
43
+ test('parseFunctionCall - returns null for undefined input', () => {
44
+ const result = parseFunctionCall(undefined)
45
+ assert.is(result, null)
46
+ })
47
+
48
+ // ==========================================
49
+ // parseFunctionCall - nested parentheses (bug fix)
50
+ // ==========================================
51
+
52
+ test('parseFunctionCall - handles parentheses in text argument', () => {
53
+ const result = parseFunctionCall("help('Deployment stage (dev, staging, prod)')")
54
+ assert.ok(result)
55
+ assert.is(result[1], 'help')
56
+ assert.is(result[2], "'Deployment stage (dev, staging, prod)'")
57
+ })
58
+
59
+ test('parseFunctionCall - handles nested function calls', () => {
60
+ const result = parseFunctionCall('outer(inner(arg))')
61
+ assert.ok(result)
62
+ assert.is(result[1], 'outer')
63
+ assert.is(result[2], 'inner(arg)')
64
+ })
65
+
66
+ test('parseFunctionCall - handles multiple nested function args', () => {
67
+ const result = parseFunctionCall('merge(func1(a), func2(b))')
68
+ assert.ok(result)
69
+ assert.is(result[1], 'merge')
70
+ assert.is(result[2], 'func1(a), func2(b)')
71
+ })
72
+
73
+ test('parseFunctionCall - handles deeply nested parentheses', () => {
74
+ const result = parseFunctionCall('a(b(c(d)))')
75
+ assert.ok(result)
76
+ assert.is(result[1], 'a')
77
+ assert.is(result[2], 'b(c(d))')
78
+ })
79
+
80
+ test('parseFunctionCall - handles complex help text with variables', () => {
81
+ const result = parseFunctionCall("help('Deployment stage (${allowedValues}, funky)')")
82
+ assert.ok(result)
83
+ assert.is(result[1], 'help')
84
+ assert.is(result[2], "'Deployment stage (${allowedValues}, funky)'")
85
+ })
86
+
87
+ test('parseFunctionCall - handles multiple parens in text', () => {
88
+ const result = parseFunctionCall("help('Choose option (A) or (B) or (C)')")
89
+ assert.ok(result)
90
+ assert.is(result[1], 'help')
91
+ assert.is(result[2], "'Choose option (A) or (B) or (C)'")
92
+ })
93
+
94
+ // ==========================================
95
+ // parseFunctionCall - edge cases
96
+ // ==========================================
97
+
98
+ test('parseFunctionCall - handles whitespace around args', () => {
99
+ const result = parseFunctionCall('func( arg )')
100
+ assert.ok(result)
101
+ assert.is(result[1], 'func')
102
+ assert.is(result[2], 'arg')
103
+ })
104
+
105
+ test('parseFunctionCall - handles whitespace before opening paren', () => {
106
+ const result = parseFunctionCall('func (arg)')
107
+ assert.ok(result)
108
+ assert.is(result[1], 'func')
109
+ assert.is(result[2], 'arg')
110
+ })
111
+
112
+ test('parseFunctionCall - returns null for unbalanced open paren', () => {
113
+ const result = parseFunctionCall('func((arg)')
114
+ assert.is(result, null)
115
+ })
116
+
117
+ test('parseFunctionCall - handles function in middle of string', () => {
118
+ const result = parseFunctionCall('prefix func(arg) suffix')
119
+ assert.ok(result)
120
+ assert.is(result[1], 'func')
121
+ assert.is(result[2], 'arg')
122
+ })
123
+
124
+ test('parseFunctionCall - includes index property', () => {
125
+ const result = parseFunctionCall('prefix func(arg)')
126
+ assert.ok(result)
127
+ assert.is(result.index, 7) // "prefix " is 7 chars
128
+ })
129
+
130
+ test('parseFunctionCall - includes input property', () => {
131
+ const input = 'func(arg)'
132
+ const result = parseFunctionCall(input)
133
+ assert.ok(result)
134
+ assert.is(result.input, input)
135
+ })
136
+
137
+ // ==========================================
138
+ // funcRegex.exec - same interface as RegExp
139
+ // ==========================================
140
+
141
+ test('funcRegex.exec - works like RegExp.exec', () => {
142
+ const result = funcRegex.exec("help('text')")
143
+ assert.ok(result)
144
+ assert.is(result[1], 'help')
145
+ assert.is(result[2], "'text'")
146
+ })
147
+
148
+ test('funcRegex.exec - handles nested parens', () => {
149
+ const result = funcRegex.exec("outer(inner(x))")
150
+ assert.ok(result)
151
+ assert.is(result[1], 'outer')
152
+ assert.is(result[2], 'inner(x)')
153
+ })
154
+
155
+ test('funcRegex.test - returns true for function', () => {
156
+ assert.is(funcRegex.test('func()'), true)
157
+ })
158
+
159
+ test('funcRegex.test - returns false for non-function', () => {
160
+ assert.is(funcRegex.test('not a function'), false)
161
+ })
162
+
163
+ // ==========================================
164
+ // Real-world examples from codebase
165
+ // ==========================================
166
+
167
+ test('real-world: split function', () => {
168
+ const result = funcRegex.exec("split('hello,world', ',')")
169
+ assert.ok(result)
170
+ assert.is(result[1], 'split')
171
+ assert.is(result[2], "'hello,world', ','")
172
+ })
173
+
174
+ test('real-world: merge function', () => {
175
+ const result = funcRegex.exec("merge('stuff', 'new')")
176
+ assert.ok(result)
177
+ assert.is(result[1], 'merge')
178
+ assert.is(result[2], "'stuff', 'new'")
179
+ })
180
+
181
+ test('real-world: nested split(merge())', () => {
182
+ const result = funcRegex.exec("split(merge('a', 'b'), ',')")
183
+ assert.ok(result)
184
+ assert.is(result[1], 'split')
185
+ assert.is(result[2], "merge('a', 'b'), ','")
186
+ })
187
+
188
+ test('real-world: git remote', () => {
189
+ const result = funcRegex.exec("remote('origin')")
190
+ assert.ok(result)
191
+ assert.is(result[1], 'remote')
192
+ assert.is(result[2], "'origin'")
193
+ })
194
+
195
+ test.run()
@@ -20,6 +20,10 @@ module.exports = function formatArgs(args) {
20
20
  return formatArg(args)
21
21
  }
22
22
  return args.map((arg) => {
23
+ // Skip formatting for non-string args (e.g., arrays/objects from nested function calls)
24
+ if (typeof arg !== 'string') {
25
+ return arg
26
+ }
23
27
  return formatArg(arg)
24
28
  })
25
29
  }
@@ -4,7 +4,7 @@ const { splitByComma } = require('./splitByComma')
4
4
  const VARIABLE_SYNTAX = /\${[^}]+}/g
5
5
 
6
6
  /**
7
- * Split a string by comma while preserving quoted content
7
+ * Split a string by delimiter while preserving quoted content and balanced parentheses
8
8
  * NOTE: This is a simpler version that delegates to splitByComma for consistency.
9
9
  * For advanced use cases with bracket depth tracking and regex protection, use splitByComma directly.
10
10
  * @param {string} str - String to split
@@ -14,26 +14,53 @@ const VARIABLE_SYNTAX = /\${[^}]+}/g
14
14
  * @returns {string[]} Array of split strings
15
15
  */
16
16
  function splitCsv(str, splitter, options = {}) {
17
- // If custom splitter is provided, fall back to original simple implementation
17
+ // If custom splitter is provided, use implementation with parenthesis tracking
18
18
  if (splitter && splitter !== ',') {
19
- const splitSyntax = splitter
20
- return str.split(splitSyntax).reduce(
21
- (acc, curr) => {
22
- if (acc.isConcatting) {
23
- acc.soFar[acc.soFar.length - 1] += splitter + curr
24
- } else {
25
- acc.soFar.push(curr)
19
+ const result = []
20
+ let current = ''
21
+ let inQuote = false
22
+ let quoteChar = ''
23
+ let parenDepth = 0
24
+ let bracketDepth = 0
25
+
26
+ for (let i = 0; i < str.length; i++) {
27
+ const char = str[i]
28
+
29
+ // Handle quotes
30
+ if ((char === "'" || char === '"') && (i === 0 || str[i-1] !== '\\')) {
31
+ if (!inQuote) {
32
+ inQuote = true
33
+ quoteChar = char
34
+ } else if (char === quoteChar) {
35
+ inQuote = false
26
36
  }
27
- if (curr.split('"').length % 2 == 0) {
28
- acc.isConcatting = !acc.isConcatting
29
- }
30
- return acc
31
- },
32
- {
33
- soFar: [],
34
- isConcatting: false,
35
- },
36
- ).soFar
37
+ }
38
+
39
+ // Handle parentheses and brackets (only outside quotes)
40
+ if (!inQuote) {
41
+ if (char === '(') parenDepth++
42
+ else if (char === ')') parenDepth--
43
+ else if (char === '[') bracketDepth++
44
+ else if (char === ']') bracketDepth--
45
+ }
46
+
47
+ // Check if we're at a splitter position
48
+ const atSplitter = str.substring(i, i + splitter.length) === splitter
49
+
50
+ if (atSplitter && !inQuote && parenDepth === 0 && bracketDepth === 0) {
51
+ result.push(current.trim())
52
+ current = ''
53
+ i += splitter.length - 1 // Skip rest of splitter
54
+ } else {
55
+ current += char
56
+ }
57
+ }
58
+
59
+ if (current.trim() || result.length > 0) {
60
+ result.push(current.trim())
61
+ }
62
+
63
+ return result
37
64
  }
38
65
 
39
66
  // For standard comma splitting, use the more robust splitByComma
@@ -1 +1 @@
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
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/main.js"],"names":[],"mappings":";AA0GA;IACE,0CA6bC;IArbC,cAcW;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;IAwED,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,CA6gBxB;IACD,+EA+BC;IACD,yDAeC;IACD,oEA6BC;IAKD,8CAQC;IACD,kDAyBC;IACD;;;;;;;;;;;;;OAaG;IACH,wEAoDC;IAKD,4BAOC;IACD,sCA2DC;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,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"}
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,CAiUxB;AA3WD;;;;;GAKG;AACH,2CAJW,MAAM,YACN,MAAM,GACJ,GAAC,CAoBb;AAqVD;;;;;;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"}
@@ -3,6 +3,7 @@ declare class PromiseTracker {
3
3
  reset(): void;
4
4
  promiseList: any[];
5
5
  promiseMap: {};
6
+ dependencyGraph: {};
6
7
  startTime: number;
7
8
  cursor: number;
8
9
  start(): void;
@@ -12,6 +13,9 @@ declare class PromiseTracker {
12
13
  add(variable: any, promise: any, specifier: any, hasFilter: any, promiseKey: any): any;
13
14
  contains(variable: any): boolean;
14
15
  get(variable: any, specifier: any): any;
16
+ addDependency(from: any, to: any): void;
17
+ wouldCreateCycle(from: any, to: any): boolean;
18
+ getCyclePath(from: any, to: any): any[];
15
19
  getPending(): any[];
16
20
  getSettled(): any[];
17
21
  getAll(): any[];
@@ -1 +1 @@
1
- {"version":3,"file":"PromiseTracker.d.ts","sourceRoot":"","sources":["../../../src/utils/PromiseTracker.js"],"names":[],"mappings":";AAGA;IAIE,cAKC;IAJC,mBAAqB;IACrB,eAAoB;IACpB,kBAA2B;IAC3B,eAAe;IAEjB,cAGC;IADC,yBAAyD;IAE3D,eAqBC;IACD,aAGC;IACD,uFA+BC;IACD,iCAEC;IACD,wCAIC;IACD,oBAEC;IACD,oBAEC;IACD,gBAEC;CACF"}
1
+ {"version":3,"file":"PromiseTracker.d.ts","sourceRoot":"","sources":["../../../src/utils/PromiseTracker.js"],"names":[],"mappings":";AAGA;IAIE,cAOC;IANC,mBAAqB;IACrB,eAAoB;IAEpB,oBAAyB;IACzB,kBAA2B;IAC3B,eAAe;IAEjB,cAGC;IADC,yBAAyD;IAE3D,eAqBC;IACD,aAGC;IACD,uFA+BC;IACD,iCAEC;IACD,wCAIC;IAED,wCAKC;IAED,8CAqBC;IAED,wCAoBC;IACD,oBAEC;IACD,oBAEC;IACD,gBAEC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"lodash.d.ts","sourceRoot":"","sources":["../../../src/utils/lodash.js"],"names":[],"mappings":"AAiDA,mDAoBC;AAnDD,6DA4BC"}
1
+ {"version":3,"file":"lodash.d.ts","sourceRoot":"","sources":["../../../src/utils/lodash.js"],"names":[],"mappings":"AAkDA,mDAoBC;AApDD,6DA6BC"}
@@ -1 +1 @@
1
- {"version":3,"file":"mergeByKeys.d.ts","sourceRoot":"","sources":["../../../../src/utils/parsing/mergeByKeys.js"],"names":[],"mappings":"AAAA;;GAEG;AACH,yEAwBC"}
1
+ {"version":3,"file":"mergeByKeys.d.ts","sourceRoot":"","sources":["../../../../src/utils/parsing/mergeByKeys.js"],"names":[],"mappings":"AAAA;;GAEG;AACH,yEAyBC"}
@@ -1 +1 @@
1
- {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../../../src/utils/parsing/parse.js"],"names":[],"mappings":";;;;cAec,MAAM;;;;cACN,MAAM;;;;eACN,MAAM;;;;kBACN,cAAe;;;;;;eAkGf,MAAM;;;;kBACN,cAAe;;AAxG7B;;;;;;GAMG;AAEH;;;;GAIG;AACH,iFAHW,YAAY,OAyFtB;AAED;;;;GAIG;AAEH;;;;;GAKG;AACH,oCAJW,MAAM,SACN,gBAAgB,OAW1B"}
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../../../src/utils/parsing/parse.js"],"names":[],"mappings":";;;;cAec,MAAM;;;;cACN,MAAM;;;;eACN,MAAM;;;;kBACN,cAAe;;;;;;eAqGf,MAAM;;;;kBACN,cAAe;;AA3G7B;;;;;;GAMG;AAEH;;;;GAIG;AACH,iFAHW,YAAY,OA4FtB;AAED;;;;GAIG;AAEH;;;;;GAKG;AACH,oCAJW,MAAM,SACN,gBAAgB,OAW1B"}
@@ -1,7 +1,13 @@
1
+ export namespace funcRegex {
2
+ export { parseFunctionCall as exec };
3
+ export function test(str: any): boolean;
4
+ export let source: string;
5
+ export function toString(): string;
6
+ }
1
7
  /**
2
8
  * Shared regex patterns and utilities
3
9
  */
4
- export const funcRegex: RegExp;
10
+ export const funcRegexSimple: RegExp;
5
11
  export const funcStartOfLineRegex: RegExp;
6
12
  export const subFunctionRegex: RegExp;
7
13
  /**
@@ -10,5 +16,13 @@ export const subFunctionRegex: RegExp;
10
16
  * @returns {RegExp} Combined regex with OR operator
11
17
  */
12
18
  export function combineRegexes(regexes: RegExp[]): RegExp;
19
+ /**
20
+ * Parse a function call with balanced parentheses support
21
+ * Returns a regex-exec-like array: [fullMatch, funcName, args] with index and input properties
22
+ * or null if no function found
23
+ * @param {string} str - String to search for function call
24
+ * @returns {any} Regex-like result array or null
25
+ */
26
+ export function parseFunctionCall(str: string): any;
13
27
  export { funcRegex as functionRegex };
14
28
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/regex/index.js"],"names":[],"mappings":"AAAA;;GAEG;AAEH,+BAAoD;AACpD,0CAAgE;AAChE,sCAAiE;AAEjE;;;;GAIG;AACH,wCAHW,MAAM,EAAE,GACN,MAAM,CAKlB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/regex/index.js"],"names":[],"mappings":";;IAgEQ,wCAAwC;;IAGpC,mCAAkC;;AAnE9C;;GAEG;AAGH,qCAA0D;AAC1D,0CAAgE;AAChE,sCAAiE;AA+DjE;;;;GAIG;AACH,wCAHW,MAAM,EAAE,GACN,MAAM,CAKlB;AArED;;;;;;GAMG;AACH,uCAHW,MAAM,GACJ,GAAG,CA0Cf"}
@@ -1 +1 @@
1
- {"version":3,"file":"formatFunctionArgs.d.ts","sourceRoot":"","sources":["../../../../src/utils/strings/formatFunctionArgs.js"],"names":[],"mappings":"AAiBiB,0CAOhB"}
1
+ {"version":3,"file":"formatFunctionArgs.d.ts","sourceRoot":"","sources":["../../../../src/utils/strings/formatFunctionArgs.js"],"names":[],"mappings":"AAiBiB,0CAWhB"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Split a string by comma while preserving quoted content
2
+ * Split a string by delimiter while preserving quoted content and balanced parentheses
3
3
  * NOTE: This is a simpler version that delegates to splitByComma for consistency.
4
4
  * For advanced use cases with bracket depth tracking and regex protection, use splitByComma directly.
5
5
  * @param {string} str - String to split
@@ -1 +1 @@
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"}
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,CA0DpB"}