diff --git a/packages/core/src/execution-engine/node-execution-context/utils/__tests__/validate-value-against-schema.test.ts b/packages/core/src/execution-engine/node-execution-context/utils/__tests__/validate-value-against-schema.test.ts index 4f389856ad..af6eb43395 100644 --- a/packages/core/src/execution-engine/node-execution-context/utils/__tests__/validate-value-against-schema.test.ts +++ b/packages/core/src/execution-engine/node-execution-context/utils/__tests__/validate-value-against-schema.test.ts @@ -247,65 +247,155 @@ describe('validateValueAgainstSchema', () => { expect(typeof result).toEqual('number'); }); - describe('when the mode is in Fixed mode, and the node is a resource mapper', () => { - const nodeType = { - description: { - properties: [ - { - name: 'operation', - type: 'resourceMapper', - typeOptions: { - resourceMapper: { - mode: 'add', + describe('when validating a resource mapper value', () => { + describe('when attemptToConvertTypes === true', () => { + const nodeType = { + description: { + properties: [ + { + name: 'operation', + type: 'resourceMapper', + typeOptions: { + resourceMapper: { + mode: 'add', + }, }, }, - }, - ], - }, - } as unknown as INodeType; - - const node = { - parameters: { - operation: { - schema: [ - { id: 'num', type: 'number', required: true }, - { id: 'str', type: 'string', required: true }, - { id: 'obj', type: 'object', required: true }, - { id: 'arr', type: 'array', required: true }, ], - attemptToConvertTypes: true, - mappingMode: '', - value: '', }, - }, - } as unknown as INode; + } as unknown as INodeType; - const parameterName = 'operation.value'; + const node = { + parameters: { + operation: { + schema: [ + { id: 'num', type: 'number', required: true }, + { id: 'str', type: 'string', required: true }, + { id: 'obj', type: 'object', required: true }, + { id: 'arr', type: 'array', required: true }, + ], + attemptToConvertTypes: true, + mappingMode: '', + value: '', + }, + }, + } as unknown as INode; - describe('should correctly validate values for', () => { - test.each([ - { num: 0 }, - { num: 23 }, - { num: -0 }, - { num: -Infinity }, - { num: Infinity }, - { str: '' }, - { str: ' ' }, - { str: 'hello' }, - { arr: [] }, - { obj: {} }, - ])('%s', (value) => { - expect(() => - validateValueAgainstSchema(node, nodeType, value, parameterName, 0, 0), - ).not.toThrow(); + const parameterName = 'operation.value'; + + describe('should correctly validate values for', () => { + test.each([ + { num: 0 }, + { num: 23 }, + { num: -0 }, + { num: -Infinity }, + { num: Infinity }, + { str: '' }, + { str: ' ' }, + { str: 'hello' }, + { arr: [] }, + { obj: {} }, + ])('%s', (value) => { + expect(() => + validateValueAgainstSchema(node, nodeType, value, parameterName, 0, 0), + ).not.toThrow(); + }); + }); + + describe('should throw an error for', () => { + test.each([{ num: NaN }, { num: undefined }, { num: null }])('%s', (value) => { + expect(() => + validateValueAgainstSchema(node, nodeType, value, parameterName, 0, 0), + ).toThrow(); + }); }); }); - describe('should throw an error for', () => { - test.each([{ num: NaN }, { num: undefined }, { num: null }])('%s', (value) => { - expect(() => - validateValueAgainstSchema(node, nodeType, value, parameterName, 0, 0), - ).toThrow(); + describe('when attemptToConvertTypes is not set (=default)', () => { + test('should correctly validate and convert types', () => { + const nodeType = { + description: { + properties: [ + { + displayName: 'Columns', + name: 'columns', + type: 'resourceMapper', + noDataExpression: true, + default: { + mappingMode: 'defineBelow', + value: null, + }, + required: true, + typeOptions: { + loadOptionsDependsOn: ['table.value', 'operation'], + resourceMapper: { + resourceMapperMethod: 'getMappingColumns', + mode: 'upsert', + fieldWords: { + singular: 'column', + plural: 'columns', + }, + addAllFields: true, + multiKeyMatch: true, + }, + }, + }, + ], + }, + } as unknown as INodeType; + + const node: INode = { + parameters: { + columns: { + mappingMode: 'defineBelow', + value: { + id: 2, + count: '={{ $json.count }}', + }, + matchingColumns: ['id'], + schema: [ + { + id: 'id', + displayName: 'id', + required: false, + defaultMatch: true, + display: true, + type: 'number', + canBeUsedToMatch: true, + }, + { + id: 'count', + displayName: 'count', + required: false, + defaultMatch: false, + display: true, + type: 'number', + canBeUsedToMatch: false, + }, + ], + }, + options: {}, + }, + id: '8d6cec63-8db1-440c-8966-4d6311ee69a9', + name: 'add products to DB', + type: 'n8n-nodes-base.postgres', + typeVersion: 2.3, + position: [420, 0], + }; + + const value = { + id: 2, + count: '23', + }; + + const parameterName = 'columns.value'; + + const result = validateValueAgainstSchema(node, nodeType, value, parameterName, 0, 0); + + expect(result).toEqual({ + id: 2, + count: 23, + }); }); }); }); diff --git a/packages/core/src/execution-engine/node-execution-context/utils/validate-value-against-schema.ts b/packages/core/src/execution-engine/node-execution-context/utils/validate-value-against-schema.ts index 58744adf03..f05929c456 100644 --- a/packages/core/src/execution-engine/node-execution-context/utils/validate-value-against-schema.ts +++ b/packages/core/src/execution-engine/node-execution-context/utils/validate-value-against-schema.ts @@ -56,8 +56,8 @@ const validateResourceMapperValue = ( if (schemaEntry?.type) { const validationResult = validateFieldType(key, resolvedValue, schemaEntry.type, { valueOptions: schemaEntry.options, - strict: !resourceMapperField.attemptToConvertTypes, - parseStrings: !!resourceMapperField.convertFieldsToString, + strict: resourceMapperField.attemptToConvertTypes === false, + parseStrings: Boolean(resourceMapperField.convertFieldsToString), }); if (!validationResult.valid) { diff --git a/packages/workflow/src/Interfaces.ts b/packages/workflow/src/Interfaces.ts index 1d64f3e8fc..ab04bd429e 100644 --- a/packages/workflow/src/Interfaces.ts +++ b/packages/workflow/src/Interfaces.ts @@ -2722,8 +2722,8 @@ export type ResourceMapperValue = { value: { [key: string]: string | number | boolean | null } | null; matchingColumns: string[]; schema: ResourceMapperField[]; - attemptToConvertTypes: boolean; - convertFieldsToString: boolean; + attemptToConvertTypes?: boolean; + convertFieldsToString?: boolean; }; export type FilterOperatorType =