mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-21 02:56:40 -08:00
fix: CodeNodeEditor walk cannot read properties of null (#11129)
Some checks are pending
Test Master / install-and-build (push) Waiting to run
Test Master / Unit tests (18.x) (push) Blocked by required conditions
Test Master / Unit tests (20.x) (push) Blocked by required conditions
Test Master / Unit tests (22.4) (push) Blocked by required conditions
Test Master / Lint (push) Blocked by required conditions
Test Master / Notify Slack on failure (push) Blocked by required conditions
Some checks are pending
Test Master / install-and-build (push) Waiting to run
Test Master / Unit tests (18.x) (push) Blocked by required conditions
Test Master / Unit tests (20.x) (push) Blocked by required conditions
Test Master / Unit tests (22.4) (push) Blocked by required conditions
Test Master / Lint (push) Blocked by required conditions
Test Master / Notify Slack on failure (push) Blocked by required conditions
Co-authored-by: Elias Meire <elias@meire.dev>
This commit is contained in:
parent
40dd02f360
commit
d99e0a7c97
|
@ -0,0 +1,44 @@
|
|||
import * as esprima from 'esprima-next';
|
||||
import { walk } from './utils';
|
||||
|
||||
describe('CodeNodeEditor utils', () => {
|
||||
describe('walk', () => {
|
||||
it('should find the correct syntax nodes', () => {
|
||||
const code = `const x = 'a'
|
||||
function f(arg) {
|
||||
arg['b'] = 1
|
||||
return arg
|
||||
}
|
||||
|
||||
const y = f({ a: 'c' })
|
||||
`;
|
||||
const program = esprima.parse(code);
|
||||
const stringLiterals = walk(
|
||||
program,
|
||||
(node) => node.type === esprima.Syntax.Literal && typeof node.value === 'string',
|
||||
);
|
||||
expect(stringLiterals).toEqual([
|
||||
new esprima.Literal('a', "'a'"),
|
||||
new esprima.Literal('b', "'b'"),
|
||||
new esprima.Literal('c', "'c'"),
|
||||
]);
|
||||
});
|
||||
|
||||
it('should handle null syntax nodes', () => {
|
||||
// ,, in [1,,2] results in a `null` ArrayExpressionElement
|
||||
const code = 'const fn = () => [1,,2]';
|
||||
const program = esprima.parse(code);
|
||||
const arrayExpressions = walk(
|
||||
program,
|
||||
(node) => node.type === esprima.Syntax.ArrayExpression,
|
||||
);
|
||||
expect(arrayExpressions).toEqual([
|
||||
new esprima.ArrayExpression([
|
||||
new esprima.Literal(1, '1'),
|
||||
null,
|
||||
new esprima.Literal(2, '2'),
|
||||
]),
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,29 +1,33 @@
|
|||
import type * as esprima from 'esprima-next';
|
||||
import * as esprima from 'esprima-next';
|
||||
import type { Completion } from '@codemirror/autocomplete';
|
||||
import type { Node } from 'estree';
|
||||
import type { RangeNode } from './types';
|
||||
import { sanitizeHtml } from '@/utils/htmlUtils';
|
||||
import type { Node } from 'estree';
|
||||
|
||||
export function walk<T extends RangeNode>(
|
||||
node: Node | esprima.Program,
|
||||
test: (node: Node) => boolean,
|
||||
found: Node[] = [],
|
||||
) {
|
||||
// @ts-ignore
|
||||
if (test(node)) found.push(node);
|
||||
const isProgram = node.type === esprima.Syntax.Program;
|
||||
if (!isProgram && test(node)) found.push(node);
|
||||
|
||||
for (const key in node) {
|
||||
if (!(key in node)) continue;
|
||||
if (isProgram) {
|
||||
node.body.forEach((n) => walk(n as Node, test, found));
|
||||
} else {
|
||||
for (const key in node) {
|
||||
if (!(key in node)) continue;
|
||||
|
||||
// @ts-ignore
|
||||
const child = node[key];
|
||||
// @ts-expect-error Node is not string indexable, but it has many possible properties
|
||||
const child = node[key];
|
||||
|
||||
if (child === null || typeof child !== 'object') continue;
|
||||
if (child === null || typeof child !== 'object') continue;
|
||||
|
||||
if (Array.isArray(child)) {
|
||||
child.forEach((node) => walk(node, test, found));
|
||||
} else {
|
||||
walk(child, test, found);
|
||||
if (Array.isArray(child)) {
|
||||
child.filter(Boolean).forEach((n) => walk(n, test, found));
|
||||
} else {
|
||||
walk(child, test, found);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue