@code.store/arcxp-sdk-ts 5.3.0 → 5.3.2
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.
- package/dist/content-elements/html/html.processor.d.ts +1 -0
- package/dist/content-elements/index.d.ts +1 -0
- package/dist/content-elements/xml/xml.processor.d.ts +1 -0
- package/dist/index.cjs +251 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +250 -24
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -26,6 +26,7 @@ export type WrapHandler = (node: Node, content: ContentElementType<'text'>) => C
|
|
|
26
26
|
* using the `handle()` and `wrap()` methods.
|
|
27
27
|
*/
|
|
28
28
|
export declare class HTMLProcessor {
|
|
29
|
+
protected blockElementTags: string[];
|
|
29
30
|
protected parallelProcessing: boolean;
|
|
30
31
|
protected handlers: {
|
|
31
32
|
node: Map<string, NodeHandler>;
|
|
@@ -5,6 +5,7 @@ export type CElement = ArcTypes.ANS.AnElementThatCanBeListedAsPartOfContentEleme
|
|
|
5
5
|
export type NodeHandler = (node: xmldoc.XmlNodeBase) => MaybePromise<CElement[] | undefined>;
|
|
6
6
|
export type WrapHandler = (node: xmldoc.XmlElement, content: string) => string;
|
|
7
7
|
export declare class XMLProcessor {
|
|
8
|
+
protected blockElementTags: string[];
|
|
8
9
|
protected handlers: {
|
|
9
10
|
node: Map<string, NodeHandler>;
|
|
10
11
|
wrap: Map<string, WrapHandler>;
|
package/dist/index.cjs
CHANGED
|
@@ -11,6 +11,7 @@ var FormData = require('form-data');
|
|
|
11
11
|
var ws = require('ws');
|
|
12
12
|
var nodeHtmlParser = require('node-html-parser');
|
|
13
13
|
var htmlEntities = require('html-entities');
|
|
14
|
+
var xmldoc = require('xmldoc');
|
|
14
15
|
var encode = require('base32-encode');
|
|
15
16
|
var uuid = require('uuid');
|
|
16
17
|
var assert = require('node:assert');
|
|
@@ -34,6 +35,7 @@ function _interopNamespaceDefault(e) {
|
|
|
34
35
|
|
|
35
36
|
var rateLimit__namespace = /*#__PURE__*/_interopNamespaceDefault(rateLimit);
|
|
36
37
|
var ws__namespace = /*#__PURE__*/_interopNamespaceDefault(ws);
|
|
38
|
+
var xmldoc__namespace = /*#__PURE__*/_interopNamespaceDefault(xmldoc);
|
|
37
39
|
|
|
38
40
|
const safeJSONStringify = (data) => {
|
|
39
41
|
try {
|
|
@@ -913,7 +915,7 @@ const ArcAPI = (options) => {
|
|
|
913
915
|
return API;
|
|
914
916
|
};
|
|
915
917
|
|
|
916
|
-
const ContentElement = {
|
|
918
|
+
const ContentElement$1 = {
|
|
917
919
|
divider: () => {
|
|
918
920
|
return {
|
|
919
921
|
type: 'divider',
|
|
@@ -1145,7 +1147,7 @@ const ContentElement = {
|
|
|
1145
1147
|
},
|
|
1146
1148
|
};
|
|
1147
1149
|
|
|
1148
|
-
const BLOCK_ELEMENT_TAGS = [
|
|
1150
|
+
const BLOCK_ELEMENT_TAGS$1 = [
|
|
1149
1151
|
'ADDRESS',
|
|
1150
1152
|
'ARTICLE',
|
|
1151
1153
|
'ASIDE',
|
|
@@ -1184,7 +1186,7 @@ const BLOCK_ELEMENT_TAGS = [
|
|
|
1184
1186
|
|
|
1185
1187
|
var html_constants = /*#__PURE__*/Object.freeze({
|
|
1186
1188
|
__proto__: null,
|
|
1187
|
-
BLOCK_ELEMENT_TAGS: BLOCK_ELEMENT_TAGS
|
|
1189
|
+
BLOCK_ELEMENT_TAGS: BLOCK_ELEMENT_TAGS$1
|
|
1188
1190
|
});
|
|
1189
1191
|
|
|
1190
1192
|
const socialRegExps = {
|
|
@@ -1228,27 +1230,27 @@ function createSocial(url = '') {
|
|
|
1228
1230
|
const embeds = [];
|
|
1229
1231
|
const instagram = instagramURLParser(url);
|
|
1230
1232
|
if (instagram) {
|
|
1231
|
-
embeds.push(ContentElement.instagram(instagram));
|
|
1233
|
+
embeds.push(ContentElement$1.instagram(instagram));
|
|
1232
1234
|
}
|
|
1233
1235
|
const twitter = twitterURLParser(url);
|
|
1234
1236
|
if (twitter) {
|
|
1235
|
-
embeds.push(ContentElement.twitter(twitter));
|
|
1237
|
+
embeds.push(ContentElement$1.twitter(twitter));
|
|
1236
1238
|
}
|
|
1237
1239
|
const tiktok = tiktokURLParser(url);
|
|
1238
1240
|
if (tiktok) {
|
|
1239
|
-
embeds.push(ContentElement.tiktok(tiktok));
|
|
1241
|
+
embeds.push(ContentElement$1.tiktok(tiktok));
|
|
1240
1242
|
}
|
|
1241
1243
|
const youtube = youtubeURLParser(url);
|
|
1242
1244
|
if (youtube) {
|
|
1243
|
-
embeds.push(ContentElement.youtube(youtube));
|
|
1245
|
+
embeds.push(ContentElement$1.youtube(youtube));
|
|
1244
1246
|
}
|
|
1245
1247
|
const facebookPost = facebookPostURLParser(url);
|
|
1246
1248
|
if (facebookPost) {
|
|
1247
|
-
embeds.push(ContentElement.facebook_post(facebookPost));
|
|
1249
|
+
embeds.push(ContentElement$1.facebook_post(facebookPost));
|
|
1248
1250
|
}
|
|
1249
1251
|
const facebookVideo = facebookVideoURLParser(url);
|
|
1250
1252
|
if (facebookVideo) {
|
|
1251
|
-
embeds.push(ContentElement.facebook_video(facebookVideo));
|
|
1253
|
+
embeds.push(ContentElement$1.facebook_video(facebookVideo));
|
|
1252
1254
|
}
|
|
1253
1255
|
return embeds;
|
|
1254
1256
|
}
|
|
@@ -1272,7 +1274,7 @@ var ContentElements = /*#__PURE__*/Object.freeze({
|
|
|
1272
1274
|
youtubeURLParser: youtubeURLParser
|
|
1273
1275
|
});
|
|
1274
1276
|
|
|
1275
|
-
const isTextNode = (node) => {
|
|
1277
|
+
const isTextNode$1 = (node) => {
|
|
1276
1278
|
return node instanceof nodeHtmlParser.TextNode;
|
|
1277
1279
|
};
|
|
1278
1280
|
const isHTMLElement = (node) => {
|
|
@@ -1306,7 +1308,7 @@ var html_utils = /*#__PURE__*/Object.freeze({
|
|
|
1306
1308
|
htmlToText: htmlToText,
|
|
1307
1309
|
isCommentNode: isCommentNode,
|
|
1308
1310
|
isHTMLElement: isHTMLElement,
|
|
1309
|
-
isTextNode: isTextNode,
|
|
1311
|
+
isTextNode: isTextNode$1,
|
|
1310
1312
|
nodeTagIn: nodeTagIn,
|
|
1311
1313
|
nodeTagIs: nodeTagIs
|
|
1312
1314
|
});
|
|
@@ -1335,6 +1337,7 @@ var html_utils = /*#__PURE__*/Object.freeze({
|
|
|
1335
1337
|
*/
|
|
1336
1338
|
class HTMLProcessor {
|
|
1337
1339
|
constructor() {
|
|
1340
|
+
this.blockElementTags = BLOCK_ELEMENT_TAGS$1;
|
|
1338
1341
|
this.parallelProcessing = true;
|
|
1339
1342
|
this.handlers = {
|
|
1340
1343
|
node: new Map(),
|
|
@@ -1454,7 +1457,7 @@ class HTMLProcessor {
|
|
|
1454
1457
|
}
|
|
1455
1458
|
});
|
|
1456
1459
|
this.handle('text', (node) => {
|
|
1457
|
-
if (isTextNode(node)) {
|
|
1460
|
+
if (isTextNode$1(node)) {
|
|
1458
1461
|
return this.createText(node);
|
|
1459
1462
|
}
|
|
1460
1463
|
});
|
|
@@ -1632,23 +1635,23 @@ class HTMLProcessor {
|
|
|
1632
1635
|
return [];
|
|
1633
1636
|
}
|
|
1634
1637
|
async handleTable(node) {
|
|
1635
|
-
return [ContentElement.raw_html(node.toString())];
|
|
1638
|
+
return [ContentElement$1.raw_html(node.toString())];
|
|
1636
1639
|
}
|
|
1637
1640
|
async handleIframe(node) {
|
|
1638
|
-
return [ContentElement.raw_html(node.toString())];
|
|
1641
|
+
return [ContentElement$1.raw_html(node.toString())];
|
|
1639
1642
|
}
|
|
1640
1643
|
async handleImage(node) {
|
|
1641
|
-
return [ContentElement.raw_html(node.toString())];
|
|
1644
|
+
return [ContentElement$1.raw_html(node.toString())];
|
|
1642
1645
|
}
|
|
1643
1646
|
async handleBreak(_) {
|
|
1644
|
-
return [ContentElement.divider()];
|
|
1647
|
+
return [ContentElement$1.divider()];
|
|
1645
1648
|
}
|
|
1646
1649
|
async createQuote(node) {
|
|
1647
1650
|
const items = await this.handleNested(node);
|
|
1648
|
-
return [ContentElement.quote(items)];
|
|
1651
|
+
return [ContentElement$1.quote(items)];
|
|
1649
1652
|
}
|
|
1650
1653
|
async createText(node) {
|
|
1651
|
-
const text = ContentElement.text(node.text);
|
|
1654
|
+
const text = ContentElement$1.text(node.text);
|
|
1652
1655
|
return [text];
|
|
1653
1656
|
}
|
|
1654
1657
|
filterListItems(items) {
|
|
@@ -1656,16 +1659,16 @@ class HTMLProcessor {
|
|
|
1656
1659
|
}
|
|
1657
1660
|
async createList(node, type) {
|
|
1658
1661
|
const items = await this.handleNested(node);
|
|
1659
|
-
return [ContentElement.list(type, this.filterListItems(items))];
|
|
1662
|
+
return [ContentElement$1.list(type, this.filterListItems(items))];
|
|
1660
1663
|
}
|
|
1661
1664
|
async createHeader(node) {
|
|
1662
1665
|
const level = +node.tagName.split('H')[1] || 3;
|
|
1663
|
-
return [ContentElement.header(node.innerText, level)];
|
|
1666
|
+
return [ContentElement$1.header(node.innerText, level)];
|
|
1664
1667
|
}
|
|
1665
1668
|
isBlockElement(node) {
|
|
1666
1669
|
if (!isHTMLElement(node))
|
|
1667
1670
|
return false;
|
|
1668
|
-
const defaultBlockElements = new Set(
|
|
1671
|
+
const defaultBlockElements = new Set(this.blockElementTags);
|
|
1669
1672
|
return defaultBlockElements.has(node.tagName);
|
|
1670
1673
|
}
|
|
1671
1674
|
warn(metadata, message) {
|
|
@@ -1673,17 +1676,241 @@ class HTMLProcessor {
|
|
|
1673
1676
|
}
|
|
1674
1677
|
}
|
|
1675
1678
|
|
|
1676
|
-
var index$
|
|
1679
|
+
var index$4 = /*#__PURE__*/Object.freeze({
|
|
1677
1680
|
__proto__: null,
|
|
1678
1681
|
Constants: html_constants,
|
|
1679
1682
|
HTMLProcessor: HTMLProcessor,
|
|
1680
1683
|
Utils: html_utils
|
|
1681
1684
|
});
|
|
1682
1685
|
|
|
1686
|
+
const BLOCK_ELEMENT_TAGS = ['paragraph', 'line', 'header', 'ul', 'ol', 'li', 'embed', 'iframe', 'table'];
|
|
1687
|
+
|
|
1688
|
+
var xml_constants = /*#__PURE__*/Object.freeze({
|
|
1689
|
+
__proto__: null,
|
|
1690
|
+
BLOCK_ELEMENT_TAGS: BLOCK_ELEMENT_TAGS
|
|
1691
|
+
});
|
|
1692
|
+
|
|
1693
|
+
const isXmlElement = (node) => {
|
|
1694
|
+
return node?.type === 'element';
|
|
1695
|
+
};
|
|
1696
|
+
const isTextNode = (node) => {
|
|
1697
|
+
return node?.type === 'text';
|
|
1698
|
+
};
|
|
1699
|
+
const nodeNameIs = (node, name) => {
|
|
1700
|
+
return isXmlElement(node) && node.name === name;
|
|
1701
|
+
};
|
|
1702
|
+
const nodeNameIn = (node, names) => {
|
|
1703
|
+
return isXmlElement(node) && names.includes(node.name);
|
|
1704
|
+
};
|
|
1705
|
+
|
|
1706
|
+
var xml_utils = /*#__PURE__*/Object.freeze({
|
|
1707
|
+
__proto__: null,
|
|
1708
|
+
isTextNode: isTextNode,
|
|
1709
|
+
isXmlElement: isXmlElement,
|
|
1710
|
+
nodeNameIn: nodeNameIn,
|
|
1711
|
+
nodeNameIs: nodeNameIs
|
|
1712
|
+
});
|
|
1713
|
+
|
|
1714
|
+
const ContentElement = ContentElement$1;
|
|
1715
|
+
class XMLProcessor {
|
|
1716
|
+
constructor() {
|
|
1717
|
+
this.blockElementTags = BLOCK_ELEMENT_TAGS;
|
|
1718
|
+
this.handlers = {
|
|
1719
|
+
node: new Map(),
|
|
1720
|
+
wrap: new Map(),
|
|
1721
|
+
};
|
|
1722
|
+
}
|
|
1723
|
+
init() {
|
|
1724
|
+
// wrappers are used to wrap the content of nested text nodes
|
|
1725
|
+
// in a specific way
|
|
1726
|
+
this.wrap('link', (node, content) => {
|
|
1727
|
+
return `<a href="${node.attr.url || node.attr.href || '/'}">${content}</a>`;
|
|
1728
|
+
});
|
|
1729
|
+
this.wrap('header', (_node, content) => {
|
|
1730
|
+
return `<h3>${content}</h3>`;
|
|
1731
|
+
});
|
|
1732
|
+
this.wrap('emphasize', (_node, content) => {
|
|
1733
|
+
return `<i>${content}</i>`;
|
|
1734
|
+
});
|
|
1735
|
+
this.wrap('strong', (_node, content) => {
|
|
1736
|
+
return `<b>${content}</b>`;
|
|
1737
|
+
});
|
|
1738
|
+
// handlers are used to handle specific nodes
|
|
1739
|
+
// and return a list of content elements
|
|
1740
|
+
this.handle('default', (node) => {
|
|
1741
|
+
if (nodeNameIn(node, ['section', 'paragraph', 'line', 'header', 'emphasize', 'strong', 'link', 'li'])) {
|
|
1742
|
+
return this.handleNested(node);
|
|
1743
|
+
}
|
|
1744
|
+
});
|
|
1745
|
+
this.handle('text', (node) => {
|
|
1746
|
+
if (isTextNode(node)) {
|
|
1747
|
+
return [ContentElement.text(node.text)];
|
|
1748
|
+
}
|
|
1749
|
+
});
|
|
1750
|
+
this.handle('list', async (node) => {
|
|
1751
|
+
if (nodeNameIn(node, ['ul', 'ol'])) {
|
|
1752
|
+
const listType = node.name === 'ul' ? 'unordered' : 'ordered';
|
|
1753
|
+
return this.createList(node, listType);
|
|
1754
|
+
}
|
|
1755
|
+
});
|
|
1756
|
+
this.handle('table', (node) => {
|
|
1757
|
+
if (nodeNameIs(node, 'table')) {
|
|
1758
|
+
return this.handleTable(node);
|
|
1759
|
+
}
|
|
1760
|
+
});
|
|
1761
|
+
}
|
|
1762
|
+
async parse(xml) {
|
|
1763
|
+
const doc = new xmldoc__namespace.XmlDocument(xml);
|
|
1764
|
+
const elements = await this.process(doc);
|
|
1765
|
+
return elements || [];
|
|
1766
|
+
}
|
|
1767
|
+
handle(name, handler) {
|
|
1768
|
+
if (this.handlers.node.has(name)) {
|
|
1769
|
+
throw new Error(`${name} node handler already set`);
|
|
1770
|
+
}
|
|
1771
|
+
this.handlers.node.set(name, handler);
|
|
1772
|
+
}
|
|
1773
|
+
wrap(name, handler) {
|
|
1774
|
+
if (this.handlers.wrap.has(name)) {
|
|
1775
|
+
throw new Error(`${name} wrap handler already set`);
|
|
1776
|
+
}
|
|
1777
|
+
this.handlers.wrap.set(name, handler);
|
|
1778
|
+
}
|
|
1779
|
+
addTextAdditionalProperties(c, parent) {
|
|
1780
|
+
const additionalProperties = c.additional_properties || {};
|
|
1781
|
+
const parentNodeIsBlockElement = this.isBlockElement(parent);
|
|
1782
|
+
c.additional_properties = {
|
|
1783
|
+
...c.additional_properties,
|
|
1784
|
+
isBlockElement: additionalProperties.isBlockElement || parentNodeIsBlockElement,
|
|
1785
|
+
};
|
|
1786
|
+
return c;
|
|
1787
|
+
}
|
|
1788
|
+
wrapChildrenTextNodes(node, elements) {
|
|
1789
|
+
const wrapped = [];
|
|
1790
|
+
for (const c of elements) {
|
|
1791
|
+
if (!isTextCE(c)) {
|
|
1792
|
+
wrapped.push(c);
|
|
1793
|
+
continue;
|
|
1794
|
+
}
|
|
1795
|
+
this.addTextAdditionalProperties(c, node);
|
|
1796
|
+
const handler = this.handlers.wrap.get(node.name);
|
|
1797
|
+
if (handler) {
|
|
1798
|
+
wrapped.push({
|
|
1799
|
+
...c,
|
|
1800
|
+
content: handler(node, c.content),
|
|
1801
|
+
});
|
|
1802
|
+
}
|
|
1803
|
+
else {
|
|
1804
|
+
wrapped.push(c);
|
|
1805
|
+
}
|
|
1806
|
+
}
|
|
1807
|
+
return wrapped;
|
|
1808
|
+
}
|
|
1809
|
+
async handleNested(node) {
|
|
1810
|
+
const children = await Promise.all(node.children.map((child) => this.process(child)));
|
|
1811
|
+
const filtered = children.filter(Boolean).flat();
|
|
1812
|
+
const merged = this.mergeParagraphs(filtered);
|
|
1813
|
+
const wrapped = this.wrapChildrenTextNodes(node, merged);
|
|
1814
|
+
return wrapped;
|
|
1815
|
+
}
|
|
1816
|
+
async process(node) {
|
|
1817
|
+
let isKnownNode = false;
|
|
1818
|
+
const elements = [];
|
|
1819
|
+
for (const [name, handler] of this.handlers.node.entries()) {
|
|
1820
|
+
try {
|
|
1821
|
+
const result = await handler(node);
|
|
1822
|
+
if (Array.isArray(result)) {
|
|
1823
|
+
// if handler returns an array of elements, it means that the node was handled properly, even if there is no elements inside
|
|
1824
|
+
isKnownNode = true;
|
|
1825
|
+
elements.push(...result);
|
|
1826
|
+
break;
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
catch (error) {
|
|
1830
|
+
this.warn({ node: node.toString(), error: error.toString(), name }, 'HandlerError');
|
|
1831
|
+
}
|
|
1832
|
+
}
|
|
1833
|
+
if (isKnownNode)
|
|
1834
|
+
return elements;
|
|
1835
|
+
this.warn({ node: node.toString(), type: node.type }, 'UnknownNodeError');
|
|
1836
|
+
}
|
|
1837
|
+
mergeParagraphs(items) {
|
|
1838
|
+
const merged = [];
|
|
1839
|
+
let toMerge = [];
|
|
1840
|
+
const merge = () => {
|
|
1841
|
+
if (!toMerge.length)
|
|
1842
|
+
return;
|
|
1843
|
+
const paragraph = toMerge.reduce((acc, p) => {
|
|
1844
|
+
return {
|
|
1845
|
+
...p,
|
|
1846
|
+
content: acc.content + p.content,
|
|
1847
|
+
};
|
|
1848
|
+
}, { type: 'text', content: '' });
|
|
1849
|
+
merged.push(paragraph);
|
|
1850
|
+
toMerge = [];
|
|
1851
|
+
};
|
|
1852
|
+
for (let i = 0; i < items.length; i++) {
|
|
1853
|
+
const item = items[i];
|
|
1854
|
+
const isBlockElement = item.additional_properties?.isBlockElement;
|
|
1855
|
+
if (isTextCE(item) && !isBlockElement) {
|
|
1856
|
+
toMerge.push(item);
|
|
1857
|
+
}
|
|
1858
|
+
else {
|
|
1859
|
+
merge();
|
|
1860
|
+
merged.push(item);
|
|
1861
|
+
}
|
|
1862
|
+
}
|
|
1863
|
+
merge();
|
|
1864
|
+
return merged;
|
|
1865
|
+
}
|
|
1866
|
+
async handleTable(node) {
|
|
1867
|
+
const html = node.toString({ html: true });
|
|
1868
|
+
return [ContentElement.raw_html(html)];
|
|
1869
|
+
}
|
|
1870
|
+
async createQuote(node) {
|
|
1871
|
+
const items = await this.handleNested(node);
|
|
1872
|
+
return [ContentElement.quote(items)];
|
|
1873
|
+
}
|
|
1874
|
+
async createList(node, type) {
|
|
1875
|
+
const items = await this.handleNested(node);
|
|
1876
|
+
return [ContentElement.list(type, items)];
|
|
1877
|
+
}
|
|
1878
|
+
getNodeInnerText(node) {
|
|
1879
|
+
return node.children.map((n) => this.htmlFromNode(n).innerText.trim());
|
|
1880
|
+
}
|
|
1881
|
+
getNodeInnerHTML(node) {
|
|
1882
|
+
return node.children.map((n) => this.htmlFromNode(n).innerHTML.trim());
|
|
1883
|
+
}
|
|
1884
|
+
htmlFromNode(node) {
|
|
1885
|
+
return nodeHtmlParser.parse(node.toString({ html: true }));
|
|
1886
|
+
}
|
|
1887
|
+
getDecodedHTMLFromInnerNodes(node) {
|
|
1888
|
+
const encodedHtml = this.getNodeInnerText(node).join('');
|
|
1889
|
+
const decoded = decodeHTMLEntities(encodedHtml);
|
|
1890
|
+
return decoded;
|
|
1891
|
+
}
|
|
1892
|
+
isBlockElement(node) {
|
|
1893
|
+
const defaultBlockElements = new Set(this.blockElementTags);
|
|
1894
|
+
if (defaultBlockElements.has(node.name))
|
|
1895
|
+
return true;
|
|
1896
|
+
}
|
|
1897
|
+
warn(metadata, message) {
|
|
1898
|
+
console.warn(metadata, message);
|
|
1899
|
+
}
|
|
1900
|
+
}
|
|
1901
|
+
|
|
1902
|
+
var index$3 = /*#__PURE__*/Object.freeze({
|
|
1903
|
+
__proto__: null,
|
|
1904
|
+
Constants: xml_constants,
|
|
1905
|
+
Utils: xml_utils,
|
|
1906
|
+
XMLProcessor: XMLProcessor
|
|
1907
|
+
});
|
|
1908
|
+
|
|
1683
1909
|
var index$2 = /*#__PURE__*/Object.freeze({
|
|
1684
1910
|
__proto__: null,
|
|
1685
|
-
ContentElement: ContentElement,
|
|
1686
|
-
HTML: index$
|
|
1911
|
+
ContentElement: ContentElement$1,
|
|
1912
|
+
HTML: index$4,
|
|
1913
|
+
XML: index$3
|
|
1687
1914
|
});
|
|
1688
1915
|
|
|
1689
1916
|
/**
|