Skip to content

Commit 05a2f66

Browse files
committed
feat: toString, toArray, & toNumber functions
1 parent 2486658 commit 05a2f66

File tree

4 files changed

+36
-34
lines changed

4 files changed

+36
-34
lines changed

packages/jmespath/src/Parser.ts

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ class Parser {
176176
lexPosition: 0,
177177
tokenValue: token.value,
178178
tokenType: token.type,
179-
reason: 'Quoted identifier cannot be used as a function name',
179+
reason: 'quoted identifiers cannot be used as a function name',
180180
});
181181
}
182182

@@ -247,7 +247,6 @@ class Parser {
247247
lexPosition: token.start,
248248
tokenValue: token.value,
249249
tokenType: token.type,
250-
reason: 'invalid token',
251250
});
252251
}
253252
}
@@ -354,7 +353,6 @@ class Parser {
354353
lexPosition: token.start,
355354
tokenValue: token.value,
356355
tokenType: token.type,
357-
reason: 'invalid token',
358356
});
359357
}
360358
}
@@ -402,7 +400,6 @@ class Parser {
402400
lexPosition: token.start,
403401
tokenValue: token.value,
404402
tokenType: token.type,
405-
reason: 'syntax error',
406403
});
407404
}
408405
this.#advance();
@@ -419,7 +416,6 @@ class Parser {
419416
lexPosition: token.start,
420417
tokenValue: token.value,
421418
tokenType: token.type,
422-
reason: 'syntax error',
423419
});
424420
}
425421
currentToken = this.#currentToken();
@@ -531,7 +527,6 @@ class Parser {
531527
lexPosition: token.start,
532528
tokenValue: token.value,
533529
tokenType: token.type,
534-
reason: 'syntax error',
535530
});
536531
}
537532

@@ -568,17 +563,10 @@ class Parser {
568563
return this.#parseMultiSelectHash();
569564
} else {
570565
const token = this.#lookaheadToken(0);
571-
const allowed = [
572-
'quoted_identifier',
573-
'unquoted_identifier',
574-
'lbracket',
575-
'lbrace',
576-
];
577566
throw new ParseError({
578567
lexPosition: token.start,
579568
tokenValue: token.value,
580569
tokenType: token.type,
581-
reason: `Expecting one of: ${allowed.join(', ')}, got: ${token.type}`,
582570
});
583571
}
584572
}
@@ -605,7 +593,6 @@ class Parser {
605593
lexPosition: token.start,
606594
tokenValue: token.value,
607595
tokenType: token.type,
608-
reason: `Expecting: ${tokenType}, got: ${token.type}`,
609596
});
610597
}
611598
}
@@ -631,7 +618,6 @@ class Parser {
631618
lexPosition: token.start,
632619
tokenValue: token.value,
633620
tokenType: token.type,
634-
reason: `Expecting: ${tokenTypes}, got: ${token.type}`,
635621
});
636622
}
637623
}

