diff --git a/packages/nodes-base/nodes/Notion/GenericFunctions.ts b/packages/nodes-base/nodes/Notion/GenericFunctions.ts index 1fc6871087..f338c33cfd 100644 --- a/packages/nodes-base/nodes/Notion/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Notion/GenericFunctions.ts @@ -15,6 +15,7 @@ import { INodeProperties, IPollFunctions, NodeApiError, + NodeOperationError, } from 'n8n-workflow'; import { camelCase, capitalCase, snakeCase } from 'change-case'; @@ -25,6 +26,22 @@ import moment from 'moment-timezone'; import { validate as uuidValidate } from 'uuid'; +function uuidValidateWithoutDashes(this: IExecuteFunctions, value: string) { + if (!value || typeof value !== 'string') return false; + if (uuidValidate(value)) return true; + if (value.length == 32) { + //prettier-ignore + const strWithDashes = `${value.slice(0, 8)}-${value.slice(8, 12)}-${value.slice(12, 16)}-${value.slice(16, 20)}-${value.slice(20)}`; + if (uuidValidate(strWithDashes)) return true; + } + throw new NodeOperationError( + this.getNode(), + `The relation id "${value}" is not a valid uuid with optional dashes.`, + ); +} + +export type SortData = { key: string; type: string; direction: string; timestamp: boolean }; + const apiVersion: { [key: number]: string } = { 1: '2021-05-13', 2: '2021-08-16', @@ -261,7 +278,13 @@ function getDateFormat(includeTime: boolean) { return ''; } -function getPropertyKeyValue(value: any, type: string, timezone: string, version = 1) { +function getPropertyKeyValue( + this: IExecuteFunctions, + value: any, + type: string, + timezone: string, + version = 1, +) { const ignoreIfEmpty = (v: T, cb: (v: T) => any) => !v && value.ignoreIfEmpty ? undefined : cb(v); let result: IDataObject = {}; @@ -289,10 +312,13 @@ function getPropertyKeyValue(value: any, type: string, timezone: string, version case 'relation': result = { type: 'relation', - - relation: value.relationValue.reduce((acc: [], cur: any) => { - return acc.concat(cur.split(',').map((relation: string) => ({ id: relation.trim() }))); - }, []), + relation: value.relationValue + .filter((rv: string) => { + return uuidValidateWithoutDashes.call(this, rv); + }) + .reduce((acc: [], cur: any) => { + return acc.concat(cur.split(',').map((relation: string) => ({ id: relation.trim() }))); + }, []), }; break; case 'multi_select': @@ -392,7 +418,12 @@ function getNameAndType(key: string) { }; } -export function mapProperties(properties: IDataObject[], timezone: string, version = 1) { +export function mapProperties( + this: IExecuteFunctions, + properties: IDataObject[], + timezone: string, + version = 1, +) { return properties .filter( (property): property is Record => @@ -402,7 +433,7 @@ export function mapProperties(properties: IDataObject[], timezone: string, versi (property) => [ `${property.key.split('|')[0]}`, - getPropertyKeyValue(property, property.key.split('|')[1], timezone, version), + getPropertyKeyValue.call(this, property, property.key.split('|')[1], timezone, version), ] as const, ) .filter(([, value]) => value) @@ -415,9 +446,7 @@ export function mapProperties(properties: IDataObject[], timezone: string, versi ); } -export function mapSorting( - data: [{ key: string; type: string; direction: string; timestamp: boolean }], -) { +export function mapSorting(data: SortData[]) { return data.map((sort) => { return { direction: sort.direction, diff --git a/packages/nodes-base/nodes/Notion/v1/NotionV1.node.ts b/packages/nodes-base/nodes/Notion/v1/NotionV1.node.ts index 35678ecdbd..a7de180182 100644 --- a/packages/nodes-base/nodes/Notion/v1/NotionV1.node.ts +++ b/packages/nodes-base/nodes/Notion/v1/NotionV1.node.ts @@ -359,7 +359,7 @@ export class NotionV1 implements INodeType { [], ) as IDataObject[]; if (properties.length !== 0) { - body.properties = mapProperties(properties, timezone) as IDataObject; + body.properties = mapProperties.call(this, properties, timezone) as IDataObject; } const blockValues = this.getNodeParameter('blockUi.blockValues', i, []) as IDataObject[]; extractDatabaseMentionRLC(blockValues); @@ -460,7 +460,7 @@ export class NotionV1 implements INodeType { properties: {}, }; if (properties.length !== 0) { - body.properties = mapProperties(properties, timezone) as IDataObject; + body.properties = mapProperties.call(this, properties, timezone) as IDataObject; } responseData = await notionApiRequest.call(this, 'PATCH', `/pages/${pageId}`, body); if (simple) { diff --git a/packages/nodes-base/nodes/Notion/v2/NotionV2.node.ts b/packages/nodes-base/nodes/Notion/v2/NotionV2.node.ts index 0fc5916d83..1d1173e613 100644 --- a/packages/nodes-base/nodes/Notion/v2/NotionV2.node.ts +++ b/packages/nodes-base/nodes/Notion/v2/NotionV2.node.ts @@ -26,6 +26,7 @@ import { notionApiRequest, notionApiRequestAllItems, simplifyObjects, + SortData, validateJSON, } from '../GenericFunctions'; @@ -457,7 +458,7 @@ export class NotionV2 implements INodeType { if (propertiesValues.length !== 0) { body.properties = Object.assign( body.properties, - mapProperties(propertiesValues, timezone, 2) as IDataObject, + mapProperties.call(this, propertiesValues, timezone, 2) as IDataObject, ); } const blockValues = this.getNodeParameter('blockUi.blockValues', i, []) as IDataObject[]; @@ -536,8 +537,7 @@ export class NotionV2 implements INodeType { delete body.filter; } if (sort) { - //@ts-expect-error - body.sorts = mapSorting(sort); + body.sorts = mapSorting(sort as SortData[]); } if (returnAll) { responseData = await notionApiRequestAllItems.call( @@ -590,7 +590,7 @@ export class NotionV2 implements INodeType { properties: {}, }; if (properties.length !== 0) { - body.properties = mapProperties(properties, timezone, 2) as IDataObject; + body.properties = mapProperties.call(this, properties, timezone, 2) as IDataObject; } responseData = await notionApiRequest.call(this, 'PATCH', `/pages/${pageId}`, body); if (simple) {