mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-21 02:56:40 -08:00
fix(core): amend typing for jsonParse()
options (#4423)
* 📘 Amend typing for `jsonParse()` options * ✏️ Update rule message and description * 🔀 Cherrypick Adi's work * 🐛 Account for falsy fallback values * ♻️ Use `else if` * ⚡ Add explicit error message as type * ⚡ Consolidate utils tests * ♻️ Use optional chaining * 🔥 Remove patchy type error Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <aditya@netroy.in>
This commit is contained in:
parent
d7c8fefe19
commit
1732324965
|
@ -30,12 +30,14 @@ module.exports = {
|
|||
meta: {
|
||||
type: 'problem',
|
||||
docs: {
|
||||
description: 'Calls to JSON.parse() must be surrounded with a try/catch block.',
|
||||
description:
|
||||
'Calls to `JSON.parse()` must be replaced with `jsonParse()` from `n8n-workflow` or surrounded with a try/catch block.',
|
||||
recommended: 'error',
|
||||
},
|
||||
schema: [],
|
||||
messages: {
|
||||
noUncaughtJsonParse: 'Surround the JSON.parse() call with a try/catch block.',
|
||||
noUncaughtJsonParse:
|
||||
'Use `jsonParse()` from `n8n-workflow` or surround the `JSON.parse()` call with a try/catch block.',
|
||||
},
|
||||
},
|
||||
defaultOptions: [],
|
||||
|
|
|
@ -30,22 +30,23 @@ export const deepCopy = <T>(source: T): T => {
|
|||
return clone;
|
||||
};
|
||||
// eslint-enable
|
||||
type ErrorMessage = { errorMessage: string };
|
||||
type FallbackValue<T> = { fallbackValue: T };
|
||||
|
||||
export const jsonParse = <T>(
|
||||
jsonString: string,
|
||||
options: ErrorMessage | FallbackValue<T> | {} = {},
|
||||
): T => {
|
||||
type MutuallyExclusive<T, U> =
|
||||
| (T & { [k in Exclude<keyof U, keyof T>]?: never })
|
||||
| (U & { [k in Exclude<keyof T, keyof U>]?: never });
|
||||
|
||||
type JSONParseOptions<T> = MutuallyExclusive<{ errorMessage: string }, { fallbackValue: T }>;
|
||||
|
||||
export const jsonParse = <T>(jsonString: string, options?: JSONParseOptions<T>): T => {
|
||||
try {
|
||||
return JSON.parse(jsonString) as T;
|
||||
} catch (error) {
|
||||
if ('fallbackValue' in options) {
|
||||
if (options?.fallbackValue !== undefined) {
|
||||
return options.fallbackValue;
|
||||
}
|
||||
if ('errorMessage' in options) {
|
||||
} else if (options?.errorMessage) {
|
||||
throw new Error(options.errorMessage);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,4 +1,21 @@
|
|||
import { deepCopy } from './utils';
|
||||
import { jsonParse, deepCopy } from '../src/utils';
|
||||
|
||||
describe('jsonParse', () => {
|
||||
it('parses JSON', () => {
|
||||
expect(jsonParse('[1, 2, 3]')).toEqual([1, 2, 3]);
|
||||
expect(jsonParse('{ "a": 1 }')).toEqual({ a: 1 });
|
||||
});
|
||||
|
||||
it('optionally throws `errorMessage', () => {
|
||||
expect(() => {
|
||||
jsonParse('', { errorMessage: 'Invalid JSON' });
|
||||
}).toThrow('Invalid JSON');
|
||||
});
|
||||
|
||||
it('optionally returns a `fallbackValue`', () => {
|
||||
expect(jsonParse('', { fallbackValue: { foo: 'bar' } })).toEqual({ foo: 'bar' });
|
||||
});
|
||||
});
|
||||
|
||||
describe('deepCopy', () => {
|
||||
it('should deep copy an object', () => {
|
Loading…
Reference in a new issue