From 46beda05f6771c31bcf0b6a781976d8261079a66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=A4=95=E0=A4=BE=E0=A4=B0=E0=A4=A4=E0=A5=8B=E0=A4=AB?= =?UTF-8?q?=E0=A5=8D=E0=A4=AB=E0=A5=87=E0=A4=B2=E0=A4=B8=E0=A5=8D=E0=A4=95?= =?UTF-8?q?=E0=A5=8D=E0=A4=B0=E0=A4=BF=E0=A4=AA=E0=A5=8D=E0=A4=9F=E2=84=A2?= Date: Tue, 24 Sep 2024 12:38:11 +0200 Subject: [PATCH] fix(Notion Node): Allow UUID v8 in notion id checks (#10938) --- .../nodes/Notion/NotionTrigger.node.ts | 17 +++--- .../nodes/Notion/shared/GenericFunctions.ts | 4 +- .../nodes/Notion/shared/constants.ts | 15 ++++++ .../shared/descriptions/BlockDescription.ts | 33 ++++++------ .../Notion/shared/descriptions/Blocks.ts | 17 +++--- .../descriptions/DatabaseDescription.ts | 17 +++--- .../descriptions/DatabasePageDescription.ts | 52 +++++++++---------- .../shared/descriptions/PageDescription.ts | 28 +++++----- .../Notion/test/GenericFunctions.test.ts | 5 +- 9 files changed, 103 insertions(+), 85 deletions(-) create mode 100644 packages/nodes-base/nodes/Notion/shared/constants.ts diff --git a/packages/nodes-base/nodes/Notion/NotionTrigger.node.ts b/packages/nodes-base/nodes/Notion/NotionTrigger.node.ts index e7aa79c431..49079c3c81 100644 --- a/packages/nodes-base/nodes/Notion/NotionTrigger.node.ts +++ b/packages/nodes-base/nodes/Notion/NotionTrigger.node.ts @@ -11,6 +11,12 @@ import moment from 'moment-timezone'; import { notionApiRequest, simplifyObjects } from './shared/GenericFunctions'; import { listSearch } from './shared/methods'; +import { + databaseUrlExtractionRegexp, + databaseUrlValidationRegexp, + idExtractionRegexp, + idValidationRegexp, +} from './shared/constants'; export class NotionTrigger implements INodeType { description: INodeTypeDescription = { @@ -85,16 +91,14 @@ export class NotionTrigger implements INodeType { { type: 'regex', properties: { - regex: - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12}).*', + regex: databaseUrlValidationRegexp, errorMessage: 'Not a valid Notion Database URL', }, }, ], extractValue: { type: 'regex', - regex: - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12})', + regex: databaseUrlExtractionRegexp, }, }, { @@ -106,15 +110,14 @@ export class NotionTrigger implements INodeType { { type: 'regex', properties: { - regex: - '^(([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12})|([0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}))[ \t]*', + regex: idValidationRegexp, errorMessage: 'Not a valid Notion Database ID', }, }, ], extractValue: { type: 'regex', - regex: '^([0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12})', + regex: idExtractionRegexp, }, url: '=https://www.notion.so/{{$value.replace(/-/g, "")}}', }, diff --git a/packages/nodes-base/nodes/Notion/shared/GenericFunctions.ts b/packages/nodes-base/nodes/Notion/shared/GenericFunctions.ts index 1b6ba6563d..2fd594756f 100644 --- a/packages/nodes-base/nodes/Notion/shared/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Notion/shared/GenericFunctions.ts @@ -23,6 +23,7 @@ import moment from 'moment-timezone'; import { validate as uuidValidate } from 'uuid'; import set from 'lodash/set'; import { filters } from './descriptions/Filters'; +import { blockUrlExtractionRegexp } from './constants'; function uuidValidateWithoutDashes(this: IExecuteFunctions, value: string) { if (uuidValidate(value)) return true; @@ -1152,8 +1153,7 @@ export function extractBlockId(this: IExecuteFunctions, nodeVersion: number, ite const match = (blockIdRLCData.value as string).match(blockRegex); if (match === null) { - const pageRegex = - /(?:https|http):\/\/www\.notion\.so\/(?:[a-z0-9-]{2,}\/)?(?:[a-zA-Z0-9-]{2,}-)?([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12})/; + const pageRegex = new RegExp(blockUrlExtractionRegexp); const pageMatch = (blockIdRLCData.value as string).match(pageRegex); if (pageMatch === null) { diff --git a/packages/nodes-base/nodes/Notion/shared/constants.ts b/packages/nodes-base/nodes/Notion/shared/constants.ts new file mode 100644 index 0000000000..d2121741e5 --- /dev/null +++ b/packages/nodes-base/nodes/Notion/shared/constants.ts @@ -0,0 +1,15 @@ +const notionIdRegexp = '[0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12}'; + +export const idExtractionRegexp = `^(${notionIdRegexp})`; +export const idValidationRegexp = `${idExtractionRegexp}.*`; + +const baseUrlRegexp = '(?:https|http)://www\\.notion\\.so/(?:[a-z0-9-]{2,}/)?'; + +export const databaseUrlExtractionRegexp = `${baseUrlRegexp}(${notionIdRegexp})`; +export const databaseUrlValidationRegexp = `${databaseUrlExtractionRegexp}.*`; + +export const databasePageUrlExtractionRegexp = `${baseUrlRegexp}(?:[a-zA-Z0-9-]{1,}-)?(${notionIdRegexp})`; +export const databasePageUrlValidationRegexp = `${databasePageUrlExtractionRegexp}.*`; + +export const blockUrlExtractionRegexp = `${baseUrlRegexp}(?:[a-zA-Z0-9-]{2,}-)?(${notionIdRegexp})`; +export const blockUrlValidationRegexp = `${blockUrlExtractionRegexp}.*`; diff --git a/packages/nodes-base/nodes/Notion/shared/descriptions/BlockDescription.ts b/packages/nodes-base/nodes/Notion/shared/descriptions/BlockDescription.ts index fbb48ce26b..a2cab6049f 100644 --- a/packages/nodes-base/nodes/Notion/shared/descriptions/BlockDescription.ts +++ b/packages/nodes-base/nodes/Notion/shared/descriptions/BlockDescription.ts @@ -1,6 +1,12 @@ import type { INodeProperties } from 'n8n-workflow'; import { blocks } from './Blocks'; +import { + blockUrlExtractionRegexp, + blockUrlValidationRegexp, + idExtractionRegexp, + idValidationRegexp, +} from '../constants'; //RLC with fixed regex for blockId const blockIdRLC: INodeProperties = { @@ -20,15 +26,14 @@ const blockIdRLC: INodeProperties = { { type: 'regex', properties: { - regex: - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?(?:[a-zA-Z0-9-]{2,}-)?([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12}).*', + regex: blockUrlValidationRegexp, errorMessage: 'Not a valid Notion Block URL', }, }, ], // extractValue: { // type: 'regex', - // regex: 'https:\\/\\/www\\.notion\\.so\\/.+\\?pvs=[0-9]+#([a-f0-9]{2,})', + // regex: blockUrlExtractionRegexp, // }, }, { @@ -101,16 +106,14 @@ export const blockFields: INodeProperties[] = [ { type: 'regex', properties: { - regex: - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?(?:[a-zA-Z0-9-]{2,}-)?([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12}).*', + regex: blockUrlValidationRegexp, errorMessage: 'Not a valid Notion Block URL', }, }, ], extractValue: { type: 'regex', - regex: - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?(?:[a-zA-Z0-9-]{2,}-)?([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12})', + regex: blockUrlExtractionRegexp, }, }, { @@ -122,15 +125,14 @@ export const blockFields: INodeProperties[] = [ { type: 'regex', properties: { - regex: - '^(([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12})|([0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}))[ \t]*', + regex: idValidationRegexp, errorMessage: 'Not a valid Notion Block ID', }, }, ], extractValue: { type: 'regex', - regex: '^([0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12})', + regex: idExtractionRegexp, }, url: '=https://www.notion.so/{{$value.replace(/-/g, "")}}', }, @@ -176,16 +178,14 @@ export const blockFields: INodeProperties[] = [ { type: 'regex', properties: { - regex: - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?(?:[a-zA-Z0-9-]{2,}-)?([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12}).*', + regex: blockUrlValidationRegexp, errorMessage: 'Not a valid Notion Block URL', }, }, ], extractValue: { type: 'regex', - regex: - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?(?:[a-zA-Z0-9-]{2,}-)?([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12})', + regex: blockUrlExtractionRegexp, }, }, { @@ -197,15 +197,14 @@ export const blockFields: INodeProperties[] = [ { type: 'regex', properties: { - regex: - '^(([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12})|([0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}))[ \t]*', + regex: idValidationRegexp, errorMessage: 'Not a valid Notion Block ID', }, }, ], extractValue: { type: 'regex', - regex: '^([0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12})', + regex: idExtractionRegexp, }, url: '=https://www.notion.so/{{$value.replace(/-/g, "")}}', }, diff --git a/packages/nodes-base/nodes/Notion/shared/descriptions/Blocks.ts b/packages/nodes-base/nodes/Notion/shared/descriptions/Blocks.ts index 3efaef484e..3b49e23fbe 100644 --- a/packages/nodes-base/nodes/Notion/shared/descriptions/Blocks.ts +++ b/packages/nodes-base/nodes/Notion/shared/descriptions/Blocks.ts @@ -1,4 +1,10 @@ import type { IDisplayOptions, INodeProperties } from 'n8n-workflow'; +import { + databaseUrlExtractionRegexp, + databaseUrlValidationRegexp, + idExtractionRegexp, + idValidationRegexp, +} from '../constants'; const colors = [ { @@ -221,16 +227,14 @@ const typeMention: INodeProperties[] = [ { type: 'regex', properties: { - regex: - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12}).*', + regex: databaseUrlValidationRegexp, errorMessage: 'Not a valid Notion Database URL', }, }, ], extractValue: { type: 'regex', - regex: - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12})', + regex: databaseUrlExtractionRegexp, }, }, { @@ -242,15 +246,14 @@ const typeMention: INodeProperties[] = [ { type: 'regex', properties: { - regex: - '^(([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12})|([0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}))[ \t]*', + regex: idValidationRegexp, errorMessage: 'Not a valid Notion Database ID', }, }, ], extractValue: { type: 'regex', - regex: '^([0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12})', + regex: idExtractionRegexp, }, url: '=https://www.notion.so/{{$value.replace(/-/g, "")}}', }, diff --git a/packages/nodes-base/nodes/Notion/shared/descriptions/DatabaseDescription.ts b/packages/nodes-base/nodes/Notion/shared/descriptions/DatabaseDescription.ts index aee9c8d886..f814139603 100644 --- a/packages/nodes-base/nodes/Notion/shared/descriptions/DatabaseDescription.ts +++ b/packages/nodes-base/nodes/Notion/shared/descriptions/DatabaseDescription.ts @@ -1,4 +1,10 @@ import type { INodeProperties } from 'n8n-workflow'; +import { + databaseUrlExtractionRegexp, + databaseUrlValidationRegexp, + idExtractionRegexp, + idValidationRegexp, +} from '../constants'; export const databaseOperations: INodeProperties[] = [ { @@ -97,8 +103,7 @@ export const databaseFields: INodeProperties[] = [ { type: 'regex', properties: { - regex: - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12}).*', + regex: databaseUrlValidationRegexp, errorMessage: 'Not a valid Notion Database URL. Hint: use the URL of the database itself, not a page containing it.', }, @@ -106,8 +111,7 @@ export const databaseFields: INodeProperties[] = [ ], extractValue: { type: 'regex', - regex: - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12})', + regex: databaseUrlExtractionRegexp, }, }, { @@ -119,15 +123,14 @@ export const databaseFields: INodeProperties[] = [ { type: 'regex', properties: { - regex: - '^(([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12})|([0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}))[ \t]*', + regex: idValidationRegexp, errorMessage: 'Not a valid Notion Database ID', }, }, ], extractValue: { type: 'regex', - regex: '^([0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12})', + regex: idExtractionRegexp, }, url: '=https://www.notion.so/{{$value.replace(/-/g, "")}}', }, diff --git a/packages/nodes-base/nodes/Notion/shared/descriptions/DatabasePageDescription.ts b/packages/nodes-base/nodes/Notion/shared/descriptions/DatabasePageDescription.ts index c1f4a3749f..1a590457da 100644 --- a/packages/nodes-base/nodes/Notion/shared/descriptions/DatabasePageDescription.ts +++ b/packages/nodes-base/nodes/Notion/shared/descriptions/DatabasePageDescription.ts @@ -5,6 +5,14 @@ import { getConditions, getSearchFilters } from '../GenericFunctions'; import { blocks, text } from './Blocks'; import { filters } from './Filters'; +import { + databaseUrlExtractionRegexp, + databaseUrlValidationRegexp, + databasePageUrlExtractionRegexp, + databasePageUrlValidationRegexp, + idExtractionRegexp, + idValidationRegexp, +} from '../constants'; export const databasePageOperations: INodeProperties[] = [ { @@ -114,16 +122,14 @@ export const databasePageFields: INodeProperties[] = [ { type: 'regex', properties: { - regex: - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12}).*', + regex: databaseUrlValidationRegexp, errorMessage: 'Not a valid Notion Database URL', }, }, ], extractValue: { type: 'regex', - regex: - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12})', + regex: databaseUrlExtractionRegexp, }, }, { @@ -135,15 +141,14 @@ export const databasePageFields: INodeProperties[] = [ { type: 'regex', properties: { - regex: - '^(([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12})|([0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}))[ \t]*', + regex: idValidationRegexp, errorMessage: 'Not a valid Notion Database ID', }, }, ], extractValue: { type: 'regex', - regex: '^([0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12})', + regex: idExtractionRegexp, }, url: '=https://www.notion.so/{{$value.replace(/-/g, "")}}', }, @@ -600,16 +605,14 @@ export const databasePageFields: INodeProperties[] = [ { type: 'regex', properties: { - regex: - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?(?:[a-zA-Z0-9-]{1,}-)?([0-9a-f]{8}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{12}).*', + regex: databasePageUrlValidationRegexp, errorMessage: 'Not a valid Notion Database Page URL', }, }, ], extractValue: { type: 'regex', - regex: - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?(?:[a-zA-Z0-9-]{1,}-)?([0-9a-f]{8}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{12})', + regex: databasePageUrlExtractionRegexp, }, }, { @@ -621,15 +624,14 @@ export const databasePageFields: INodeProperties[] = [ { type: 'regex', properties: { - regex: - '^(([0-9a-f]{8}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{12})|([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}))[ \t]*', + regex: idValidationRegexp, errorMessage: 'Not a valid Notion Database Page ID', }, }, ], extractValue: { type: 'regex', - regex: '^([0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12})', + regex: idExtractionRegexp, }, url: '=https://www.notion.so/{{$value.replace(/-/g, "")}}', }, @@ -1069,16 +1071,14 @@ export const databasePageFields: INodeProperties[] = [ { type: 'regex', properties: { - regex: - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?(?:[a-zA-Z0-9-]{1,}-)?([0-9a-f]{8}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{12}).*', + regex: databasePageUrlValidationRegexp, errorMessage: 'Not a valid Notion Database Page URL', }, }, ], extractValue: { type: 'regex', - regex: - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?(?:[a-zA-Z0-9-]{1,}-)?([0-9a-f]{8}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{12})', + regex: databasePageUrlExtractionRegexp, }, }, { @@ -1090,15 +1090,14 @@ export const databasePageFields: INodeProperties[] = [ { type: 'regex', properties: { - regex: - '^(([0-9a-f]{8}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{12})|([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}))[ \t]*', + regex: idValidationRegexp, errorMessage: 'Not a valid Notion Database Page ID', }, }, ], extractValue: { type: 'regex', - regex: '^([0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12})', + regex: idExtractionRegexp, }, url: '=https://www.notion.so/{{$value.replace(/-/g, "")}}', }, @@ -1160,16 +1159,14 @@ export const databasePageFields: INodeProperties[] = [ { type: 'regex', properties: { - regex: - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?(?:[a-zA-Z0-9-]{1,}-)?([0-9a-f]{8}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{12}).*', + regex: databasePageUrlValidationRegexp, errorMessage: 'Not a valid Notion Database Page URL', }, }, ], extractValue: { type: 'regex', - regex: - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?(?:[a-zA-Z0-9-]{1,}-)?([0-9a-f]{8}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{12})', + regex: databasePageUrlExtractionRegexp, }, }, { @@ -1181,15 +1178,14 @@ export const databasePageFields: INodeProperties[] = [ { type: 'regex', properties: { - regex: - '^(([0-9a-f]{8}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{12})|([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}))[ \t]*', + regex: idValidationRegexp, errorMessage: 'Not a valid Notion Database Page ID', }, }, ], extractValue: { type: 'regex', - regex: '^([0-9a-f]{8}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{4}-?[0-9a-f]{12})', + regex: idExtractionRegexp, }, url: '=https://www.notion.so/{{$value.replace(/-/g, "")}}', }, diff --git a/packages/nodes-base/nodes/Notion/shared/descriptions/PageDescription.ts b/packages/nodes-base/nodes/Notion/shared/descriptions/PageDescription.ts index 93c79fb2cf..37d57799cb 100644 --- a/packages/nodes-base/nodes/Notion/shared/descriptions/PageDescription.ts +++ b/packages/nodes-base/nodes/Notion/shared/descriptions/PageDescription.ts @@ -1,6 +1,12 @@ import type { INodeProperties } from 'n8n-workflow'; import { blocks } from './Blocks'; +import { + databasePageUrlExtractionRegexp, + databasePageUrlValidationRegexp, + idExtractionRegexp, + idValidationRegexp, +} from '../constants'; export const pageOperations: INodeProperties[] = [ { @@ -93,16 +99,14 @@ export const pageFields: INodeProperties[] = [ { type: 'regex', properties: { - regex: - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?(?:[a-zA-Z0-9-]{1,}-)?([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12}).*', + regex: databasePageUrlValidationRegexp, errorMessage: 'Not a valid Notion Database Page URL', }, }, ], extractValue: { type: 'regex', - regex: - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?(?:[a-zA-Z0-9-]{1,}-)?([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12})', + regex: databasePageUrlExtractionRegexp, }, }, { @@ -114,15 +118,14 @@ export const pageFields: INodeProperties[] = [ { type: 'regex', properties: { - regex: - '^(([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12})|([0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}))[ \t]*', + regex: idValidationRegexp, errorMessage: 'Not a valid Notion Page ID', }, }, ], extractValue: { type: 'regex', - regex: '^([0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12})', + regex: idExtractionRegexp, }, url: '=https://www.notion.so/{{$value.replace(/-/g, "")}}', }, @@ -173,16 +176,14 @@ export const pageFields: INodeProperties[] = [ { type: 'regex', properties: { - regex: - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?(?:[a-zA-Z0-9-]{1,}-)?([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12}).*', + regex: databasePageUrlValidationRegexp, errorMessage: 'Not a valid Notion Database Page URL', }, }, ], extractValue: { type: 'regex', - regex: - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?(?:[a-zA-Z0-9-]{1,}-)?([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12})', + regex: databasePageUrlExtractionRegexp, }, }, { @@ -194,15 +195,14 @@ export const pageFields: INodeProperties[] = [ { type: 'regex', properties: { - regex: - '^(([0-9a-f]{8}[0-9a-f]{4}4[0-9a-f]{3}[89ab][0-9a-f]{3}[0-9a-f]{12})|([0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}))[ \t]*', + regex: idValidationRegexp, errorMessage: 'Not a valid Notion Page ID', }, }, ], extractValue: { type: 'regex', - regex: '^([0-9a-f]{8}-?[0-9a-f]{4}-?4[0-9a-f]{3}-?[89ab][0-9a-f]{3}-?[0-9a-f]{12})', + regex: idExtractionRegexp, }, url: '=https://www.notion.so/{{$value.replace(/-/g, "")}}', }, diff --git a/packages/nodes-base/nodes/Notion/test/GenericFunctions.test.ts b/packages/nodes-base/nodes/Notion/test/GenericFunctions.test.ts index 543292abe8..40b01ea18b 100644 --- a/packages/nodes-base/nodes/Notion/test/GenericFunctions.test.ts +++ b/packages/nodes-base/nodes/Notion/test/GenericFunctions.test.ts @@ -1,3 +1,4 @@ +import { databasePageUrlExtractionRegexp } from '../shared/constants'; import { extractPageId, formatBlocks } from '../shared/GenericFunctions'; describe('Test NotionV2, formatBlocks', () => { @@ -41,11 +42,9 @@ describe('Test Notion', () => { 'f4c1217e48f711ef94540242ac120002', // Random v1 UUID ]; describe('extractPageId From URL', () => { - const extractPattern = - '(?:https|http)://www.notion.so/(?:[a-z0-9-]{2,}/)?(?:[a-zA-Z0-9-]{1,}-)?([0-9a-f]{8}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{4}[0-9a-f]{12})'; // RLC does some Regex extraction before extractPageId is called const extractIdFromUrl = (url: string): string => { - const match = url.match(extractPattern); + const match = url.match(databasePageUrlExtractionRegexp); return match ? match[1] : url; };