@curl-runner/cli 1.5.0 → 1.6.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@curl-runner/cli",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "A powerful CLI tool for HTTP request management using YAML configuration",
5
5
  "type": "module",
6
6
  "main": "./dist/cli.js",
@@ -175,6 +175,84 @@ describe('YamlParser.resolveVariable', () => {
175
175
  });
176
176
  });
177
177
 
178
+ describe('YamlParser string transforms', () => {
179
+ test('should transform variable to uppercase with :upper', () => {
180
+ const variables = { ENV: 'production' };
181
+ const result = YamlParser.resolveVariable('ENV:upper', variables, {});
182
+ expect(result).toBe('PRODUCTION');
183
+ });
184
+
185
+ test('should transform variable to lowercase with :lower', () => {
186
+ const variables = { RESOURCE: 'USERS' };
187
+ const result = YamlParser.resolveVariable('RESOURCE:lower', variables, {});
188
+ expect(result).toBe('users');
189
+ });
190
+
191
+ test('should return null for transform on missing variable', () => {
192
+ const result = YamlParser.resolveVariable('MISSING:upper', {}, {});
193
+ expect(result).toBeNull();
194
+ });
195
+
196
+ test('should work with interpolateVariables for :upper transform', () => {
197
+ const obj = {
198
+ headers: {
199
+ // biome-ignore lint/suspicious/noTemplateCurlyInString: Testing string transform
200
+ 'X-Environment': '${ENV:upper}',
201
+ },
202
+ };
203
+ const variables = { ENV: 'production' };
204
+ const result = YamlParser.interpolateVariables(obj, variables);
205
+ expect(result).toEqual({
206
+ headers: {
207
+ 'X-Environment': 'PRODUCTION',
208
+ },
209
+ });
210
+ });
211
+
212
+ test('should work with interpolateVariables for :lower transform', () => {
213
+ const obj = {
214
+ headers: {
215
+ // biome-ignore lint/suspicious/noTemplateCurlyInString: Testing string transform
216
+ 'X-Resource': '${RESOURCE:lower}',
217
+ },
218
+ };
219
+ const variables = { RESOURCE: 'USERS' };
220
+ const result = YamlParser.interpolateVariables(obj, variables);
221
+ expect(result).toEqual({
222
+ headers: {
223
+ 'X-Resource': 'users',
224
+ },
225
+ });
226
+ });
227
+
228
+ test('should mix transforms with regular variables', () => {
229
+ const obj = {
230
+ // biome-ignore lint/suspicious/noTemplateCurlyInString: Testing string transform
231
+ url: '${BASE_URL}/${RESOURCE:lower}',
232
+ headers: {
233
+ // biome-ignore lint/suspicious/noTemplateCurlyInString: Testing string transform
234
+ 'X-Environment': '${ENV:upper}',
235
+ },
236
+ };
237
+ const variables = { BASE_URL: 'https://api.example.com', RESOURCE: 'Users', ENV: 'staging' };
238
+ const result = YamlParser.interpolateVariables(obj, variables);
239
+ expect(result).toEqual({
240
+ url: 'https://api.example.com/users',
241
+ headers: {
242
+ 'X-Environment': 'STAGING',
243
+ },
244
+ });
245
+ });
246
+
247
+ test('should keep unresolved transforms as-is', () => {
248
+ // biome-ignore lint/suspicious/noTemplateCurlyInString: Testing string transform
249
+ const obj = { value: '${MISSING:upper}' };
250
+ const result = YamlParser.interpolateVariables(obj, {});
251
+ // biome-ignore lint/suspicious/noTemplateCurlyInString: Testing string transform
252
+ expect(result).toEqual({ value: '${MISSING:upper}' });
253
+ });
254
+ });
255
+
178
256
  describe('YamlParser.resolveVariable with default values', () => {
179
257
  test('should use default value when variable is not set', () => {
180
258
  const result = YamlParser.resolveVariable('API_TIMEOUT:5000', {}, {});
@@ -189,17 +267,20 @@ describe('YamlParser.resolveVariable with default values', () => {
189
267
 
190
268
  test('should handle nested default with first variable set', () => {
191
269
  const variables = { DATABASE_HOST: 'prod-db.example.com' };
270
+ // biome-ignore lint/suspicious/noTemplateCurlyInString: Testing variable interpolation
192
271
  const result = YamlParser.resolveVariable('DATABASE_HOST:${DB_HOST:localhost}', variables, {});
193
272
  expect(result).toBe('prod-db.example.com');
194
273
  });
195
274
 
196
275
  test('should handle nested default with second variable set', () => {
197
276
  const variables = { DB_HOST: 'staging-db.example.com' };
277
+ // biome-ignore lint/suspicious/noTemplateCurlyInString: Testing variable interpolation
198
278
  const result = YamlParser.resolveVariable('DATABASE_HOST:${DB_HOST:localhost}', variables, {});
199
279
  expect(result).toBe('staging-db.example.com');
200
280
  });
201
281
 
202
282
  test('should use final fallback when no variables are set', () => {
283
+ // biome-ignore lint/suspicious/noTemplateCurlyInString: Testing variable interpolation
203
284
  const result = YamlParser.resolveVariable('DATABASE_HOST:${DB_HOST:localhost}', {}, {});
204
285
  expect(result).toBe('localhost');
205
286
  });
@@ -39,7 +39,11 @@ export class YamlParser {
39
39
  }
40
40
 
41
41
  // Check if it's a single variable that spans the entire string
42
- if (extractedVars.length === 1 && extractedVars[0].start === 0 && extractedVars[0].end === obj.length) {
42
+ if (
43
+ extractedVars.length === 1 &&
44
+ extractedVars[0].start === 0 &&
45
+ extractedVars[0].end === obj.length
46
+ ) {
43
47
  const varName = extractedVars[0].name;
44
48
  const resolvedValue = YamlParser.resolveVariable(varName, variables, storeContext);
45
49
  return resolvedValue !== null ? resolvedValue : obj;
@@ -75,7 +79,7 @@ export class YamlParser {
75
79
 
76
80
  /**
77
81
  * Resolves a single variable reference.
78
- * Priority: store context > dynamic variables > static variables > default values
82
+ * Priority: store context > string transforms > dynamic variables > static variables > default values
79
83
  */
80
84
  static resolveVariable(
81
85
  varName: string,
@@ -91,6 +95,19 @@ export class YamlParser {
91
95
  return null; // Store variable not found, return null to keep original
92
96
  }
93
97
 
98
+ // Check for string transforms: ${VAR:upper} or ${VAR:lower}
99
+ const transformMatch = varName.match(/^([^:]+):(upper|lower)$/);
100
+ if (transformMatch) {
101
+ const baseVarName = transformMatch[1];
102
+ const transform = transformMatch[2];
103
+ const baseValue = variables[baseVarName] || process.env[baseVarName];
104
+
105
+ if (baseValue) {
106
+ return transform === 'upper' ? baseValue.toUpperCase() : baseValue.toLowerCase();
107
+ }
108
+ return null; // Base variable not found
109
+ }
110
+
94
111
  // Check for default value syntax: ${VAR:default}
95
112
  // Must check before dynamic variables to properly handle defaults
96
113
  const colonIndex = varName.indexOf(':');