mirror of
https://github.com/n8n-io/n8n.git
synced 2026-10-17 05:29:44 +02:00
fix(core): Hand node reference results without an item shape to the engine (no-changelog) (#41083)
This commit is contained in:
parent
d0cb582163
commit
1b02863c00
|
|
@ -508,11 +508,19 @@ function evalNodeRefCall(proxy: unknown, method: string, env: Env): unknown {
|
|||
if (typeof fn !== 'function') throw new EngineFallbackError();
|
||||
|
||||
const result = bounded(fn.call(proxy));
|
||||
|
||||
// A node name that is an Object.prototype key resolves through a plain
|
||||
// object lookup on the host. Only the item shapes stay native.
|
||||
const expected = method === 'all' ? isArray(result) : result === undefined || isItem(result);
|
||||
if (!expected) throw new EngineFallbackError();
|
||||
|
||||
env.charge(isArray(result) ? result.length : 1);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const isItem = (value: unknown): boolean => isObj(value) && !isArray(value);
|
||||
|
||||
/**
|
||||
* A captured Luxon getter or zero-argument method on `$now`/`$today`. The
|
||||
* root is the proxy's own DateTime (anything else is the engine's), and the
|
||||
|
|
|
|||
|
|
@ -731,6 +731,32 @@ describe('Expression - fast native evaluation parity', () => {
|
|||
expect(nativeOn(expr, visits(fits + 2))).toEqual({ handled: false });
|
||||
expect(nativeOn(expr, visits(fits))).toEqual({ handled: true, value: false });
|
||||
});
|
||||
|
||||
// `$('hasOwnProperty')` resolves through a plain object lookup on the
|
||||
// host and hands back Object.prototype.hasOwnProperty, not item data.
|
||||
test('a node reference call that returns no item shape hands off to the engine', () => {
|
||||
const { hasOwnProperty } = Object.prototype;
|
||||
const prototypeNode = {
|
||||
$: () => ({ all: () => hasOwnProperty, first: () => hasOwnProperty }),
|
||||
};
|
||||
expect(nativeOn("{{ $('hasOwnProperty').all().name }}", prototypeNode)).toEqual({
|
||||
handled: false,
|
||||
});
|
||||
expect(nativeOn("{{ $('hasOwnProperty').first() }}", prototypeNode)).toEqual({
|
||||
handled: false,
|
||||
});
|
||||
const item = { json: { a: 1 } };
|
||||
const node = { $: () => ({ all: () => [item], first: () => item, last: () => undefined }) };
|
||||
expect(nativeOn("{{ $('Source').all().length }}", node)).toEqual({ handled: true, value: 1 });
|
||||
expect(nativeOn("{{ $('Source').first().json.a }}", node)).toEqual({
|
||||
handled: true,
|
||||
value: 1,
|
||||
});
|
||||
expect(nativeOn("{{ $('Source').last() }}", node)).toEqual({
|
||||
handled: true,
|
||||
value: undefined,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// extendSyntax rewrites calls to extension-named methods into extend()
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user