fix(editor): Drop mergeDeep in favor of lodash merge (#5943)

This commit is contained in:
Csaba Tuncsik 2023-04-11 13:05:43 +02:00 committed by GitHub
parent 6cf74e412a
commit 0570514b78
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 4 additions and 225 deletions

View file

@ -1,5 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, ref } from 'vue'; import { computed, ref } from 'vue';
import { merge } from 'lodash-es';
import { INodeUi, Schema } from '@/Interface'; import { INodeUi, Schema } from '@/Interface';
import RunDataSchemaItem from '@/components/RunDataSchemaItem.vue'; import RunDataSchemaItem from '@/components/RunDataSchemaItem.vue';
import Draggable from '@/components/Draggable.vue'; import Draggable from '@/components/Draggable.vue';
@ -8,7 +9,7 @@ import { useWebhooksStore } from '@/stores/webhooks';
import { runExternalHook } from '@/mixins/externalHooks'; import { runExternalHook } from '@/mixins/externalHooks';
import { telemetry } from '@/plugins/telemetry'; import { telemetry } from '@/plugins/telemetry';
import { IDataObject } from 'n8n-workflow'; import { IDataObject } from 'n8n-workflow';
import { getSchema, isEmpty, mergeDeep } from '@/utils'; import { getSchema, isEmpty } from '@/utils';
import { i18n } from '@/plugins/i18n'; import { i18n } from '@/plugins/i18n';
import MappingPill from './MappingPill.vue'; import MappingPill from './MappingPill.vue';
@ -32,7 +33,7 @@ const webhooksStore = useWebhooksStore();
const schema = computed<Schema>(() => { const schema = computed<Schema>(() => {
const [head, ...tail] = props.data; const [head, ...tail] = props.data;
return getSchema(mergeDeep([head, ...tail, head])); return getSchema(merge({}, head, ...tail, head));
}); });
const isDataEmpty = computed(() => { const isDataEmpty = computed(() => {

View file

@ -1,5 +1,5 @@
import jp from 'jsonpath'; import jp from 'jsonpath';
import { isEmpty, intersection, mergeDeep, getSchema, isValidDate } from '@/utils'; import { isEmpty, intersection, getSchema, isValidDate } from '@/utils';
import { Schema } from '@/Interface'; import { Schema } from '@/Interface';
describe('Types Utils', () => { 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', () => { describe('getSchema', () => {
test.each([ test.each([
[, { type: 'undefined', value: 'undefined', path: '' }], [, { type: 'undefined', value: 'undefined', path: '' }],

View file

@ -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[] => export const getObjectKeys = <T extends object, K extends keyof T>(o: T): K[] =>
Object.keys(o) as 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 => { export const getSchema = (input: Optional<Primitives | object>, path = ''): Schema => {
let schema: Schema = { type: 'undefined', value: 'undefined', path }; let schema: Schema = { type: 'undefined', value: 'undefined', path };
switch (typeof input) { switch (typeof input) {