packages/jmespath/src/errors.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,9 @@ class ParseError extends JMESPathError {
9494
this.reason = options.reason;
9595

9696
// Set the message to include the lexer position and token info.
97-
const issue =
98-
this.tokenType === 'eof'
97+
const issue = this.reason
98+
? this.reason
99+
: this.tokenType === 'eof'
99100
? 'found unexpected end of expression (EOF)'
100101
: `found unexpected token "${this.tokenValue}" (${this.tokenType})`;
101102
this.message = `${this.message}: parse error at column ${this.lexPosition}, ${issue}`;

packages/jmespath/src/functions/Functions.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,9 @@ class Functions {
244244
* @param args The items to convert to an array
245245
* @returns The items as an array
246246
*/
247+
@Functions.signature({
248+
argumentsSpecs: [['any']],
249+
})
247250
public funcToArray(
248251
arg: JSONArray | Array<JSONValue>
249252
): Array<JSONValue> | JSONArray {
@@ -261,6 +264,9 @@ class Functions {
261264
* @param arg The value to convert to a number
262265
* @returns The value as a number or null if the value cannot be converted to a number
263266
*/
267+
@Functions.signature({
268+
argumentsSpecs: [['any']],
269+
})
264270
public funcToNumber(arg: JSONValue): number | null {
265271
if (typeof arg === 'number') {
266272
return arg;
@@ -282,6 +288,9 @@ class Functions {
282288
* @param arg The value to convert to a string
283289
* @returns The value as a string
284290
*/
291+
@Functions.signature({
292+
argumentsSpecs: [['any']],
293+
})
285294
public funcToString(arg: JSONValue): string {
286295
return typeof arg === 'string' ? arg : JSON.stringify(arg);
287296
}
@@ -292,18 +301,21 @@ class Functions {
292301
* @param arg The value to check the type of
293302
* @returns The type of the value
294303
*/
295-
public funcType(arg: Array<unknown>): string {
296-
if (Array.isArray(arg[0])) {
304+
@Functions.signature({
305+
argumentsSpecs: [['any']],
306+
})
307+
public funcType(arg: JSONValue): string {
308+
if (Array.isArray(arg)) {
297309
return 'array';
298-
} else if (isRecord(arg[0])) {
310+
} else if (isRecord(arg)) {
299311
return 'object';
300-
} else if (typeof arg[0] === 'string') {
312+
} else if (typeof arg === 'string') {
301313
return 'string';
302-
} else if (typeof arg[0] === 'number') {
314+
} else if (typeof arg === 'number') {
303315
return 'number';
304-
} else if (typeof arg[0] === 'boolean') {
316+
} else if (typeof arg === 'boolean') {
305317
return 'boolean';
306-
} else if (Object.is(arg[0], null)) {
318+
} else if (Object.is(arg, null)) {
307319
return 'null';
308320
} else {
309321
return 'unknown';

packages/jmespath/tests/unit/functions.test.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,7 +1301,7 @@ describe('Functions tests', () => {
13011301
expect(() => search(expression, data)).toThrow(error);
13021302
}); */
13031303

1304-
/* it.each([
1304+
it.each([
13051305
{
13061306
expression: `to_array('foo')`,
13071307
expected: ['foo'],
@@ -1352,9 +1352,9 @@ describe('Functions tests', () => {
13521352

13531353
// Assess
13541354
expect(result).toStrictEqual(expected);
1355-
}); */
1355+
});
13561356

1357-
/* it.each([
1357+
it.each([
13581358
{
13591359
expression: `to_string('foo')`,
13601360
expected: 'foo',
@@ -1397,8 +1397,9 @@ describe('Functions tests', () => {
13971397

13981398
// Assess
13991399
expect(result).toStrictEqual(expected);
1400-
}); */
1401-
/* it.each([
1400+
});
1401+
1402+
it.each([
14021403
{
14031404
expression: `to_number('1.0')`,
14041405
expected: 1.0,
@@ -1461,22 +1462,24 @@ describe('Functions tests', () => {
14611462

14621463
// Assess
14631464
expect(result).toStrictEqual(expected);
1464-
}); */
1465-
/* it.each([
1465+
});
1466+
1467+
it.each([
14661468
{
14671469
expression: '"to_string"(`1.0`)',
1468-
error: 'Quoted identifier not allowed for function names.',
1470+
error:
1471+
'Invalid jmespath expression: parse error at column 0, quoted identifiers cannot be used as a function name in expression: "to_string"(`1.0`)',
14691472
},
14701473
])('to_number() function errors', ({ expression, error }) => {
1471-
// TODO: see if we can assert the error type as well in to_number() errors tests
14721474
// Prepare
14731475
const data = {
14741476
type: 'object',
14751477
};
14761478

14771479
// Act & Assess
14781480
expect(() => search(expression, data)).toThrow(error);
1479-
}); */
1481+
});
1482+
14801483
/* it.each([
14811484
{
14821485
expression: 'not_null(unknown_key, str)',

0 commit comments

Comments
 (0)