n8n-nodes-notion-advanced 1.2.20-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
@@ -1153,7 +1154,8 @@ class NotionAITool {
1153
1154
  })));
1154
1155
  }
1155
1156
  // Step 2: Process tree depth-first (children before parents)
1156
- const replacements = NotionAITool.processXMLTreeDepthFirst(xmlTree, blocks, placeholderPrefix);
1157
+ const counterRef = { value: 0 };
1158
+ const replacements = NotionAITool.processXMLTreeDepthFirst(xmlTree, blocks, placeholderPrefix, counterRef);
1157
1159
  // Step 3: Apply hierarchical replacements to content
1158
1160
  processedContent = NotionAITool.applyHierarchicalReplacements(processedContent, xmlTree, replacements);
1159
1161
  // Step 4: Clean up any remaining HTML tags
@@ -1180,7 +1182,7 @@ class NotionAITool {
1180
1182
  if (block) {
1181
1183
  blocks.push(block);
1182
1184
  }
1183
- return `${placeholderPrefix}${Math.random()}__`;
1185
+ return `${placeholderPrefix}${placeholderCounter++}__`;
1184
1186
  }
1185
1187
  catch (error) {
1186
1188
  console.warn('Error in fallback processor:', error);
@@ -1212,29 +1214,16 @@ class NotionAITool {
1212
1214
  // Cleanup function to remove remaining HTML tags and XML_BLOCK artifacts
1213
1215
  static cleanupRemainingHtml(content, placeholderPrefix) {
1214
1216
  let cleaned = content;
1215
- // Remove XML_BLOCK placeholder artifacts (support both old and new format)
1217
+ // Simplified placeholder cleanup - use one consistent pattern
1216
1218
  if (placeholderPrefix) {
1217
- // More aggressive placeholder cleanup with multiple patterns
1218
- const placeholderPatterns = [
1219
- new RegExp(`${placeholderPrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\d+__`, 'g'),
1220
- new RegExp(`_${placeholderPrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\d+_`, 'g'),
1221
- new RegExp(`${placeholderPrefix.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\d+`, 'g')
1222
- ];
1223
- placeholderPatterns.forEach(pattern => {
1224
- cleaned = cleaned.replace(pattern, '');
1225
- });
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, '');
1226
1223
  }
1227
- // Comprehensive fallback cleanup for all possible placeholder formats
1228
- const fallbackPatterns = [
1229
- /__XML_BLOCK_\d+__/g,
1230
- /__XML_[a-f0-9]{8}_\d+__/g,
1231
- /_XML_[a-f0-9]{8}_\d+_/g,
1232
- /__XML_[a-f0-9-]+_\d+__/g,
1233
- /_XML_[a-f0-9-]+_\d+_/g
1234
- ];
1235
- fallbackPatterns.forEach(pattern => {
1236
- cleaned = cleaned.replace(pattern, '');
1237
- });
1224
+ // Single fallback cleanup for the standard format only
1225
+ const standardPlaceholderPattern = /__XML_[a-f0-9]{8}_\d+__/g;
1226
+ cleaned = cleaned.replace(standardPlaceholderPattern, '');
1238
1227
  // Remove entire lines containing XML content to prevent double processing
1239
1228
  const xmlContentLines = [
1240
1229
  /^.*<[^>]+>.*$/gm, // Any line with XML/HTML tags
@@ -1283,20 +1272,6 @@ class NotionAITool {
1283
1272
  cleaned = cleaned.replace(/^\s*[\r\n]/gm, '');
1284
1273
  // Remove multiple consecutive line breaks
1285
1274
  cleaned = cleaned.replace(/\n{3,}/g, '\n\n');
1286
- // Remove lines that contain only XML_BLOCK artifacts (more patterns)
1287
- const artifactPatterns = [
1288
- /^.*__XML_BLOCK_\d+__.*$/gm,
1289
- /^.*__XML_[a-f0-9]{8}_\d+__.*$/gm,
1290
- /^.*_XML_[a-f0-9]{8}_\d+_.*$/gm,
1291
- /^.*__XML_[a-f0-9-]+_\d+__.*$/gm,
1292
- /^.*_XML_[a-f0-9-]+_\d+_.*$/gm
1293
- ];
1294
- artifactPatterns.forEach(pattern => {
1295
- cleaned = cleaned.replace(pattern, '');
1296
- });
1297
- // Final cleanup of any remaining isolated placeholder patterns
1298
- cleaned = cleaned.replace(/\b_+XML_[a-f0-9-]+_\d+_*\b/g, '');
1299
- cleaned = cleaned.replace(/\b_*XML_[a-f0-9-]+_\d+_+\b/g, '');
1300
1275
  return cleaned.trim();
1301
1276
  }
1302
1277
  // Helper function to process nested HTML elements in list items
@@ -1365,12 +1340,12 @@ class NotionAITool {
1365
1340
  // Helper function to convert inline HTML to markdown
1366
1341
  static convertInlineHtmlToMarkdown(content) {
1367
1342
  let processed = content;
1368
- // Convert HTML formatting tags to markdown equivalents
1343
+ // Convert HTML formatting tags to markdown equivalents - process in order to handle nested tags
1369
1344
  const htmlToMarkdown = [
1370
1345
  { regex: /<strong\s*[^>]*>(.*?)<\/strong>/gis, replacement: '**$1**' },
1371
1346
  { regex: /<b\s*[^>]*>(.*?)<\/b>/gis, replacement: '**$1**' },
1372
- { regex: /<em\s*[^>]*>(.*?)<\/em>/gis, replacement: '*$1*' },
1373
- { 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
1374
1349
  { regex: /<code\s*[^>]*>(.*?)<\/code>/gis, replacement: '`$1`' },
1375
1350
  { regex: /<a\s+href="([^"]*)"[^>]*>(.*?)<\/a>/gis, replacement: '[$2]($1)' },
1376
1351
  { regex: /<u\s*[^>]*>(.*?)<\/u>/gis, replacement: '$1' }, // Notion doesn't support underline
@@ -1512,7 +1487,8 @@ class NotionAITool {
1512
1487
  { regex: /\[([^\]]+)\]\(([^)]+)\)/g, type: 'link' }, // [text](url)
1513
1488
  { regex: /\*\*\*([^*]+)\*\*\*/g, type: 'bold_italic' }, // ***bold italic***
1514
1489
  { regex: /\*\*([^*]+)\*\*/g, type: 'bold' }, // **bold**
1515
- { regex: /\*([^*]+)\*/g, type: 'italic' }, // *italic*
1490
+ { regex: /_([^_]+)_/g, type: 'italic' }, // _italic_ (changed from *)
1491
+ { regex: /\*([^*]+)\*/g, type: 'italic' }, // *italic* (keep for backward compatibility)
1516
1492
  { regex: /~~([^~]+)~~/g, type: 'strikethrough' }, // ~~strikethrough~~
1517
1493
  { regex: /`([^`]+)`/g, type: 'code' }, // `code`
1518
1494
  ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-notion-advanced",
3
- "version": "1.2.20-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": [