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
|
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 (
|
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}${
|
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}${
|
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
|
892
|
-
const
|
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
|
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}${
|
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
|
-
//
|
1217
|
+
// Simplified placeholder cleanup - use one consistent pattern
|
1240
1218
|
if (placeholderPrefix) {
|
1241
|
-
//
|
1242
|
-
const
|
1243
|
-
|
1244
|
-
|
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
|
-
//
|
1252
|
-
const
|
1253
|
-
|
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: '
|
1397
|
-
{ regex: /<i\s*[^>]*>(.*?)<\/i>/gis, replacement: '
|
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:
|
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.
|
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": [
|