n8n-nodes-notion-advanced 1.2.19-beta → 1.2.21-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -43,7 +43,9 @@ export declare class NotionAITool implements INodeType {
43
43
  }[]): string;
44
44
  static getUtf8BytePosition(str: string, charIndex: number): number;
45
45
  static buildXMLTree(content: string, tagProcessors: any[]): XMLNode[];
46
- static processXMLTreeDepthFirst(nodes: XMLNode[], blocks: IDataObject[], placeholderPrefix: string): Map<string, string>;
46
+ static processXMLTreeDepthFirst(nodes: XMLNode[], blocks: IDataObject[], placeholderPrefix: string, placeholderCounter: {
47
+ value: number;
48
+ }): Map<string, string>;
47
49
  static applyHierarchicalReplacements(content: string, nodes: XMLNode[], replacements: Map<string, string>): string;
48
50
  static getAllNodesFromTree(nodes: XMLNode[]): XMLNode[];
49
51
  static processXmlTags(content: string, blocks: IDataObject[]): string;
@@ -480,7 +480,7 @@ class NotionAITool {
480
480
  for (let i = 0; i < lines.length; i++) {
481
481
  const line = lines[i];
482
482
  const trimmedLine = line.trim();
483
- // Skip completely empty lines and XML placeholders (now using dynamic prefix check)
483
+ // Skip completely empty lines and XML placeholders (consistent format check)
484
484
  if (!trimmedLine || /__XML_[a-f0-9]{8}_\d+__/.test(trimmedLine))
485
485
  continue;
486
486
  // Skip lines that contain XML tag patterns (to prevent double processing)
@@ -789,9 +789,8 @@ class NotionAITool {
789
789
  return rootNodes;
790
790
  }
791
791
  // Process XML tree depth-first (children before parents)
792
- static processXMLTreeDepthFirst(nodes, blocks, placeholderPrefix) {
792
+ static processXMLTreeDepthFirst(nodes, blocks, placeholderPrefix, placeholderCounter) {
793
793
  const replacements = new Map();
794
- let blockCounter = 0;
795
794
  const processNode = (node) => {
796
795
  // First, process all children depth-first
797
796
  for (const child of node.children) {
@@ -835,14 +834,14 @@ class NotionAITool {
835
834
  // Handle special list processors
836
835
  if (node.listProcessor && (node.tagName === 'ul' || node.tagName === 'ol')) {
837
836
  node.listProcessor(innerContent, blocks);
838
- return `${placeholderPrefix}${blockCounter++}__`;
837
+ return `${placeholderPrefix}${placeholderCounter.value++}__`;
839
838
  }
840
839
  // Use blockCreator to create the block
841
840
  const block = node.processor(...node.groups);
842
841
  if (block) {
843
842
  blocks.push(block);
844
843
  }
845
- return `${placeholderPrefix}${blockCounter++}__`;
844
+ return `${placeholderPrefix}${placeholderCounter.value++}__`;
846
845
  }
847
846
  catch (error) {
848
847
  console.warn(`Error processing XML node ${node.tagName}:`, error);
@@ -888,8 +887,10 @@ class NotionAITool {
888
887
  // New hierarchical XML-like tag processing function
889
888
  static processXmlTags(content, blocks) {
890
889
  let processedContent = content;
891
- // Generate unique placeholder prefix to avoid collisions
892
- const placeholderPrefix = `__XML_${(0, crypto_1.randomUUID)().slice(0, 8)}_`;
890
+ // Generate consistent placeholder format: __XML_{uuid8}_{counter}__
891
+ const placeholderUuid = (0, crypto_1.randomUUID)().slice(0, 8);
892
+ const placeholderPrefix = `__XML_${placeholderUuid}_`;
893
+ let placeholderCounter = 0;
893
894
  // Debug mode for development
894
895
  const DEBUG_ORDERING = process.env.NODE_ENV === 'development';
895
896
  // Define all tag processors
@@ -1128,30 +1129,6 @@ class NotionAITool {
1128
1129
  return null;
1129
1130
  }
1130
1131
  },
1131
- // Strong/Bold: <strong>content</strong> or <b>content</b> (only as standalone)
1132
- {
1133
- regex: /(?:^|>|\s)<(strong|b)>(.*?)<\/(strong|b)>(?=<|$|\s)/gis,
1134
- blockCreator: (tag, content) => {
1135
- return {
1136
- type: 'paragraph',
1137
- paragraph: {
1138
- rich_text: NotionAITool.parseBasicMarkdown(`**${content.trim()}**`),
1139
- },
1140
- };
1141
- }
1142
- },
1143
- // Emphasis/Italic: <em>content</em> or <i>content</i> (only as standalone)
1144
- {
1145
- regex: /(?:^|>|\s)<(em|i)>(.*?)<\/(em|i)>(?=<|$|\s)/gis,
1146
- blockCreator: (tag, content) => {
1147
- return {
1148
- type: 'paragraph',
1149
- paragraph: {
1150
- rich_text: NotionAITool.parseBasicMarkdown(`*${content.trim()}*`),
1151
- },
1152
- };
1153
- }
1154
- },
1155
1132
  // Line breaks: <br/> or <br>
1156
1133
  {
1157
1134
  regex: /<br\s*\/?>/gis,
@@ -1177,7 +1154,8 @@ class NotionAITool {
1177
1154
  })));
1178
1155
  }
1179
1156
  // Step 2: Process tree depth-first (children before parents)
1180
- const replacements = NotionAITool.processXMLTreeDepthFirst(xmlTree, blocks, placeholderPrefix);
1157
+ const counterRef = { value: 0 };
1158
+ const replacements = NotionAITool.processXMLTreeDepthFirst(xmlTree, blocks, placeholderPrefix, counterRef);
1181
1159
  // Step 3: Apply hierarchical replacements to content
1182
1160
  processedContent = NotionAITool.applyHierarchicalReplacements(processedContent, xmlTree, replacements);
1183
1161
  // Step 4: Clean up any remaining HTML tags
@@ -1204,7 +1182,7 @@ class NotionAITool {
1204
1182
  if (block) {
1205
1183
  blocks.push(block);
1206
1184
  }
1207
- return `${placeholderPrefix}${Math.random()}__`;
1185
+ return `${placeholderPrefix}${placeholderCounter++}__`;
1208
1186
  }
1209
1187
  catch (error) {
1210
1188
  console.warn('Error in fallback processor:', error);
@@ -1236,29 +1214,16 @@ class NotionAITool {
1236
1214
  // Cleanup function to remove remaining HTML tags and XML_BLOCK artifacts
1237
1215
  static cleanupRemainingHtml(content, placeholderPrefix) {
1238
1216
  let cleaned = content;
1239
- // Remove XML_BLOCK placeholder artifacts (support both old and new format)
1217
+ // Simplified placeholder cleanup - use one consistent pattern
1240
1218
  if (placeholderPrefix) {
1241
- // More aggressive placeholder cleanup with multiple patterns
1242
- const placeholderPatterns = [
1243
- new RegExp(`${placeholderPrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\d+__`, 'g'),
1244
- new RegExp(`_${placeholderPrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\d+_`, 'g'),
1245
- new RegExp(`${placeholderPrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\d+`, 'g')
1246
- ];
1247
- placeholderPatterns.forEach(pattern => {
1248
- cleaned = cleaned.replace(pattern, '');
1249
- });
1219
+ // Clean up our specific placeholder format: __XML_{uuid8}_{number}__
1220
+ const escapedPrefix = placeholderPrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1221
+ const placeholderPattern = new RegExp(`${escapedPrefix}\\d+__`, 'g');
1222
+ cleaned = cleaned.replace(placeholderPattern, '');
1250
1223
  }
1251
- // Comprehensive fallback cleanup for all possible placeholder formats
1252
- const fallbackPatterns = [
1253
- /__XML_BLOCK_\d+__/g,
1254
- /__XML_[a-f0-9]{8}_\d+__/g,
1255
- /_XML_[a-f0-9]{8}_\d+_/g,
1256
- /__XML_[a-f0-9-]+_\d+__/g,
1257
- /_XML_[a-f0-9-]+_\d+_/g
1258
- ];
1259
- fallbackPatterns.forEach(pattern => {
1260
- cleaned = cleaned.replace(pattern, '');
1261
- });
1224
+ // Single fallback cleanup for the standard format only
1225
+ const standardPlaceholderPattern = /__XML_[a-f0-9]{8}_\d+__/g;
1226
+ cleaned = cleaned.replace(standardPlaceholderPattern, '');
1262
1227
  // Remove entire lines containing XML content to prevent double processing
1263
1228
  const xmlContentLines = [
1264
1229
  /^.*<[^>]+>.*$/gm, // Any line with XML/HTML tags
@@ -1307,20 +1272,6 @@ class NotionAITool {
1307
1272
  cleaned = cleaned.replace(/^\s*[\r\n]/gm, '');
1308
1273
  // Remove multiple consecutive line breaks
1309
1274
  cleaned = cleaned.replace(/\n{3,}/g, '\n\n');
1310
- // Remove lines that contain only XML_BLOCK artifacts (more patterns)
1311
- const artifactPatterns = [
1312
- /^.*__XML_BLOCK_\d+__.*$/gm,
1313
- /^.*__XML_[a-f0-9]{8}_\d+__.*$/gm,
1314
- /^.*_XML_[a-f0-9]{8}_\d+_.*$/gm,
1315
- /^.*__XML_[a-f0-9-]+_\d+__.*$/gm,
1316
- /^.*_XML_[a-f0-9-]+_\d+_.*$/gm
1317
- ];
1318
- artifactPatterns.forEach(pattern => {
1319
- cleaned = cleaned.replace(pattern, '');
1320
- });
1321
- // Final cleanup of any remaining isolated placeholder patterns
1322
- cleaned = cleaned.replace(/\b_+XML_[a-f0-9-]+_\d+_*\b/g, '');
1323
- cleaned = cleaned.replace(/\b_*XML_[a-f0-9-]+_\d+_+\b/g, '');
1324
1275
  return cleaned.trim();
1325
1276
  }
1326
1277
  // Helper function to process nested HTML elements in list items
@@ -1389,12 +1340,12 @@ class NotionAITool {
1389
1340
  // Helper function to convert inline HTML to markdown
1390
1341
  static convertInlineHtmlToMarkdown(content) {
1391
1342
  let processed = content;
1392
- // Convert HTML formatting tags to markdown equivalents
1343
+ // Convert HTML formatting tags to markdown equivalents - process in order to handle nested tags
1393
1344
  const htmlToMarkdown = [
1394
1345
  { regex: /<strong\s*[^>]*>(.*?)<\/strong>/gis, replacement: '**$1**' },
1395
1346
  { regex: /<b\s*[^>]*>(.*?)<\/b>/gis, replacement: '**$1**' },
1396
- { regex: /<em\s*[^>]*>(.*?)<\/em>/gis, replacement: '*$1*' },
1397
- { regex: /<i\s*[^>]*>(.*?)<\/i>/gis, replacement: '*$1*' },
1347
+ { regex: /<em\s*[^>]*>(.*?)<\/em>/gis, replacement: '_$1_' }, // Use underscore to avoid conflicts
1348
+ { regex: /<i\s*[^>]*>(.*?)<\/i>/gis, replacement: '_$1_' }, // Use underscore to avoid conflicts
1398
1349
  { regex: /<code\s*[^>]*>(.*?)<\/code>/gis, replacement: '`$1`' },
1399
1350
  { regex: /<a\s+href="([^"]*)"[^>]*>(.*?)<\/a>/gis, replacement: '[$2]($1)' },
1400
1351
  { regex: /<u\s*[^>]*>(.*?)<\/u>/gis, replacement: '$1' }, // Notion doesn't support underline
@@ -1536,7 +1487,8 @@ class NotionAITool {
1536
1487
  { regex: /\[([^\]]+)\]\(([^)]+)\)/g, type: 'link' }, // [text](url)
1537
1488
  { regex: /\*\*\*([^*]+)\*\*\*/g, type: 'bold_italic' }, // ***bold italic***
1538
1489
  { regex: /\*\*([^*]+)\*\*/g, type: 'bold' }, // **bold**
1539
- { regex: /\*([^*]+)\*/g, type: 'italic' }, // *italic*
1490
+ { regex: /_([^_]+)_/g, type: 'italic' }, // _italic_ (changed from *)
1491
+ { regex: /\*([^*]+)\*/g, type: 'italic' }, // *italic* (keep for backward compatibility)
1540
1492
  { regex: /~~([^~]+)~~/g, type: 'strikethrough' }, // ~~strikethrough~~
1541
1493
  { regex: /`([^`]+)`/g, type: 'code' }, // `code`
1542
1494
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-notion-advanced",
3
- "version": "1.2.19-beta",
3
+ "version": "1.2.21-beta",
4
4
  "description": "Advanced n8n Notion nodes: Full-featured workflow node + AI Agent Tool for intelligent Notion automation with 25+ block types (BETA)",
5
5
  "scripts": {},
6
6
  "files": [