mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
fix(editor): Drop mergeDeep in favor of lodash merge (#5943)
This commit is contained in:
parent
6cf74e412a
commit
0570514b78
|
@ -1,5 +1,6 @@
|
|||
<script lang="ts" setup>
|
||||
import { computed, ref } from 'vue';
|
||||
import { merge } from 'lodash-es';
|
||||
import { INodeUi, Schema } from '@/Interface';
|
||||
import RunDataSchemaItem from '@/components/RunDataSchemaItem.vue';
|
||||
import Draggable from '@/components/Draggable.vue';
|
||||
|
@ -8,7 +9,7 @@ import { useWebhooksStore } from '@/stores/webhooks';
|
|||
import { runExternalHook } from '@/mixins/externalHooks';
|
||||
import { telemetry } from '@/plugins/telemetry';
|
||||
import { IDataObject } from 'n8n-workflow';
|
||||
import { getSchema, isEmpty, mergeDeep } from '@/utils';
|
||||
import { getSchema, isEmpty } from '@/utils';
|
||||
import { i18n } from '@/plugins/i18n';
|
||||
import MappingPill from './MappingPill.vue';
|
||||
|
||||
|
@ -32,7 +33,7 @@ const webhooksStore = useWebhooksStore();
|
|||
|
||||
const schema = computed<Schema>(() => {
|
||||
const [head, ...tail] = props.data;
|
||||
return getSchema(mergeDeep([head, ...tail, head]));
|
||||
return getSchema(merge({}, head, ...tail, head));
|
||||
});
|
||||
|
||||
const isDataEmpty = computed(() => {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import jp from 'jsonpath';
|
||||
import { isEmpty, intersection, mergeDeep, getSchema, isValidDate } from '@/utils';
|
||||
import { isEmpty, intersection, getSchema, isValidDate } from '@/utils';
|
||||
import { Schema } from '@/Interface';
|
||||
|
||||
describe('Types Utils', () => {
|
||||
|
@ -43,180 +43,6 @@ describe('Types Utils', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('mergeDeep', () => {
|
||||
test.each([
|
||||
[
|
||||
[
|
||||
[1, 2],
|
||||
[3, 4],
|
||||
],
|
||||
{},
|
||||
[3, 4],
|
||||
],
|
||||
[
|
||||
[
|
||||
[1, 2],
|
||||
[3, 4],
|
||||
],
|
||||
{ concatArrays: true },
|
||||
[1, 2, 3, 4],
|
||||
],
|
||||
[
|
||||
[
|
||||
[1, 2],
|
||||
[3, 4],
|
||||
],
|
||||
{ overwriteArrays: true },
|
||||
[3, 4],
|
||||
],
|
||||
[
|
||||
[
|
||||
[1, 2, 3],
|
||||
[4, 5],
|
||||
],
|
||||
{},
|
||||
[4, 5, 3],
|
||||
],
|
||||
[
|
||||
[
|
||||
[1, 2, 3],
|
||||
[4, 5],
|
||||
],
|
||||
{ concatArrays: true },
|
||||
[1, 2, 3, 4, 5],
|
||||
],
|
||||
[
|
||||
[
|
||||
[1, 2, 3],
|
||||
[4, 5],
|
||||
],
|
||||
{ overwriteArrays: true },
|
||||
[4, 5],
|
||||
],
|
||||
[
|
||||
[
|
||||
[1, 2],
|
||||
[3, 4, 5],
|
||||
],
|
||||
{},
|
||||
[3, 4, 5],
|
||||
],
|
||||
[
|
||||
[
|
||||
[1, 2],
|
||||
[3, 4, 5],
|
||||
],
|
||||
{ concatArrays: true },
|
||||
[1, 2, 3, 4, 5],
|
||||
],
|
||||
[
|
||||
[
|
||||
[1, 2],
|
||||
[3, 4, 5],
|
||||
],
|
||||
{ overwriteArrays: true },
|
||||
[3, 4, 5],
|
||||
],
|
||||
[[{ a: 1, b: [1, 2, { d: 2 }] }, {}], {}, { a: 1, b: [1, 2, { d: 2 }] }],
|
||||
[[{ a: 1, b: [1, 2, { d: 2 }] }, {}], { concatArrays: true }, { a: 1, b: [1, 2, { d: 2 }] }],
|
||||
[
|
||||
[{ a: 1, b: [1, 2, { d: 2 }] }, {}],
|
||||
{ overwriteArrays: true },
|
||||
{ a: 1, b: [1, 2, { d: 2 }] },
|
||||
],
|
||||
[[[{ a: 1, b: [1, 2, { d: 2 }] }], []], {}, [{ a: 1, b: [1, 2, { d: 2 }] }]],
|
||||
[
|
||||
[[{ a: 1, b: [1, 2, { d: 2 }] }], []],
|
||||
{ concatArrays: true },
|
||||
[{ a: 1, b: [1, 2, { d: 2 }] }],
|
||||
],
|
||||
[[[{ a: 1, b: [1, 2, { d: 2 }] }], []], { overwriteArrays: true }, []],
|
||||
[
|
||||
[
|
||||
{ a: 1, b: [1, 2, 3] },
|
||||
{ a: 2, b: [4, 5, 6, 7], c: '2' },
|
||||
{ a: 3, b: [8, 9], d: '3' },
|
||||
],
|
||||
{},
|
||||
{ a: 3, b: [8, 9, 6, 7], c: '2', d: '3' },
|
||||
],
|
||||
[
|
||||
[
|
||||
{ a: 1, b: [1, 2, 3] },
|
||||
{ a: 2, b: [4, 5, 6, 7], c: '2' },
|
||||
{ a: 3, b: [8, 9], d: '3' },
|
||||
],
|
||||
{ concatArrays: true },
|
||||
{ a: 3, b: [1, 2, 3, 4, 5, 6, 7, 8, 9], c: '2', d: '3' },
|
||||
],
|
||||
[
|
||||
[
|
||||
{ a: 1, b: [1, 2, 3] },
|
||||
{ a: 2, b: [4, 5, 6, 7], c: '2' },
|
||||
{ a: 3, b: [8, 9], d: '3' },
|
||||
],
|
||||
{ overwriteArrays: true },
|
||||
{ a: 3, b: [8, 9], c: '2', d: '3' },
|
||||
],
|
||||
[
|
||||
[
|
||||
{ a: 1, b: [{ x: 'a' }] },
|
||||
{ a: 2, b: [{ y: 'b' }], c: '2' },
|
||||
{ a: 3, b: [{ z: 'c' }], d: '3' },
|
||||
],
|
||||
{},
|
||||
{ a: 3, b: [{ x: 'a', y: 'b', z: 'c' }], c: '2', d: '3' },
|
||||
],
|
||||
[
|
||||
[
|
||||
{ a: 1, b: [{ x: 'a' }] },
|
||||
{ a: 2, b: [{ y: 'b' }], c: '2' },
|
||||
{ a: 3, b: [{ z: 'c' }], d: '3' },
|
||||
],
|
||||
{ concatArrays: true },
|
||||
{ a: 3, b: [{ x: 'a' }, { y: 'b' }, { z: 'c' }], c: '2', d: '3' },
|
||||
],
|
||||
[
|
||||
[
|
||||
{ a: 1, b: [{ x: 'a' }] },
|
||||
{ a: 2, b: [{ y: 'b' }], c: '2' },
|
||||
{ a: 3, b: [{ z: 'c' }], d: '3' },
|
||||
],
|
||||
{ overwriteArrays: true },
|
||||
{ a: 3, b: [{ z: 'c' }], c: '2', d: '3' },
|
||||
],
|
||||
[
|
||||
[
|
||||
{ a: 1, b: [{ x: 'a' }, { w: 'd' }] },
|
||||
{ a: 2, b: [{ y: 'b' }], c: '2' },
|
||||
{ a: 3, b: [{ z: 'c' }], d: '3' },
|
||||
],
|
||||
{},
|
||||
{ a: 3, b: [{ z: 'c' }, { w: 'd' }], c: '2', d: '3' },
|
||||
],
|
||||
[
|
||||
[
|
||||
{ a: 1, b: [{ x: 'a' }, { w: 'd' }] },
|
||||
{ a: 2, b: [{ y: 'b' }], c: '2' },
|
||||
{ a: 3, b: [{ z: 'c' }], d: '3' },
|
||||
],
|
||||
{ concatArrays: true },
|
||||
{ a: 3, b: [{ x: 'a' }, { w: 'd' }, { y: 'b' }, { z: 'c' }], c: '2', d: '3' },
|
||||
],
|
||||
[
|
||||
[
|
||||
{ a: 1, b: [{ x: 'a' }, { w: 'd' }] },
|
||||
{ a: 2, b: [{ y: 'b' }], c: '2' },
|
||||
{ a: 3, b: [{ z: 'c' }], d: '3' },
|
||||
],
|
||||
{ overwriteArrays: true },
|
||||
{ a: 3, b: [{ z: 'c' }], c: '2', d: '3' },
|
||||
],
|
||||
])('case %#. input %j, options %j should return %j', (sources, options, expected) => {
|
||||
expect(mergeDeep([...sources], options)).toEqual(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getSchema', () => {
|
||||
test.each([
|
||||
[, { type: 'undefined', value: 'undefined', path: '' }],
|
||||
|
|
|
@ -164,54 +164,6 @@ export const isValidDate = (input: string | number | Date): boolean => {
|
|||
export const getObjectKeys = <T extends object, K extends keyof T>(o: T): K[] =>
|
||||
Object.keys(o) as K[];
|
||||
|
||||
export const mergeDeep = <T extends object | Primitives>(
|
||||
sources: T[],
|
||||
options?: Partial<Record<'overwriteArrays' | 'concatArrays', boolean>>,
|
||||
): T =>
|
||||
sources.reduce((target, source) => {
|
||||
if (Array.isArray(target) && Array.isArray(source)) {
|
||||
const tLength = target.length;
|
||||
const sLength = source.length;
|
||||
|
||||
if (tLength === 0 || options?.overwriteArrays) {
|
||||
return source;
|
||||
}
|
||||
|
||||
if (sLength === 0) {
|
||||
return target;
|
||||
}
|
||||
|
||||
if (options?.concatArrays) {
|
||||
return [...target, ...source];
|
||||
}
|
||||
|
||||
if (tLength === sLength) {
|
||||
return target.map((item, index) => mergeDeep([item, source[index]], options));
|
||||
} else if (tLength < sLength) {
|
||||
return source.map((item, index) => mergeDeep([target[index], item], options));
|
||||
} else {
|
||||
return [...source, ...target.slice(sLength)];
|
||||
}
|
||||
} else if (isObj(target) && isObj(source)) {
|
||||
const targetKeys = getObjectKeys(target);
|
||||
const sourceKeys = getObjectKeys(source);
|
||||
const allKeys = [...new Set([...targetKeys, ...sourceKeys])];
|
||||
const mergedObject = Object.create(Object.prototype);
|
||||
for (const key of allKeys) {
|
||||
if (targetKeys.includes(key) && sourceKeys.includes(key)) {
|
||||
mergedObject[key] = mergeDeep([target[key] as T, source[key] as T], options);
|
||||
} else if (targetKeys.includes(key)) {
|
||||
mergedObject[key] = target[key];
|
||||
} else {
|
||||
mergedObject[key] = source[key];
|
||||
}
|
||||
}
|
||||
return mergedObject;
|
||||
} else {
|
||||
return source;
|
||||
}
|
||||
}, (Array.isArray(sources[0]) ? [] : {}) as T);
|
||||
|
||||
export const getSchema = (input: Optional<Primitives | object>, path = ''): Schema => {
|
||||
let schema: Schema = { type: 'undefined', value: 'undefined', path };
|
||||
switch (typeof input) {
|
||||
|
|
Loading…
Reference in a new issue