n8n-nodes-notion-advanced 1.2.31-beta → 1.2.32-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.
@@ -66,6 +66,10 @@ export declare class NotionAITool implements INodeType {
66
66
  static processNestedHtmlInListItem(content: string): string;
67
67
  static convertInlineHtmlToMarkdown(content: string): string;
68
68
  static buildListHierarchy(listContent: string, listType: 'bulleted_list_item' | 'numbered_list_item', childHierarchyNodes: HierarchyNode[]): HierarchyNode | null;
69
+ static getListItemPositions(content: string): Array<{
70
+ start: number;
71
+ end: number;
72
+ }>;
69
73
  static mapChildBlocksToListItems(listContent: string, childBlocks: IDataObject[], childNodes: XMLNode[]): Map<number, IDataObject[]>;
70
74
  static processNestedListWithChildBlocks(listContent: string, listType: 'bulleted_list_item' | 'numbered_list_item', blocks: IDataObject[], listItemChildBlocks: Map<number, IDataObject[]>): void;
71
75
  static processNestedList(listContent: string, listType: 'bulleted_list_item' | 'numbered_list_item', blocks: IDataObject[], childNodes?: XMLNode[]): void;
@@ -872,11 +872,12 @@ class NotionAITool {
872
872
  }
873
873
  // For list processors, handle them specially
874
874
  if (xmlNode.listProcessor && (xmlNode.tagName === 'ul' || xmlNode.tagName === 'ol')) {
875
- // Extract inner content
875
+ // Extract inner content and calculate offset
876
876
  const tagName = xmlNode.tagName.toLowerCase();
877
877
  const openTagRegex = new RegExp(`^<${tagName}[^>]*>`, 'i');
878
878
  const closeTagRegex = new RegExp(`</${tagName}>$`, 'i');
879
879
  let innerContent = xmlNode.match;
880
+ let contentStartOffset = 0;
880
881
  const openMatch = xmlNode.match.match(openTagRegex);
881
882
  const closeMatch = xmlNode.match.match(closeTagRegex);
882
883
  if (openMatch && closeMatch) {
@@ -885,9 +886,23 @@ class NotionAITool {
885
886
  const startIndex = openTag.length;
886
887
  const endIndex = xmlNode.match.length - closeTag.length;
887
888
  innerContent = xmlNode.match.substring(startIndex, endIndex);
889
+ contentStartOffset = xmlNode.start + startIndex; // Absolute position where list content starts
888
890
  }
891
+ // Adjust child hierarchy node positions to be relative to list content
892
+ const adjustedChildNodes = childHierarchyNodes.map(child => {
893
+ var _a;
894
+ return ({
895
+ ...child,
896
+ metadata: {
897
+ ...child.metadata,
898
+ sourcePosition: ((_a = child.metadata) === null || _a === void 0 ? void 0 : _a.sourcePosition) !== undefined
899
+ ? child.metadata.sourcePosition - contentStartOffset
900
+ : undefined
901
+ }
902
+ });
903
+ });
889
904
  // Build hierarchy structure for the list
890
- const listHierarchy = NotionAITool.buildListHierarchy(innerContent, xmlNode.tagName === 'ul' ? 'bulleted_list_item' : 'numbered_list_item', childHierarchyNodes);
905
+ const listHierarchy = NotionAITool.buildListHierarchy(innerContent, xmlNode.tagName === 'ul' ? 'bulleted_list_item' : 'numbered_list_item', adjustedChildNodes);
891
906
  return listHierarchy;
892
907
  }
893
908
  // For regular nodes, create block and attach children
@@ -1523,12 +1538,13 @@ class NotionAITool {
1523
1538
  }
1524
1539
  // Build hierarchy structure for lists using HierarchyNode approach
1525
1540
  static buildListHierarchy(listContent, listType, childHierarchyNodes) {
1541
+ var _a;
1526
1542
  try {
1527
1543
  // Process each <li> element and build hierarchy
1528
1544
  const listItems = NotionAITool.extractListItemsWithBranching(listContent);
1529
1545
  const listItemHierarchyNodes = [];
1530
- // Map child hierarchy nodes to list items based on position
1531
- let childNodeIndex = 0;
1546
+ // Map child hierarchy nodes to list items based on actual position in source XML
1547
+ const listItemPositions = NotionAITool.getListItemPositions(listContent);
1532
1548
  for (let i = 0; i < listItems.length; i++) {
1533
1549
  const item = listItems[i];
1534
1550
  if (!item.text && !item.children.length)
@@ -1547,16 +1563,19 @@ class NotionAITool {
1547
1563
  listItemBlock[listType].rich_text = NotionAITool.parseBasicMarkdown(cleanText);
1548
1564
  }
1549
1565
  }
1550
- // Collect child hierarchy nodes for this list item
1566
+ // Collect child hierarchy nodes for this list item based on position mapping
1551
1567
  const itemChildNodes = [];
1552
- // Add child hierarchy nodes that belong to this list item
1553
- // For now, distribute them evenly - this could be improved with position mapping
1554
- const childrenPerItem = Math.floor(childHierarchyNodes.length / listItems.length);
1555
- const startIndex = i * childrenPerItem;
1556
- const endIndex = i === listItems.length - 1 ? childHierarchyNodes.length : startIndex + childrenPerItem;
1557
- for (let j = startIndex; j < endIndex; j++) {
1558
- if (j < childHierarchyNodes.length) {
1559
- itemChildNodes.push(childHierarchyNodes[j]);
1568
+ // Map child hierarchy nodes that belong to this specific list item
1569
+ if (i < listItemPositions.length) {
1570
+ const currentItemStart = listItemPositions[i].start;
1571
+ const currentItemEnd = listItemPositions[i].end;
1572
+ for (const childNode of childHierarchyNodes) {
1573
+ const childPosition = (_a = childNode.metadata) === null || _a === void 0 ? void 0 : _a.sourcePosition;
1574
+ if (childPosition !== undefined &&
1575
+ childPosition >= currentItemStart &&
1576
+ childPosition < currentItemEnd) {
1577
+ itemChildNodes.push(childNode);
1578
+ }
1560
1579
  }
1561
1580
  }
1562
1581
  // Process nested list children (traditional nested lists)
@@ -1608,6 +1627,55 @@ class NotionAITool {
1608
1627
  };
1609
1628
  }
1610
1629
  }
1630
+ // Helper function to get position ranges for each list item in the content
1631
+ static getListItemPositions(content) {
1632
+ const positions = [];
1633
+ let pos = 0;
1634
+ while (pos < content.length) {
1635
+ // Find next <li> tag
1636
+ const liStart = content.indexOf('<li', pos);
1637
+ if (liStart === -1)
1638
+ break;
1639
+ const liOpenEnd = content.indexOf('>', liStart);
1640
+ if (liOpenEnd === -1)
1641
+ break;
1642
+ // Find the matching </li> using proper depth tracking
1643
+ let depth = 0;
1644
+ let searchPos = liOpenEnd + 1;
1645
+ let liEnd = -1;
1646
+ while (searchPos < content.length) {
1647
+ const nextLiOpen = content.indexOf('<li', searchPos);
1648
+ const nextLiClose = content.indexOf('</li>', searchPos);
1649
+ if (nextLiClose === -1)
1650
+ break;
1651
+ if (nextLiOpen !== -1 && nextLiOpen < nextLiClose) {
1652
+ depth++;
1653
+ searchPos = nextLiOpen + 3;
1654
+ }
1655
+ else {
1656
+ if (depth === 0) {
1657
+ liEnd = nextLiClose + 5; // Include the '</li>'
1658
+ break;
1659
+ }
1660
+ else {
1661
+ depth--;
1662
+ searchPos = nextLiClose + 5;
1663
+ }
1664
+ }
1665
+ }
1666
+ if (liEnd !== -1) {
1667
+ positions.push({
1668
+ start: liStart,
1669
+ end: liEnd
1670
+ });
1671
+ pos = liEnd;
1672
+ }
1673
+ else {
1674
+ pos = liOpenEnd + 1;
1675
+ }
1676
+ }
1677
+ return positions;
1678
+ }
1611
1679
  // Helper function to map child blocks to specific list items (legacy support)
1612
1680
  static mapChildBlocksToListItems(listContent, childBlocks, childNodes) {
1613
1681
  const listItemChildBlocks = new Map();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-notion-advanced",
3
- "version": "1.2.31-beta",
3
+ "version": "1.2.32-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": [