diff --git a/packages/core/src/Interfaces.ts b/packages/core/src/Interfaces.ts index 000f2a8125..66162ae171 100644 --- a/packages/core/src/Interfaces.ts +++ b/packages/core/src/Interfaces.ts @@ -37,4 +37,4 @@ export namespace n8n { } } -export type ExtendedValidationResult = Partial & { fieldName?: string }; +export type ExtendedValidationResult = ValidationResult & { fieldName?: string }; diff --git a/packages/core/src/NodeExecuteFunctions.ts b/packages/core/src/NodeExecuteFunctions.ts index 5b374460fd..50bd416986 100644 --- a/packages/core/src/NodeExecuteFunctions.ts +++ b/packages/core/src/NodeExecuteFunctions.ts @@ -99,6 +99,7 @@ import type { WorkflowActivateMode, WorkflowExecuteMode, CallbackManager, + INodeParameters, } from 'n8n-workflow'; import { ExpressionError, @@ -2121,13 +2122,12 @@ export function cleanupParameterData(inputData: NodeParameterValueType): void { } if (typeof inputData === 'object') { - type Key = keyof typeof inputData; - (Object.keys(inputData) as Key[]).forEach((key) => { - const value = inputData[key]; + Object.keys(inputData).forEach((key) => { + const value = (inputData as INodeParameters)[key]; if (typeof value === 'object') { if (DateTime.isDateTime(value)) { // Is a special luxon date so convert to string - inputData[key] = value.toString(); + (inputData as INodeParameters)[key] = value.toString(); } else { cleanupParameterData(value); } @@ -2230,28 +2230,30 @@ const validateCollection = ( return validationResult; } - for (const value of Array.isArray(validationResult.newValue) - ? (validationResult.newValue as IDataObject[]) - : [validationResult.newValue as IDataObject]) { - for (const key of Object.keys(value)) { - if (!validationMap[key]) continue; + if (validationResult.valid) { + for (const value of Array.isArray(validationResult.newValue) + ? (validationResult.newValue as IDataObject[]) + : [validationResult.newValue as IDataObject]) { + for (const key of Object.keys(value)) { + if (!validationMap[key]) continue; - const fieldValidationResult = validateFieldType(key, value[key], validationMap[key].type, { - valueOptions: validationMap[key].options, - }); + const fieldValidationResult = validateFieldType(key, value[key], validationMap[key].type, { + valueOptions: validationMap[key].options, + }); - if (!fieldValidationResult.valid) { - throw new ExpressionError( - `Invalid input for field '${validationMap[key].displayName}' inside '${propertyDescription.displayName}' in [item ${itemIndex}]`, - { - description: fieldValidationResult.errorMessage, - runIndex, - itemIndex, - nodeCause: node.name, - }, - ); + if (!fieldValidationResult.valid) { + throw new ExpressionError( + `Invalid input for field '${validationMap[key].displayName}' inside '${propertyDescription.displayName}' in [item ${itemIndex}]`, + { + description: fieldValidationResult.errorMessage, + runIndex, + itemIndex, + nodeCause: node.name, + }, + ); + } + value[key] = fieldValidationResult.newValue; } - value[key] = fieldValidationResult.newValue; } } diff --git a/packages/editor-ui/src/Interface.ts b/packages/editor-ui/src/Interface.ts index 110c2df88b..f859bed7a0 100644 --- a/packages/editor-ui/src/Interface.ts +++ b/packages/editor-ui/src/Interface.ts @@ -130,15 +130,17 @@ export type EndpointStyle = { hoverMessage?: string; }; -export interface IUpdateInformation { - name: string; - key?: string; - value: +export interface IUpdateInformation< + T extends NodeParameterValueType = | string | number | { [key: string]: string | number | boolean } | NodeParameterValueType - | INodeParameters; // with null makes problems in NodeSettings.vue + | INodeParameters, +> { + name: string; + key?: string; + value: T; node?: string; oldValue?: string | number; type?: 'optionsOrderChanged'; diff --git a/packages/editor-ui/src/components/CodeNodeEditor/linter.ts b/packages/editor-ui/src/components/CodeNodeEditor/linter.ts index d64d4f83cd..2613abd68b 100644 --- a/packages/editor-ui/src/components/CodeNodeEditor/linter.ts +++ b/packages/editor-ui/src/components/CodeNodeEditor/linter.ts @@ -1,20 +1,27 @@ -import { defineComponent } from 'vue'; import type { Diagnostic } from '@codemirror/lint'; import { linter as createLinter } from '@codemirror/lint'; import type { EditorView } from '@codemirror/view'; import * as esprima from 'esprima-next'; import type { Node } from 'estree'; -import type { CodeNodeEditorLanguage } from 'n8n-workflow'; +import type { CodeExecutionMode, CodeNodeEditorLanguage } from 'n8n-workflow'; +import { type PropType, defineComponent } from 'vue'; import { DEFAULT_LINTER_DELAY_IN_MS, DEFAULT_LINTER_SEVERITY, OFFSET_FOR_SCRIPT_WRAPPER, } from './constants'; -import { walk } from './utils'; import type { RangeNode } from './types'; +import { walk } from './utils'; export const linterExtension = defineComponent({ + props: { + mode: { + type: String as PropType, + required: true, + }, + editor: { type: Object as PropType, default: null }, + }, methods: { createLinter(language: CodeNodeEditorLanguage) { switch (language) { diff --git a/packages/editor-ui/src/components/CollectionParameter.vue b/packages/editor-ui/src/components/CollectionParameter.vue index 55d25ee405..37c5e3d75f 100644 --- a/packages/editor-ui/src/components/CollectionParameter.vue +++ b/packages/editor-ui/src/components/CollectionParameter.vue @@ -72,7 +72,7 @@ export interface Props { nodeValues: INodeParameters; parameter: INodeProperties; path: string; - values: INodeProperties; + values: INodeParameters; isReadOnly?: boolean; } const emit = defineEmits<{ diff --git a/packages/editor-ui/src/components/ExpandableInput/ExpandableInputEdit.vue b/packages/editor-ui/src/components/ExpandableInput/ExpandableInputEdit.vue index ec9838d429..3d378ea313 100644 --- a/packages/editor-ui/src/components/ExpandableInput/ExpandableInputEdit.vue +++ b/packages/editor-ui/src/components/ExpandableInput/ExpandableInputEdit.vue @@ -25,14 +25,18 @@ export default defineComponent({ name: 'ExpandableInputEdit', components: { ExpandableInputBase }, props: { - modelValue: {}, - placeholder: {}, - maxlength: {}, - autofocus: {}, + modelValue: { + type: String, + required: true, + }, + placeholder: { type: String, required: true }, + maxlength: { type: Number }, + autofocus: { type: Boolean }, eventBus: { type: Object as PropType, }, }, + emits: ['update:modelValue', 'enter', 'blur', 'esc'], mounted() { // autofocus on input element is not reliable if (this.autofocus && this.$refs.input) { diff --git a/packages/editor-ui/src/components/ExpressionEdit.vue b/packages/editor-ui/src/components/ExpressionEdit.vue index 7e4deea9a2..e61b4dbe05 100644 --- a/packages/editor-ui/src/components/ExpressionEdit.vue +++ b/packages/editor-ui/src/components/ExpressionEdit.vue @@ -80,7 +80,7 @@