mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-20 11:22:15 +00:00
feat(editor): Add mapping support for data paths (#5191)
* feat: add data path flag * chore: update types * feat: use path for data * feat: add support for multiple values * fix: handle if not prev node * fix: update node * fix: handle multi part path * feat: add support for multiple vals for field * feat: add support for table transforms * feat: use dot notation * feat: fix bug where brackets removed * fix: handle dots, fix unit tests * test: update snapshot * test: fix tests * test: add test for edge case
This commit is contained in:
@@ -229,12 +229,31 @@ export default mixins(showMessage).extend({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
onDrop(data: string) {
|
onDrop(data: string) {
|
||||||
|
const useDataPath = !!this.parameter.requiresDataPath && data.startsWith('{{ $json');
|
||||||
|
if (!useDataPath) {
|
||||||
this.forceShowExpression = true;
|
this.forceShowExpression = true;
|
||||||
|
}
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (this.node) {
|
if (this.node) {
|
||||||
const prevValue = this.isResourceLocator ? this.value.value : this.value;
|
const prevValue = this.isResourceLocator ? this.value.value : this.value;
|
||||||
let updatedValue: string;
|
let updatedValue: string;
|
||||||
if (typeof prevValue === 'string' && prevValue.startsWith('=') && prevValue.length > 1) {
|
if (useDataPath) {
|
||||||
|
const newValue = data
|
||||||
|
.replace('{{ $json', '')
|
||||||
|
.replace(new RegExp('^\\.'), '')
|
||||||
|
.replace(new RegExp('}}$'), '')
|
||||||
|
.trim();
|
||||||
|
|
||||||
|
if (prevValue && this.parameter.requiresDataPath === 'multiple') {
|
||||||
|
updatedValue = `${prevValue}, ${newValue}`;
|
||||||
|
} else {
|
||||||
|
updatedValue = newValue;
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
typeof prevValue === 'string' &&
|
||||||
|
prevValue.startsWith('=') &&
|
||||||
|
prevValue.length > 1
|
||||||
|
) {
|
||||||
updatedValue = `${prevValue} ${data}`;
|
updatedValue = `${prevValue} ${data}`;
|
||||||
} else {
|
} else {
|
||||||
updatedValue = `=${data}`;
|
updatedValue = `=${data}`;
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ import { externalHooks } from '@/mixins/externalHooks';
|
|||||||
import { mapStores } from 'pinia';
|
import { mapStores } from 'pinia';
|
||||||
import { useNDVStore } from '@/stores/ndv';
|
import { useNDVStore } from '@/stores/ndv';
|
||||||
import MappingPill from './MappingPill.vue';
|
import MappingPill from './MappingPill.vue';
|
||||||
|
import { getMappedExpression } from '@/utils/mappingUtils';
|
||||||
|
|
||||||
const runDataJsonActions = () => import('@/components/RunDataJsonActions.vue');
|
const runDataJsonActions = () => import('@/components/RunDataJsonActions.vue');
|
||||||
|
|
||||||
@@ -169,11 +170,13 @@ export default mixins(externalHooks).extend({
|
|||||||
return shorten(el.dataset.name || '', 16, 2);
|
return shorten(el.dataset.name || '', 16, 2);
|
||||||
},
|
},
|
||||||
getJsonParameterPath(path: string): string {
|
getJsonParameterPath(path: string): string {
|
||||||
const convertedPath = convertPath(path);
|
const subPath = path.replace(/^(\["?\d"?])/, ''); // remove item position
|
||||||
return `{{ ${convertedPath.replace(
|
|
||||||
/^(\["?\d"?])/,
|
return getMappedExpression({
|
||||||
this.distanceFromActive === 1 ? '$json' : `$node["${this.node!.name}"].json`,
|
nodeName: this.node.name,
|
||||||
)} }}`;
|
distanceFromActive: this.distanceFromActive,
|
||||||
|
path: subPath,
|
||||||
|
});
|
||||||
},
|
},
|
||||||
onDragStart(el: HTMLElement) {
|
onDragStart(el: HTMLElement) {
|
||||||
if (el && el.dataset.path) {
|
if (el && el.dataset.path) {
|
||||||
|
|||||||
@@ -60,4 +60,23 @@ describe('RunDataJsonSchema.vue', () => {
|
|||||||
});
|
});
|
||||||
expect(container).toMatchSnapshot();
|
expect(container).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('renders schema with spaces and dots', () => {
|
||||||
|
renderOptions.props.data = [
|
||||||
|
{
|
||||||
|
'hello world': [
|
||||||
|
{
|
||||||
|
test: {
|
||||||
|
'more to think about': 1,
|
||||||
|
},
|
||||||
|
'test.how': 'ignore',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const { container } = render(RunDataJsonSchema, renderOptions, (vue) => {
|
||||||
|
vue.use(PiniaVuePlugin);
|
||||||
|
});
|
||||||
|
expect(container).toMatchSnapshot();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import { INodeUi, Schema } from '@/Interface';
|
import { INodeUi, Schema } from '@/Interface';
|
||||||
import { checkExhaustive, shorten } from '@/utils';
|
import { checkExhaustive, shorten } from '@/utils';
|
||||||
|
import { getMappedExpression } from '@/utils/mappingUtils';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
schema: Schema;
|
schema: Schema;
|
||||||
@@ -35,7 +36,12 @@ const text = computed(() =>
|
|||||||
);
|
);
|
||||||
|
|
||||||
const getJsonParameterPath = (path: string): string =>
|
const getJsonParameterPath = (path: string): string =>
|
||||||
`{{ ${props.distanceFromActive === 1 ? '$json' : `$node["${props.node!.name}"].json`}${path} }}`;
|
getMappedExpression({
|
||||||
|
nodeName: props.node!.name,
|
||||||
|
distanceFromActive: props.distanceFromActive,
|
||||||
|
path,
|
||||||
|
});
|
||||||
|
|
||||||
const transitionDelay = (i: number) => `${i * 0.033}s`;
|
const transitionDelay = (i: number) => `${i * 0.033}s`;
|
||||||
|
|
||||||
const getIconBySchemaType = (type: Schema['type']): string => {
|
const getIconBySchemaType = (type: Schema['type']): string => {
|
||||||
|
|||||||
@@ -170,6 +170,7 @@ import { mapStores } from 'pinia';
|
|||||||
import { useWorkflowsStore } from '@/stores/workflows';
|
import { useWorkflowsStore } from '@/stores/workflows';
|
||||||
import { useNDVStore } from '@/stores/ndv';
|
import { useNDVStore } from '@/stores/ndv';
|
||||||
import MappingPill from './MappingPill.vue';
|
import MappingPill from './MappingPill.vue';
|
||||||
|
import { getMappedExpression } from '@/utils/mappingUtils';
|
||||||
|
|
||||||
const MAX_COLUMNS_LIMIT = 40;
|
const MAX_COLUMNS_LIMIT = 40;
|
||||||
|
|
||||||
@@ -315,11 +316,11 @@ export default mixins(externalHooks).extend({
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.distanceFromActive === 1) {
|
return getMappedExpression({
|
||||||
return `{{ $json["${column}"] }}`;
|
nodeName: this.node.name,
|
||||||
}
|
distanceFromActive: this.distanceFromActive,
|
||||||
|
path: [column],
|
||||||
return `{{ $node["${this.node.name}"].json["${column}"] }}`;
|
});
|
||||||
},
|
},
|
||||||
getPathNameFromTarget(el: HTMLElement) {
|
getPathNameFromTarget(el: HTMLElement) {
|
||||||
if (!el) {
|
if (!el) {
|
||||||
@@ -343,21 +344,12 @@ export default mixins(externalHooks).extend({
|
|||||||
if (!this.node) {
|
if (!this.node) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
const expr = path.reduce((accu: string, key: string | number) => {
|
|
||||||
if (typeof key === 'number') {
|
|
||||||
return `${accu}[${key}]`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return `${accu}["${key}"]`;
|
|
||||||
}, '');
|
|
||||||
const column = this.tableData.columns[colIndex];
|
const column = this.tableData.columns[colIndex];
|
||||||
|
return getMappedExpression({
|
||||||
if (this.distanceFromActive === 1) {
|
nodeName: this.node.name,
|
||||||
return `{{ $json["${column}"]${expr} }}`;
|
distanceFromActive: this.distanceFromActive,
|
||||||
}
|
path: [column, ...path],
|
||||||
|
});
|
||||||
return `{{ $node["${this.node.name}"].json["${column}"]${expr} }}`;
|
|
||||||
},
|
},
|
||||||
isEmpty(value: unknown): boolean {
|
isEmpty(value: unknown): boolean {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ exports[`RunDataJsonSchema.vue > renders schema for data 1`] = `
|
|||||||
class="label"
|
class="label"
|
||||||
data-depth="1"
|
data-depth="1"
|
||||||
data-name="name"
|
data-name="name"
|
||||||
data-path="[\\"name\\"]"
|
data-path=".name"
|
||||||
data-target="mappable"
|
data-target="mappable"
|
||||||
data-value="{{ $json[\\"name\\"] }}"
|
data-value="{{ $json.name }}"
|
||||||
>
|
>
|
||||||
<font-awesome-icon-stub
|
<font-awesome-icon-stub
|
||||||
icon="font"
|
icon="font"
|
||||||
@@ -70,9 +70,9 @@ exports[`RunDataJsonSchema.vue > renders schema for data 1`] = `
|
|||||||
class="label"
|
class="label"
|
||||||
data-depth="1"
|
data-depth="1"
|
||||||
data-name="age"
|
data-name="age"
|
||||||
data-path="[\\"age\\"]"
|
data-path=".age"
|
||||||
data-target="mappable"
|
data-target="mappable"
|
||||||
data-value="{{ $json[\\"age\\"] }}"
|
data-value="{{ $json.age }}"
|
||||||
>
|
>
|
||||||
<font-awesome-icon-stub
|
<font-awesome-icon-stub
|
||||||
icon="hashtag"
|
icon="hashtag"
|
||||||
@@ -107,9 +107,9 @@ exports[`RunDataJsonSchema.vue > renders schema for data 1`] = `
|
|||||||
class="label"
|
class="label"
|
||||||
data-depth="1"
|
data-depth="1"
|
||||||
data-name="hobbies"
|
data-name="hobbies"
|
||||||
data-path="[\\"hobbies\\"]"
|
data-path=".hobbies"
|
||||||
data-target="mappable"
|
data-target="mappable"
|
||||||
data-value="{{ $json[\\"hobbies\\"] }}"
|
data-value="{{ $json.hobbies }}"
|
||||||
>
|
>
|
||||||
<font-awesome-icon-stub
|
<font-awesome-icon-stub
|
||||||
icon="list"
|
icon="list"
|
||||||
@@ -152,9 +152,9 @@ exports[`RunDataJsonSchema.vue > renders schema for data 1`] = `
|
|||||||
class="label"
|
class="label"
|
||||||
data-depth="2"
|
data-depth="2"
|
||||||
data-name="string[0]"
|
data-name="string[0]"
|
||||||
data-path="[\\"hobbies\\"][0]"
|
data-path=".hobbies[0]"
|
||||||
data-target="mappable"
|
data-target="mappable"
|
||||||
data-value="{{ $json[\\"hobbies\\"][0] }}"
|
data-value="{{ $json.hobbies[0] }}"
|
||||||
>
|
>
|
||||||
<font-awesome-icon-stub
|
<font-awesome-icon-stub
|
||||||
icon="font"
|
icon="font"
|
||||||
@@ -191,9 +191,9 @@ exports[`RunDataJsonSchema.vue > renders schema for data 1`] = `
|
|||||||
class="label"
|
class="label"
|
||||||
data-depth="2"
|
data-depth="2"
|
||||||
data-name="string[1]"
|
data-name="string[1]"
|
||||||
data-path="[\\"hobbies\\"][1]"
|
data-path=".hobbies[1]"
|
||||||
data-target="mappable"
|
data-target="mappable"
|
||||||
data-value="{{ $json[\\"hobbies\\"][1] }}"
|
data-value="{{ $json.hobbies[1] }}"
|
||||||
>
|
>
|
||||||
<font-awesome-icon-stub
|
<font-awesome-icon-stub
|
||||||
icon="font"
|
icon="font"
|
||||||
@@ -259,3 +259,503 @@ exports[`RunDataJsonSchema.vue > renders schema for empty data 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`RunDataJsonSchema.vue > renders schema with spaces 1`] = `
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="_schemaWrapper_1mtap_1"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="_schema_1mtap_1"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="_item_14xdy_1"
|
||||||
|
>
|
||||||
|
<!---->
|
||||||
|
<!---->
|
||||||
|
<!---->
|
||||||
|
<!---->
|
||||||
|
<div
|
||||||
|
class="_sub_14xdy_14"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="_item_14xdy_1"
|
||||||
|
style="transition-delay: 0s;"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="_pill_14xdy_51 _mappable_14xdy_70"
|
||||||
|
title="array"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="_label_14xdy_89"
|
||||||
|
data-depth="1"
|
||||||
|
data-name="hello world"
|
||||||
|
data-path="[\\"hello world\\"]"
|
||||||
|
data-target="mappable"
|
||||||
|
data-value="{{ $json[\\"hello world\\"] }}"
|
||||||
|
>
|
||||||
|
<font-awesome-icon-stub
|
||||||
|
icon="list"
|
||||||
|
size="sm"
|
||||||
|
/>
|
||||||
|
<!---->
|
||||||
|
<span
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
hello world
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<!---->
|
||||||
|
<input
|
||||||
|
checked="checked"
|
||||||
|
id="array-0-0"
|
||||||
|
type="checkbox"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
class="_toggle_14xdy_20"
|
||||||
|
for="array-0-0"
|
||||||
|
>
|
||||||
|
<font-awesome-icon-stub
|
||||||
|
icon="angle-up"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<div
|
||||||
|
class="_sub_14xdy_14"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="_item_14xdy_1"
|
||||||
|
style="transition-delay: 0s;"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="_pill_14xdy_51 _mappable_14xdy_70"
|
||||||
|
title="object"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="_label_14xdy_89"
|
||||||
|
data-depth="2"
|
||||||
|
data-name="object[0]"
|
||||||
|
data-path="[\\"hello world\\"][0]"
|
||||||
|
data-target="mappable"
|
||||||
|
data-value="{{ $json[\\"hello world\\"][0] }}"
|
||||||
|
>
|
||||||
|
<font-awesome-icon-stub
|
||||||
|
icon="cube"
|
||||||
|
size="sm"
|
||||||
|
/>
|
||||||
|
<span>
|
||||||
|
hello world
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="_arrayIndex_14xdy_94"
|
||||||
|
>
|
||||||
|
[0]
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<!---->
|
||||||
|
<input
|
||||||
|
checked="checked"
|
||||||
|
id="object-1-0"
|
||||||
|
type="checkbox"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
class="_toggle_14xdy_20"
|
||||||
|
for="object-1-0"
|
||||||
|
>
|
||||||
|
<font-awesome-icon-stub
|
||||||
|
icon="angle-up"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<div
|
||||||
|
class="_sub_14xdy_14"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="_item_14xdy_1"
|
||||||
|
style="transition-delay: 0s;"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="_pill_14xdy_51 _mappable_14xdy_70"
|
||||||
|
title="object"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="_label_14xdy_89"
|
||||||
|
data-depth="3"
|
||||||
|
data-name="test"
|
||||||
|
data-path="[\\"hello world\\"][0].test"
|
||||||
|
data-target="mappable"
|
||||||
|
data-value="{{ $json[\\"hello world\\"][0].test }}"
|
||||||
|
>
|
||||||
|
<font-awesome-icon-stub
|
||||||
|
icon="cube"
|
||||||
|
size="sm"
|
||||||
|
/>
|
||||||
|
<!---->
|
||||||
|
<span
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
test
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<!---->
|
||||||
|
<input
|
||||||
|
checked="checked"
|
||||||
|
id="object-2-0"
|
||||||
|
type="checkbox"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
class="_toggle_14xdy_20"
|
||||||
|
for="object-2-0"
|
||||||
|
>
|
||||||
|
<font-awesome-icon-stub
|
||||||
|
icon="angle-up"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<div
|
||||||
|
class="_sub_14xdy_14"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="_item_14xdy_1"
|
||||||
|
style="transition-delay: 0s;"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="_pill_14xdy_51 _mappable_14xdy_70"
|
||||||
|
title="number"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="_label_14xdy_89"
|
||||||
|
data-depth="4"
|
||||||
|
data-name="more to think about"
|
||||||
|
data-path="[\\"hello world\\"][0].test[\\"more to think about\\"]"
|
||||||
|
data-target="mappable"
|
||||||
|
data-value="{{ $json[\\"hello world\\"][0].test[\\"more to think about\\"] }}"
|
||||||
|
>
|
||||||
|
<font-awesome-icon-stub
|
||||||
|
icon="hashtag"
|
||||||
|
size="sm"
|
||||||
|
/>
|
||||||
|
<!---->
|
||||||
|
<span
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
more to think about
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="_text_14xdy_100"
|
||||||
|
>
|
||||||
|
1
|
||||||
|
</span>
|
||||||
|
<!---->
|
||||||
|
<!---->
|
||||||
|
<!---->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="_item_14xdy_1"
|
||||||
|
style="transition-delay: 0.033s;"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="_pill_14xdy_51 _mappable_14xdy_70"
|
||||||
|
title="string"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="_label_14xdy_89"
|
||||||
|
data-depth="3"
|
||||||
|
data-name="test.how"
|
||||||
|
data-path="[\\"hello world\\"][0][\\"test.how\\"]"
|
||||||
|
data-target="mappable"
|
||||||
|
data-value="{{ $json[\\"hello world\\"][0][\\"test.how\\"] }}"
|
||||||
|
>
|
||||||
|
<font-awesome-icon-stub
|
||||||
|
icon="font"
|
||||||
|
size="sm"
|
||||||
|
/>
|
||||||
|
<!---->
|
||||||
|
<span
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
test.how
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="_text_14xdy_100"
|
||||||
|
>
|
||||||
|
ignore
|
||||||
|
</span>
|
||||||
|
<!---->
|
||||||
|
<!---->
|
||||||
|
<!---->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="teleporter hidden"
|
||||||
|
data-v-d4e6e290=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`RunDataJsonSchema.vue > renders schema with spaces and dots 1`] = `
|
||||||
|
<div>
|
||||||
|
<div
|
||||||
|
class="_schemaWrapper_1mtap_1"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="_schema_1mtap_1"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="_item_14xdy_1"
|
||||||
|
>
|
||||||
|
<!---->
|
||||||
|
<!---->
|
||||||
|
<!---->
|
||||||
|
<!---->
|
||||||
|
<div
|
||||||
|
class="_sub_14xdy_14"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="_item_14xdy_1"
|
||||||
|
style="transition-delay: 0s;"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="_pill_14xdy_51 _mappable_14xdy_70"
|
||||||
|
title="array"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="_label_14xdy_89"
|
||||||
|
data-depth="1"
|
||||||
|
data-name="hello world"
|
||||||
|
data-path="[\\"hello world\\"]"
|
||||||
|
data-target="mappable"
|
||||||
|
data-value="{{ $json[\\"hello world\\"] }}"
|
||||||
|
>
|
||||||
|
<font-awesome-icon-stub
|
||||||
|
icon="list"
|
||||||
|
size="sm"
|
||||||
|
/>
|
||||||
|
<!---->
|
||||||
|
<span
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
hello world
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<!---->
|
||||||
|
<input
|
||||||
|
checked="checked"
|
||||||
|
id="array-0-0"
|
||||||
|
type="checkbox"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
class="_toggle_14xdy_20"
|
||||||
|
for="array-0-0"
|
||||||
|
>
|
||||||
|
<font-awesome-icon-stub
|
||||||
|
icon="angle-up"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<div
|
||||||
|
class="_sub_14xdy_14"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="_item_14xdy_1"
|
||||||
|
style="transition-delay: 0s;"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="_pill_14xdy_51 _mappable_14xdy_70"
|
||||||
|
title="object"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="_label_14xdy_89"
|
||||||
|
data-depth="2"
|
||||||
|
data-name="object[0]"
|
||||||
|
data-path="[\\"hello world\\"][0]"
|
||||||
|
data-target="mappable"
|
||||||
|
data-value="{{ $json[\\"hello world\\"][0] }}"
|
||||||
|
>
|
||||||
|
<font-awesome-icon-stub
|
||||||
|
icon="cube"
|
||||||
|
size="sm"
|
||||||
|
/>
|
||||||
|
<span>
|
||||||
|
hello world
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="_arrayIndex_14xdy_94"
|
||||||
|
>
|
||||||
|
[0]
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<!---->
|
||||||
|
<input
|
||||||
|
checked="checked"
|
||||||
|
id="object-1-0"
|
||||||
|
type="checkbox"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
class="_toggle_14xdy_20"
|
||||||
|
for="object-1-0"
|
||||||
|
>
|
||||||
|
<font-awesome-icon-stub
|
||||||
|
icon="angle-up"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<div
|
||||||
|
class="_sub_14xdy_14"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="_item_14xdy_1"
|
||||||
|
style="transition-delay: 0s;"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="_pill_14xdy_51 _mappable_14xdy_70"
|
||||||
|
title="object"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="_label_14xdy_89"
|
||||||
|
data-depth="3"
|
||||||
|
data-name="test"
|
||||||
|
data-path="[\\"hello world\\"][0].test"
|
||||||
|
data-target="mappable"
|
||||||
|
data-value="{{ $json[\\"hello world\\"][0].test }}"
|
||||||
|
>
|
||||||
|
<font-awesome-icon-stub
|
||||||
|
icon="cube"
|
||||||
|
size="sm"
|
||||||
|
/>
|
||||||
|
<!---->
|
||||||
|
<span
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
test
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<!---->
|
||||||
|
<input
|
||||||
|
checked="checked"
|
||||||
|
id="object-2-0"
|
||||||
|
type="checkbox"
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
class="_toggle_14xdy_20"
|
||||||
|
for="object-2-0"
|
||||||
|
>
|
||||||
|
<font-awesome-icon-stub
|
||||||
|
icon="angle-up"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
<div
|
||||||
|
class="_sub_14xdy_14"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="_item_14xdy_1"
|
||||||
|
style="transition-delay: 0s;"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="_pill_14xdy_51 _mappable_14xdy_70"
|
||||||
|
title="number"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="_label_14xdy_89"
|
||||||
|
data-depth="4"
|
||||||
|
data-name="more to think about"
|
||||||
|
data-path="[\\"hello world\\"][0].test[\\"more to think about\\"]"
|
||||||
|
data-target="mappable"
|
||||||
|
data-value="{{ $json[\\"hello world\\"][0].test[\\"more to think about\\"] }}"
|
||||||
|
>
|
||||||
|
<font-awesome-icon-stub
|
||||||
|
icon="hashtag"
|
||||||
|
size="sm"
|
||||||
|
/>
|
||||||
|
<!---->
|
||||||
|
<span
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
more to think about
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="_text_14xdy_100"
|
||||||
|
>
|
||||||
|
1
|
||||||
|
</span>
|
||||||
|
<!---->
|
||||||
|
<!---->
|
||||||
|
<!---->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="_item_14xdy_1"
|
||||||
|
style="transition-delay: 0.033s;"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="_pill_14xdy_51 _mappable_14xdy_70"
|
||||||
|
title="string"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="_label_14xdy_89"
|
||||||
|
data-depth="3"
|
||||||
|
data-name="test.how"
|
||||||
|
data-path="[\\"hello world\\"][0][\\"test.how\\"]"
|
||||||
|
data-target="mappable"
|
||||||
|
data-value="{{ $json[\\"hello world\\"][0][\\"test.how\\"] }}"
|
||||||
|
>
|
||||||
|
<font-awesome-icon-stub
|
||||||
|
icon="font"
|
||||||
|
size="sm"
|
||||||
|
/>
|
||||||
|
<!---->
|
||||||
|
<span
|
||||||
|
class=""
|
||||||
|
>
|
||||||
|
test.how
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="_text_14xdy_100"
|
||||||
|
>
|
||||||
|
ignore
|
||||||
|
</span>
|
||||||
|
<!---->
|
||||||
|
<!---->
|
||||||
|
<!---->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="teleporter hidden"
|
||||||
|
data-v-d4e6e290=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|||||||
@@ -257,10 +257,31 @@ describe('Utils', () => {
|
|||||||
type: 'array',
|
type: 'array',
|
||||||
key: 'people',
|
key: 'people',
|
||||||
value: [
|
value: [
|
||||||
{ type: 'string', value: 'Joe', key: '0', path: '["people"][0]' },
|
{ type: 'string', value: 'Joe', key: '0', path: '.people[0]' },
|
||||||
{ type: 'string', value: 'John', key: '1', path: '["people"][1]' },
|
{ type: 'string', value: 'John', key: '1', path: '.people[1]' },
|
||||||
],
|
],
|
||||||
path: '["people"]',
|
path: '.people',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
path: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{ 'with space': [], 'with.dot': 'test' },
|
||||||
|
{
|
||||||
|
type: 'object',
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
type: 'array',
|
||||||
|
key: 'with space',
|
||||||
|
value: [],
|
||||||
|
path: '["with space"]',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'string',
|
||||||
|
key: 'with.dot',
|
||||||
|
value: 'test',
|
||||||
|
path: '["with.dot"]',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
path: '',
|
path: '',
|
||||||
@@ -278,8 +299,8 @@ describe('Utils', () => {
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
key: '0',
|
key: '0',
|
||||||
value: [
|
value: [
|
||||||
{ type: 'string', key: 'name', value: 'John', path: '[0]["name"]' },
|
{ type: 'string', key: 'name', value: 'John', path: '[0].name' },
|
||||||
{ type: 'number', key: 'age', value: '22', path: '[0]["age"]' },
|
{ type: 'number', key: 'age', value: '22', path: '[0].age' },
|
||||||
],
|
],
|
||||||
path: '[0]',
|
path: '[0]',
|
||||||
},
|
},
|
||||||
@@ -287,8 +308,8 @@ describe('Utils', () => {
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
key: '1',
|
key: '1',
|
||||||
value: [
|
value: [
|
||||||
{ type: 'string', key: 'name', value: 'Joe', path: '[1]["name"]' },
|
{ type: 'string', key: 'name', value: 'Joe', path: '[1].name' },
|
||||||
{ type: 'number', key: 'age', value: '33', path: '[1]["age"]' },
|
{ type: 'number', key: 'age', value: '33', path: '[1].age' },
|
||||||
],
|
],
|
||||||
path: '[1]',
|
path: '[1]',
|
||||||
},
|
},
|
||||||
@@ -308,16 +329,16 @@ describe('Utils', () => {
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
key: '0',
|
key: '0',
|
||||||
value: [
|
value: [
|
||||||
{ type: 'string', key: 'name', value: 'John', path: '[0]["name"]' },
|
{ type: 'string', key: 'name', value: 'John', path: '[0].name' },
|
||||||
{ type: 'number', key: 'age', value: '22', path: '[0]["age"]' },
|
{ type: 'number', key: 'age', value: '22', path: '[0].age' },
|
||||||
{
|
{
|
||||||
type: 'array',
|
type: 'array',
|
||||||
key: 'hobbies',
|
key: 'hobbies',
|
||||||
value: [
|
value: [
|
||||||
{ type: 'string', key: '0', value: 'surfing', path: '[0]["hobbies"][0]' },
|
{ type: 'string', key: '0', value: 'surfing', path: '[0].hobbies[0]' },
|
||||||
{ type: 'string', key: '1', value: 'traveling', path: '[0]["hobbies"][1]' },
|
{ type: 'string', key: '1', value: 'traveling', path: '[0].hobbies[1]' },
|
||||||
],
|
],
|
||||||
path: '[0]["hobbies"]',
|
path: '[0].hobbies',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
path: '[0]',
|
path: '[0]',
|
||||||
@@ -326,16 +347,16 @@ describe('Utils', () => {
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
key: '1',
|
key: '1',
|
||||||
value: [
|
value: [
|
||||||
{ type: 'string', key: 'name', value: 'Joe', path: '[1]["name"]' },
|
{ type: 'string', key: 'name', value: 'Joe', path: '[1].name' },
|
||||||
{ type: 'number', key: 'age', value: '33', path: '[1]["age"]' },
|
{ type: 'number', key: 'age', value: '33', path: '[1].age' },
|
||||||
{
|
{
|
||||||
type: 'array',
|
type: 'array',
|
||||||
key: 'hobbies',
|
key: 'hobbies',
|
||||||
value: [
|
value: [
|
||||||
{ type: 'string', key: '0', value: 'skateboarding', path: '[1]["hobbies"][0]' },
|
{ type: 'string', key: '0', value: 'skateboarding', path: '[1].hobbies[0]' },
|
||||||
{ type: 'string', key: '1', value: 'gaming', path: '[1]["hobbies"][1]' },
|
{ type: 'string', key: '1', value: 'gaming', path: '[1].hobbies[1]' },
|
||||||
],
|
],
|
||||||
path: '[1]["hobbies"]',
|
path: '[1].hobbies',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
path: '[1]',
|
path: '[1]',
|
||||||
@@ -381,8 +402,8 @@ describe('Utils', () => {
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
key: '0',
|
key: '0',
|
||||||
value: [
|
value: [
|
||||||
{ type: 'string', key: 'name', value: 'John', path: '[0][0]["name"]' },
|
{ type: 'string', key: 'name', value: 'John', path: '[0][0].name' },
|
||||||
{ type: 'number', key: 'age', value: '22', path: '[0][0]["age"]' },
|
{ type: 'number', key: 'age', value: '22', path: '[0][0].age' },
|
||||||
],
|
],
|
||||||
path: '[0][0]',
|
path: '[0][0]',
|
||||||
},
|
},
|
||||||
@@ -390,8 +411,8 @@ describe('Utils', () => {
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
key: '1',
|
key: '1',
|
||||||
value: [
|
value: [
|
||||||
{ type: 'string', key: 'name', value: 'Joe', path: '[0][1]["name"]' },
|
{ type: 'string', key: 'name', value: 'Joe', path: '[0][1].name' },
|
||||||
{ type: 'number', key: 'age', value: '33', path: '[0][1]["age"]' },
|
{ type: 'number', key: 'age', value: '33', path: '[0][1].age' },
|
||||||
],
|
],
|
||||||
path: '[0][1]',
|
path: '[0][1]',
|
||||||
},
|
},
|
||||||
@@ -430,16 +451,16 @@ describe('Utils', () => {
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
key: '0',
|
key: '0',
|
||||||
value: '2022-11-22T00:00:00.000Z',
|
value: '2022-11-22T00:00:00.000Z',
|
||||||
path: '[0]["dates"][0][0]',
|
path: '[0].dates[0][0]',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'string',
|
type: 'string',
|
||||||
key: '1',
|
key: '1',
|
||||||
value: '2022-11-23T00:00:00.000Z',
|
value: '2022-11-23T00:00:00.000Z',
|
||||||
path: '[0]["dates"][0][1]',
|
path: '[0].dates[0][1]',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
path: '[0]["dates"][0]',
|
path: '[0].dates[0]',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'array',
|
type: 'array',
|
||||||
@@ -449,19 +470,19 @@ describe('Utils', () => {
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
key: '0',
|
key: '0',
|
||||||
value: '2022-12-22T00:00:00.000Z',
|
value: '2022-12-22T00:00:00.000Z',
|
||||||
path: '[0]["dates"][1][0]',
|
path: '[0].dates[1][0]',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'string',
|
type: 'string',
|
||||||
key: '1',
|
key: '1',
|
||||||
value: '2022-12-23T00:00:00.000Z',
|
value: '2022-12-23T00:00:00.000Z',
|
||||||
path: '[0]["dates"][1][1]',
|
path: '[0].dates[1][1]',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
path: '[0]["dates"][1]',
|
path: '[0].dates[1]',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
path: '[0]["dates"]',
|
path: '[0].dates',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
path: '[0]',
|
path: '[0]',
|
||||||
|
|||||||
31
packages/editor-ui/src/utils/mappingUtils.ts
Normal file
31
packages/editor-ui/src/utils/mappingUtils.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
export function generatePath(root: string, path: Array<string | number>): string {
|
||||||
|
return path.reduce((accu: string, part: string | number) => {
|
||||||
|
if (typeof part === 'number') {
|
||||||
|
return `${accu}[${part}]`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (part.includes(' ') || part.includes('.')) {
|
||||||
|
return `${accu}["${part}"]`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${accu}.${part}`;
|
||||||
|
}, root);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getMappedExpression({
|
||||||
|
nodeName,
|
||||||
|
distanceFromActive,
|
||||||
|
path,
|
||||||
|
}: {
|
||||||
|
nodeName: string;
|
||||||
|
distanceFromActive: number;
|
||||||
|
path: Array<string | number> | string;
|
||||||
|
}) {
|
||||||
|
const root = distanceFromActive === 1 ? '$json' : generatePath('$node', [nodeName, 'json']);
|
||||||
|
|
||||||
|
if (typeof path === 'string') {
|
||||||
|
return `{{ ${root}${path} }}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `{{ ${generatePath(root, path)} }}`;
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ import dateformat from 'dateformat';
|
|||||||
import { IDataObject, jsonParse } from 'n8n-workflow';
|
import { IDataObject, jsonParse } from 'n8n-workflow';
|
||||||
import { Schema, Optional, Primitives } from '@/Interface';
|
import { Schema, Optional, Primitives } from '@/Interface';
|
||||||
import { isObj } from '@/utils/typeGuards';
|
import { isObj } from '@/utils/typeGuards';
|
||||||
|
import { generatePath } from '@/utils/mappingUtils';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Constants and utility functions than can be used to manipulate different data types and objects
|
Constants and utility functions than can be used to manipulate different data types and objects
|
||||||
@@ -231,7 +232,7 @@ export const getSchema = (input: Optional<Primitives | object>, path = ''): Sche
|
|||||||
type: 'object',
|
type: 'object',
|
||||||
value: Object.entries(input).map(([k, v]) => ({
|
value: Object.entries(input).map(([k, v]) => ({
|
||||||
key: k,
|
key: k,
|
||||||
...getSchema(v, path + `["${k}"]`),
|
...getSchema(v, generatePath(path, [k])),
|
||||||
})),
|
})),
|
||||||
path,
|
path,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ export class CompareDatasets implements INodeType {
|
|||||||
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
||||||
placeholder: 'e.g. id',
|
placeholder: 'e.g. id',
|
||||||
hint: ' Enter the field name as text',
|
hint: ' Enter the field name as text',
|
||||||
|
requiresDataPath: 'single',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Input B Field',
|
displayName: 'Input B Field',
|
||||||
@@ -61,6 +62,7 @@ export class CompareDatasets implements INodeType {
|
|||||||
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
||||||
placeholder: 'e.g. id',
|
placeholder: 'e.g. id',
|
||||||
hint: ' Enter the field name as text',
|
hint: ' Enter the field name as text',
|
||||||
|
requiresDataPath: 'single',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -126,6 +128,7 @@ export class CompareDatasets implements INodeType {
|
|||||||
resolve: ['mix'],
|
resolve: ['mix'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
requiresDataPath: 'multiple',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Options',
|
displayName: 'Options',
|
||||||
@@ -143,6 +146,7 @@ export class CompareDatasets implements INodeType {
|
|||||||
hint: 'Enter the field names as text, separated by commas',
|
hint: 'Enter the field names as text, separated by commas',
|
||||||
description:
|
description:
|
||||||
"Fields that shouldn't be included when checking whether two items are the same",
|
"Fields that shouldn't be included when checking whether two items are the same",
|
||||||
|
requiresDataPath: 'multiple',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Fuzzy Compare',
|
displayName: 'Fuzzy Compare',
|
||||||
|
|||||||
@@ -139,6 +139,7 @@ export class ItemLists implements INodeType {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
description: 'The name of the input field to break out into separate items',
|
description: 'The name of the input field to break out into separate items',
|
||||||
|
requiresDataPath: 'single',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Include',
|
displayName: 'Include',
|
||||||
@@ -197,6 +198,7 @@ export class ItemLists implements INodeType {
|
|||||||
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
||||||
placeholder: 'e.g. id',
|
placeholder: 'e.g. id',
|
||||||
hint: ' Enter the field name as text',
|
hint: ' Enter the field name as text',
|
||||||
|
requiresDataPath: 'single',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -256,6 +258,7 @@ export class ItemLists implements INodeType {
|
|||||||
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
||||||
placeholder: 'e.g. id',
|
placeholder: 'e.g. id',
|
||||||
hint: ' Enter the field name as text',
|
hint: ' Enter the field name as text',
|
||||||
|
requiresDataPath: 'single',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Rename Field',
|
displayName: 'Rename Field',
|
||||||
@@ -276,6 +279,7 @@ export class ItemLists implements INodeType {
|
|||||||
default: '',
|
default: '',
|
||||||
description:
|
description:
|
||||||
'The name of the field to put the aggregated data in. Leave blank to use the input field name.',
|
'The name of the field to put the aggregated data in. Leave blank to use the input field name.',
|
||||||
|
requiresDataPath: 'single',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -346,6 +350,7 @@ export class ItemLists implements INodeType {
|
|||||||
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
||||||
placeholder: 'e.g. id',
|
placeholder: 'e.g. id',
|
||||||
hint: ' Enter the field name as text',
|
hint: ' Enter the field name as text',
|
||||||
|
requiresDataPath: 'single',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -382,6 +387,7 @@ export class ItemLists implements INodeType {
|
|||||||
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
||||||
placeholder: 'e.g. id',
|
placeholder: 'e.g. id',
|
||||||
hint: ' Enter the field name as text',
|
hint: ' Enter the field name as text',
|
||||||
|
requiresDataPath: 'single',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -453,6 +459,7 @@ export class ItemLists implements INodeType {
|
|||||||
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
||||||
placeholder: 'e.g. id',
|
placeholder: 'e.g. id',
|
||||||
hint: ' Enter the field name as text',
|
hint: ' Enter the field name as text',
|
||||||
|
requiresDataPath: 'single',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -488,6 +495,7 @@ export class ItemLists implements INodeType {
|
|||||||
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
||||||
placeholder: 'e.g. id',
|
placeholder: 'e.g. id',
|
||||||
hint: ' Enter the field name as text',
|
hint: ' Enter the field name as text',
|
||||||
|
requiresDataPath: 'single',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -544,6 +552,7 @@ export class ItemLists implements INodeType {
|
|||||||
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
||||||
placeholder: 'e.g. id',
|
placeholder: 'e.g. id',
|
||||||
hint: ' Enter the field name as text',
|
hint: ' Enter the field name as text',
|
||||||
|
requiresDataPath: 'single',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Order',
|
displayName: 'Order',
|
||||||
|
|||||||
@@ -123,6 +123,7 @@ export const description: INodeProperties[] = [
|
|||||||
aggregation: [...NUMERICAL_AGGREGATIONS, 'countUnique', 'count'],
|
aggregation: [...NUMERICAL_AGGREGATIONS, 'countUnique', 'count'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
requiresDataPath: 'single',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Field',
|
displayName: 'Field',
|
||||||
@@ -138,6 +139,7 @@ export const description: INodeProperties[] = [
|
|||||||
aggregation: NUMERICAL_AGGREGATIONS,
|
aggregation: NUMERICAL_AGGREGATIONS,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
requiresDataPath: 'single',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Field',
|
displayName: 'Field',
|
||||||
@@ -153,6 +155,7 @@ export const description: INodeProperties[] = [
|
|||||||
aggregation: ['countUnique', 'count'],
|
aggregation: ['countUnique', 'count'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
requiresDataPath: 'single',
|
||||||
},
|
},
|
||||||
// ----------------------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------------------------
|
||||||
{
|
{
|
||||||
@@ -245,6 +248,7 @@ export const description: INodeProperties[] = [
|
|||||||
'/options.outputFormat': ['singleItem'],
|
'/options.outputFormat': ['singleItem'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
requiresDataPath: 'multiple',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Fields to Group By',
|
displayName: 'Fields to Group By',
|
||||||
@@ -261,6 +265,7 @@ export const description: INodeProperties[] = [
|
|||||||
'/options.outputFormat': ['singleItem'],
|
'/options.outputFormat': ['singleItem'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
requiresDataPath: 'multiple',
|
||||||
},
|
},
|
||||||
// ----------------------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------------------------
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ const versionDescription: INodeTypeDescription = {
|
|||||||
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
||||||
placeholder: 'e.g. id',
|
placeholder: 'e.g. id',
|
||||||
hint: ' Enter the field name as text',
|
hint: ' Enter the field name as text',
|
||||||
|
requiresDataPath: 'single',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
displayName: 'Input 2 Field',
|
displayName: 'Input 2 Field',
|
||||||
@@ -131,6 +132,7 @@ const versionDescription: INodeTypeDescription = {
|
|||||||
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
// eslint-disable-next-line n8n-nodes-base/node-param-placeholder-miscased-id
|
||||||
placeholder: 'e.g. id',
|
placeholder: 'e.g. id',
|
||||||
hint: ' Enter the field name as text',
|
hint: ' Enter the field name as text',
|
||||||
|
requiresDataPath: 'single',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1039,6 +1039,7 @@ export interface INodeProperties {
|
|||||||
>;
|
>;
|
||||||
extractValue?: INodePropertyValueExtractor;
|
extractValue?: INodePropertyValueExtractor;
|
||||||
modes?: INodePropertyMode[];
|
modes?: INodePropertyMode[];
|
||||||
|
requiresDataPath?: 'single' | 'multiple';
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface INodePropertyModeTypeOptions {
|
export interface INodePropertyModeTypeOptions {
|
||||||
|
|||||||
Reference in New Issue
Block a user