stream-chat-react-native-core 5.10.0-beta.1 → 5.10.0

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.
@@ -3,17 +3,7 @@ Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
5
  exports.parseLinksFromText = void 0;
6
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
7
- var emailUserName = '[\\w+\\.~$_-]+';
8
- var schema = "(\\w{2,15}:\\/\\/)";
9
- var domain = "((?:\\w+\\.[a-zA-Z]+)+(?:[^:\\/\\s]+)|(?:\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}))";
10
- var port = "(:[0-9]{1,5})";
11
- var path = "((?:\\/)?[^?\\s]+)";
12
- var queryString = "(\\?[^#\\s]+)";
13
- var fragment = "(#[\\w_-]+)";
14
- var emailPattern = "(mailto:)?((?:" + emailUserName + ")@(?:" + domain + "))";
15
- var schemePrefixedLinkPattern = schema + "(\\S+)";
16
- var fqdnLinkPattern = schema + "?" + domain + port + "?" + path + "?" + queryString + "?" + fragment + "?";
6
+ var _linkifyIt = _interopRequireDefault(require("linkify-it"));
17
7
  var removeMarkdownLinksFromText = function removeMarkdownLinksFromText(input) {
18
8
  return input.replace(/\[[\w\s]+\]\(.*\)/g, '');
19
9
  };
@@ -21,61 +11,21 @@ var removeUserNamesFromText = function removeUserNamesFromText(input) {
21
11
  return input.replace(/^@\w+\.?\w/, '');
22
12
  };
23
13
  var parseLinksFromText = function parseLinksFromText(input) {
24
- var matches;
14
+ var _linkify$match;
25
15
  var strippedInput = [removeMarkdownLinksFromText, removeUserNamesFromText].reduce(function (acc, fn) {
26
16
  return fn(acc);
27
17
  }, input);
28
- var results = [];
29
- var emailRegExp = new RegExp(emailPattern, 'gi');
30
- while ((matches = emailRegExp.exec(input)) !== null) {
31
- var _matches = matches,
32
- _matches2 = (0, _slicedToArray2["default"])(_matches, 3),
33
- raw = _matches2[0],
34
- _matches2$ = _matches2[1],
35
- scheme = _matches2$ === void 0 ? 'mailto:' : _matches2$,
36
- displayValue = _matches2[2];
37
- results.push({
38
- encoded: encodeURI(displayValue),
39
- raw: raw,
40
- scheme: scheme
41
- });
42
- }
43
- var linkRegex = new RegExp(fqdnLinkPattern + "|" + schemePrefixedLinkPattern, 'gi');
44
- while ((matches = linkRegex.exec(strippedInput)) !== null) {
45
- var _matches3 = matches,
46
- _matches4 = (0, _slicedToArray2["default"])(_matches3, 9),
47
- _raw = _matches4[0],
48
- _matches4$ = _matches4[1],
49
- fqdnScheme = _matches4$ === void 0 ? '' : _matches4$,
50
- _matches4$2 = _matches4[2],
51
- fqdnDomainName = _matches4$2 === void 0 ? '' : _matches4$2,
52
- _matches4$3 = _matches4[3],
53
- fqdnPort = _matches4$3 === void 0 ? '' : _matches4$3,
54
- _matches4$4 = _matches4[4],
55
- fqdnPath = _matches4$4 === void 0 ? '' : _matches4$4,
56
- _matches4$5 = _matches4[5],
57
- fqdnQueryStraing = _matches4$5 === void 0 ? '' : _matches4$5,
58
- _matches4$6 = _matches4[6],
59
- fqdnFragment = _matches4$6 === void 0 ? '' : _matches4$6,
60
- _matches4$7 = _matches4[7],
61
- schemePrefixedScheme = _matches4$7 === void 0 ? '' : _matches4$7,
62
- _matches4$8 = _matches4[8],
63
- schemePrefixedPath = _matches4$8 === void 0 ? '' : _matches4$8;
64
- if (schemePrefixedScheme !== '') {
65
- results.push({
66
- encoded: encodeURI(schemePrefixedPath),
67
- raw: _raw,
68
- scheme: schemePrefixedScheme
69
- });
70
- continue;
71
- }
72
- results.push({
73
- encoded: encodeURI([fqdnDomainName, fqdnPort, fqdnPath, fqdnQueryStraing, fqdnFragment].join('')),
74
- raw: _raw,
75
- scheme: fqdnScheme
76
- });
77
- }
78
- return results;
18
+ var linkify = (0, _linkifyIt["default"])();
19
+ var matches = (_linkify$match = linkify.match(strippedInput)) != null ? _linkify$match : [];
20
+ var result = matches.map(function (match) {
21
+ var raw = match.raw,
22
+ url = match.url;
23
+ return {
24
+ encodedUrl: encodeURI(url),
25
+ raw: raw
26
+ };
27
+ });
28
+ return result;
79
29
  };
80
30
  exports.parseLinksFromText = parseLinksFromText;
81
31
  //# sourceMappingURL=parseLinks.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["emailUserName","schema","domain","port","path","queryString","fragment","emailPattern","schemePrefixedLinkPattern","fqdnLinkPattern","removeMarkdownLinksFromText","input","replace","removeUserNamesFromText","parseLinksFromText","matches","strippedInput","reduce","acc","fn","results","emailRegExp","RegExp","exec","raw","scheme","displayValue","push","encoded","encodeURI","linkRegex","fqdnScheme","fqdnDomainName","fqdnPort","fqdnPath","fqdnQueryStraing","fqdnFragment","schemePrefixedScheme","schemePrefixedPath","join"],"sources":["parseLinks.ts"],"sourcesContent":["/**\n * 📣 Note: Do not use named capture groups, as\n * it is not yet available in Hermes.\n *\n * These helpers indend to make it easier to skim read\n * the patterns below, but note that some are optional,\n * specified in the patterns these are added to.\n * */\nconst emailUserName = '[\\\\w+\\\\.~$_-]+';\nconst schema = `(\\\\w{2,15}:\\\\/\\\\/)`;\n// something.tld OR 123.123.123.123\nconst domain = `((?:\\\\w+\\\\.[a-zA-Z]+)+(?:[^:\\\\/\\\\s]+)|(?:\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}))`;\nconst port = `(:[0-9]{1,5})`;\nconst path = `((?:\\\\/)?[^?\\\\s]+)`;\nconst queryString = `(\\\\?[^#\\\\s]+)`;\nconst fragment = `(#[\\\\w_-]+)`;\n\n/**\n * Match any email address, with and without `mailto:`\n */\nconst emailPattern = `(mailto:)?((?:${emailUserName})@(?:${domain}))`;\n\n/**\n * Match any string starting with something that seems like it's a schema.\n * */\nconst schemePrefixedLinkPattern = `${schema}(\\\\S+)`;\n\n/**\n * Match as much as possible of a fqdn, at least with a domain name formed as\n * something.tld\n */\nconst fqdnLinkPattern = `${schema}?${domain}${port}?${path}?${queryString}?${fragment}?`;\n\ninterface Link {\n encoded: string;\n raw: string;\n scheme: string;\n}\n\n/**\n * This is done separately because of the version of javascript run\n * for expo\n * */\nconst removeMarkdownLinksFromText = (input: string) => input.replace(/\\[[\\w\\s]+\\]\\(.*\\)/g, '');\n\n/**\n * Hermes doesn't support lookbehind, so this is done separately to avoid\n * parsing user names as links.\n * */\nconst removeUserNamesFromText = (input: string) => input.replace(/^@\\w+\\.?\\w/, '');\n\nexport const parseLinksFromText = (input: string): Link[] => {\n let matches;\n\n const strippedInput = [removeMarkdownLinksFromText, removeUserNamesFromText].reduce(\n (acc, fn) => fn(acc),\n input,\n );\n\n const results: Link[] = [];\n\n const emailRegExp = new RegExp(emailPattern, 'gi');\n while ((matches = emailRegExp.exec(input)) !== null) {\n const [raw, scheme = 'mailto:', displayValue] = matches;\n results.push({ encoded: encodeURI(displayValue), raw, scheme });\n }\n\n /**\n * The two link patterns are checked with an \"or\" (`|`)\n * to avoid overlapping matches being duplicated in the output.\n * */\n const linkRegex = new RegExp(`${fqdnLinkPattern}|${schemePrefixedLinkPattern}`, 'gi');\n while ((matches = linkRegex.exec(strippedInput)) !== null) {\n const [\n raw,\n fqdnScheme = '',\n fqdnDomainName = '',\n fqdnPort = '',\n fqdnPath = '',\n fqdnQueryStraing = '',\n fqdnFragment = '',\n schemePrefixedScheme = '',\n schemePrefixedPath = '',\n ] = matches;\n\n if (schemePrefixedScheme !== '') {\n results.push({\n encoded: encodeURI(schemePrefixedPath),\n raw,\n scheme: schemePrefixedScheme,\n });\n continue;\n }\n\n results.push({\n encoded: encodeURI(\n [fqdnDomainName, fqdnPort, fqdnPath, fqdnQueryStraing, fqdnFragment].join(''),\n ),\n raw,\n scheme: fqdnScheme,\n });\n }\n\n return results;\n};\n"],"mappings":";;;;;;AAQA,IAAMA,aAAa,GAAG,gBAAgB;AACtC,IAAMC,MAAM,uBAAuB;AAEnC,IAAMC,MAAM,yFAAyF;AACrG,IAAMC,IAAI,kBAAkB;AAC5B,IAAMC,IAAI,uBAAuB;AACjC,IAAMC,WAAW,kBAAkB;AACnC,IAAMC,QAAQ,gBAAgB;AAK9B,IAAMC,YAAY,sBAAoBP,aAAa,aAAQE,MAAM,OAAI;AAKrE,IAAMM,yBAAyB,GAAMP,MAAM,WAAQ;AAMnD,IAAMQ,eAAe,GAAMR,MAAM,SAAIC,MAAM,GAAGC,IAAI,SAAIC,IAAI,SAAIC,WAAW,SAAIC,QAAQ,MAAG;AAYxF,IAAMI,2BAA2B,GAAG,SAA9BA,2BAA2B,CAAIC,KAAa;EAAA,OAAKA,KAAK,CAACC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC;AAAA;AAM9F,IAAMC,uBAAuB,GAAG,SAA1BA,uBAAuB,CAAIF,KAAa;EAAA,OAAKA,KAAK,CAACC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;AAAA;AAE3E,IAAME,kBAAkB,GAAG,SAArBA,kBAAkB,CAAIH,KAAa,EAAa;EAC3D,IAAII,OAAO;EAEX,IAAMC,aAAa,GAAG,CAACN,2BAA2B,EAAEG,uBAAuB,CAAC,CAACI,MAAM,CACjF,UAACC,GAAG,EAAEC,EAAE;IAAA,OAAKA,EAAE,CAACD,GAAG,CAAC;EAAA,GACpBP,KAAK,CACN;EAED,IAAMS,OAAe,GAAG,EAAE;EAE1B,IAAMC,WAAW,GAAG,IAAIC,MAAM,CAACf,YAAY,EAAE,IAAI,CAAC;EAClD,OAAO,CAACQ,OAAO,GAAGM,WAAW,CAACE,IAAI,CAACZ,KAAK,CAAC,MAAM,IAAI,EAAE;IACnD,eAAgDI,OAAO;MAAA;MAAhDS,GAAG;MAAA;MAAEC,MAAM,2BAAG,SAAS;MAAEC,YAAY;IAC5CN,OAAO,CAACO,IAAI,CAAC;MAAEC,OAAO,EAAEC,SAAS,CAACH,YAAY,CAAC;MAAEF,GAAG,EAAHA,GAAG;MAAEC,MAAM,EAANA;IAAO,CAAC,CAAC;EACjE;EAMA,IAAMK,SAAS,GAAG,IAAIR,MAAM,CAAIb,eAAe,SAAID,yBAAyB,EAAI,IAAI,CAAC;EACrF,OAAO,CAACO,OAAO,GAAGe,SAAS,CAACP,IAAI,CAACP,aAAa,CAAC,MAAM,IAAI,EAAE;IACzD,gBAUID,OAAO;MAAA;MATTS,IAAG;MAAA;MACHO,UAAU,2BAAG,EAAE;MAAA;MACfC,cAAc,4BAAG,EAAE;MAAA;MACnBC,QAAQ,4BAAG,EAAE;MAAA;MACbC,QAAQ,4BAAG,EAAE;MAAA;MACbC,gBAAgB,4BAAG,EAAE;MAAA;MACrBC,YAAY,4BAAG,EAAE;MAAA;MACjBC,oBAAoB,4BAAG,EAAE;MAAA;MACzBC,kBAAkB,4BAAG,EAAE;IAGzB,IAAID,oBAAoB,KAAK,EAAE,EAAE;MAC/BjB,OAAO,CAACO,IAAI,CAAC;QACXC,OAAO,EAAEC,SAAS,CAACS,kBAAkB,CAAC;QACtCd,GAAG,EAAHA,IAAG;QACHC,MAAM,EAAEY;MACV,CAAC,CAAC;MACF;IACF;IAEAjB,OAAO,CAACO,IAAI,CAAC;MACXC,OAAO,EAAEC,SAAS,CAChB,CAACG,cAAc,EAAEC,QAAQ,EAAEC,QAAQ,EAAEC,gBAAgB,EAAEC,YAAY,CAAC,CAACG,IAAI,CAAC,EAAE,CAAC,CAC9E;MACDf,GAAG,EAAHA,IAAG;MACHC,MAAM,EAAEM;IACV,CAAC,CAAC;EACJ;EAEA,OAAOX,OAAO;AAChB,CAAC;AAAC"}
1
+ {"version":3,"names":["removeMarkdownLinksFromText","input","replace","removeUserNamesFromText","parseLinksFromText","strippedInput","reduce","acc","fn","linkify","Linkify","matches","match","result","map","raw","url","encodedUrl","encodeURI"],"sources":["parseLinks.ts"],"sourcesContent":["import Linkify from 'linkify-it';\n\ninterface LinkInfo {\n encodedUrl: string;\n raw: string;\n}\n\n/**\n * This is done separately because of the version of javascript run\n * for expo\n * */\nconst removeMarkdownLinksFromText = (input: string) => input.replace(/\\[[\\w\\s]+\\]\\(.*\\)/g, '');\n\n/**\n * Hermes doesn't support lookbehind, so this is done separately to avoid\n * parsing user names as links.\n * */\nconst removeUserNamesFromText = (input: string) => input.replace(/^@\\w+\\.?\\w/, '');\n\nexport const parseLinksFromText = (input: string): LinkInfo[] => {\n const strippedInput = [removeMarkdownLinksFromText, removeUserNamesFromText].reduce(\n (acc, fn) => fn(acc),\n input,\n );\n\n const linkify = Linkify();\n const matches = linkify.match(strippedInput) ?? [];\n\n const result: LinkInfo[] = matches.map((match) => {\n const { raw, url } = match;\n return { encodedUrl: encodeURI(url), raw };\n });\n\n return result;\n};\n"],"mappings":";;;;;AAAA;AAWA,IAAMA,2BAA2B,GAAG,SAA9BA,2BAA2B,CAAIC,KAAa;EAAA,OAAKA,KAAK,CAACC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC;AAAA;AAM9F,IAAMC,uBAAuB,GAAG,SAA1BA,uBAAuB,CAAIF,KAAa;EAAA,OAAKA,KAAK,CAACC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;AAAA;AAE3E,IAAME,kBAAkB,GAAG,SAArBA,kBAAkB,CAAIH,KAAa,EAAiB;EAAA;EAC/D,IAAMI,aAAa,GAAG,CAACL,2BAA2B,EAAEG,uBAAuB,CAAC,CAACG,MAAM,CACjF,UAACC,GAAG,EAAEC,EAAE;IAAA,OAAKA,EAAE,CAACD,GAAG,CAAC;EAAA,GACpBN,KAAK,CACN;EAED,IAAMQ,OAAO,GAAG,IAAAC,qBAAO,GAAE;EACzB,IAAMC,OAAO,qBAAGF,OAAO,CAACG,KAAK,CAACP,aAAa,CAAC,6BAAI,EAAE;EAElD,IAAMQ,MAAkB,GAAGF,OAAO,CAACG,GAAG,CAAC,UAACF,KAAK,EAAK;IAChD,IAAQG,GAAG,GAAUH,KAAK,CAAlBG,GAAG;MAAEC,GAAG,GAAKJ,KAAK,CAAbI,GAAG;IAChB,OAAO;MAAEC,UAAU,EAAEC,SAAS,CAACF,GAAG,CAAC;MAAED,GAAG,EAAHA;IAAI,CAAC;EAC5C,CAAC,CAAC;EAEF,OAAOF,MAAM;AACf,CAAC;AAAC"}
@@ -1,46 +1,52 @@
1
1
  var _parseLinks = require("./parseLinks");
2
2
  describe('parseLinksFromText', function () {
3
- it.each([['www.getstream.io', 'www.getstream.io'], ['getstream.io', 'getstream.io'], ['scrn://team-chat', 'team-chat'], ['https://localhost', 'localhost'], ['https://localhost/with/path?and=query&multiple=params', 'localhost/with/path?and=query&multiple=params'], ['https://localhost/with/path?and=query#fragment', 'localhost/with/path?and=query#fragment'], ['reactnative.stream', 'reactnative.stream'], ['https://zh.wikipedia.org/wiki/挪威牛油危機', 'zh.wikipedia.org/wiki/%E6%8C%AA%E5%A8%81%E7%89%9B%E6%B2%B9%E5%8D%B1%E6%A9%9F'], ['https://getstream.io/chat/docs/react-native/?language=javascript', 'getstream.io/chat/docs/react-native/?language=javascript'], ['127.0.0.1/local_(development)_server', '127.0.0.1/local_(development)_server'], ['https://a.co:8999/ab.php?p=12', 'a.co:8999/ab.php?p=12'], ['http://help.apple.com/xcode/mac/current/#/devba7f53ad4', 'help.apple.com/xcode/mac/current/#/devba7f53ad4']])('Returns the encoded value of %p as %p', function (link, expected) {
3
+ it.each([['https://www.getstream.io', 'https://www.getstream.io'], ['https://getstream.io', 'https://getstream.io'], ['scrn://team-chat', undefined], ['https://localhost', 'https://localhost'], ['https://localhost/with/path?and=query&multiple=params', 'https://localhost/with/path?and=query&multiple=params'], ['https://localhost/with/path?and=query#fragment', 'https://localhost/with/path?and=query#fragment'], ['reactnative.stream', undefined], ['https://zh.wikipedia.org/wiki/挪威牛油危機', 'https://zh.wikipedia.org/wiki/%E6%8C%AA%E5%A8%81%E7%89%9B%E6%B2%B9%E5%8D%B1%E6%A9%9F'], ['https://getstream.io/chat/docs/react-native/?language=javascript', 'https://getstream.io/chat/docs/react-native/?language=javascript'], ['127.0.0.1/local_(development)_server', undefined], ['https://a.co:8999/ab.php?p=12', 'https://a.co:8999/ab.php?p=12'], ['https://help.apple.com/xcode/mac/current/#/devba7f53ad4', 'https://help.apple.com/xcode/mac/current/#/devba7f53ad4']])('Returns the encoded value of %p as %p', function (link, expected) {
4
+ var _result$;
4
5
  var result = (0, _parseLinks.parseLinksFromText)(link);
5
- expect(result[0].encoded).toBe(expected);
6
+ expect((_result$ = result[0]) == null ? void 0 : _result$.encodedUrl).toBe(expected);
6
7
  });
7
8
  it('parses fqdn', function () {
8
- var input = "We have put the apim bol,\ntemporarily so :sj: we can later put the monitors on my grasp\non reality right now is\nhttps://www.contrived-example.com:8080/sub/page.php?p1=1\uD83C\uDDF3\uD83C\uDDF4&p2=2#fragment-identifier\n:)";
9
+ var input = "We have put the apim bol,\n temporarily so :sj: we can later put the monitors on my grasp\n on reality right now is\n https://www.contrived-example.com:8080/sub/page.php?p1=1\uD83C\uDDF3\uD83C\uDDF4&p2=2#fragment-identifier\n :)";
9
10
  var result = (0, _parseLinks.parseLinksFromText)(input);
10
11
  expect(result).toEqual([{
11
- encoded: 'www.contrived-example.com:8080/sub/page.php?p1=1%F0%9F%87%B3%F0%9F%87%B4&p2=2#fragment-identifier',
12
- raw: 'https://www.contrived-example.com:8080/sub/page.php?p1=1🇳🇴&p2=2#fragment-identifier',
13
- scheme: 'https://'
12
+ encodedUrl: 'https://www.contrived-example.com:8080/sub/page.php?p1=1%F0%9F%87%B3%F0%9F%87%B4&p2=2#fragment-identifier',
13
+ raw: 'https://www.contrived-example.com:8080/sub/page.php?p1=1🇳🇴&p2=2#fragment-identifier'
14
14
  }]);
15
15
  });
16
16
  it.each([['support+rn@getstream.io'], ['support.rn@getstream.io'], ['support-rn@getstream.io'], ['support_rn@getstream.io']])('Can parse the email address %p', function (email) {
17
17
  var result = (0, _parseLinks.parseLinksFromText)(email);
18
- expect(result[0].encoded).toBe(email);
19
- expect(result[0].scheme).toBe('mailto:');
18
+ expect(result[0].encodedUrl).toBe('mailto:' + email);
19
+ expect(result[0].raw).toBe(email);
20
20
  });
21
21
  it("doesn't double the mailto prefix", function () {
22
22
  var input = 'mailto:support@getstream.io';
23
23
  var result = (0, _parseLinks.parseLinksFromText)(input);
24
24
  expect(result[0]).toEqual({
25
- encoded: 'support@getstream.io',
26
- raw: input,
27
- scheme: 'mailto:'
25
+ encodedUrl: input,
26
+ raw: input
28
27
  });
29
28
  });
30
29
  it('Does not falsely parse LINKs from text content', function () {
31
- var input = "#This string exists to test that we don't produce false positives\n\nExisting links:\n[already a parsed link](https://getstream.io/blog/react-native-how-to-build-bidirectional-infinite-scroll/)\n[even a bogus one]( should not match )\n\n## These should, however, be parsed:\nwww.getstream.io\ngetstream.io\n";
30
+ var input = "#This string exists to test that we don't produce false positives\n Existing links:\n [already a parsed link](https://getstream.io/blog/react-native-how-to-build-bidirectional-infinite-scroll/)\n [even a bogus one]( should not match )\n ## These should, however, be parsed:\n www.getstream.io\n getstream.io\n ";
32
31
  var result = (0, _parseLinks.parseLinksFromText)(input);
32
+ console.log({
33
+ result: result
34
+ });
33
35
  expect(result).toHaveLength(2);
34
36
  });
35
37
  it('Encodes incomplete emoji unicode', function () {
36
38
  var input = 'https://getstream.io/�';
37
39
  var result = (0, _parseLinks.parseLinksFromText)(input);
38
40
  expect(result[0]).toEqual({
39
- encoded: 'getstream.io/%EF%BF%BD',
40
- raw: 'https://getstream.io/�',
41
- scheme: 'https://'
41
+ encodedUrl: 'https://getstream.io/%EF%BF%BD',
42
+ raw: input
42
43
  });
43
44
  });
45
+ it('doest not report invalid tlds as urls', function () {
46
+ var input = "\n %\n % Not links\n %\n example.invalid\n example.invalid/\n http://.example.com\n http://-example.com\n hppt://example.com\n example.coma\n -example.coma\n ";
47
+ var result = (0, _parseLinks.parseLinksFromText)(input);
48
+ expect(result).toHaveLength(0);
49
+ });
44
50
  it('does not parse a decimal number as a URL', function () {
45
51
  var input = '123.456';
46
52
  var result = (0, _parseLinks.parseLinksFromText)(input);
@@ -1 +1 @@
1
- {"version":3,"names":["describe","it","each","link","expected","result","parseLinksFromText","expect","encoded","toBe","input","toEqual","raw","scheme","email","toHaveLength"],"sources":["parseLinks.test.ts"],"sourcesContent":["import { parseLinksFromText } from './parseLinks';\n\ndescribe('parseLinksFromText', () => {\n it.each([\n ['www.getstream.io', 'www.getstream.io'],\n ['getstream.io', 'getstream.io'],\n ['scrn://team-chat', 'team-chat'],\n ['https://localhost', 'localhost'],\n [\n 'https://localhost/with/path?and=query&multiple=params',\n 'localhost/with/path?and=query&multiple=params',\n ],\n ['https://localhost/with/path?and=query#fragment', 'localhost/with/path?and=query#fragment'],\n ['reactnative.stream', 'reactnative.stream'],\n [\n 'https://zh.wikipedia.org/wiki/挪威牛油危機',\n 'zh.wikipedia.org/wiki/%E6%8C%AA%E5%A8%81%E7%89%9B%E6%B2%B9%E5%8D%B1%E6%A9%9F',\n ],\n [\n 'https://getstream.io/chat/docs/react-native/?language=javascript',\n 'getstream.io/chat/docs/react-native/?language=javascript',\n ],\n ['127.0.0.1/local_(development)_server', '127.0.0.1/local_(development)_server'],\n ['https://a.co:8999/ab.php?p=12', 'a.co:8999/ab.php?p=12'],\n [\n 'http://help.apple.com/xcode/mac/current/#/devba7f53ad4',\n 'help.apple.com/xcode/mac/current/#/devba7f53ad4',\n ],\n ])('Returns the encoded value of %p as %p', (link, expected) => {\n const result = parseLinksFromText(link);\n\n expect(result[0].encoded).toBe(expected);\n });\n\n it('parses fqdn', () => {\n const input = `We have put the apim bol,\ntemporarily so :sj: we can later put the monitors on my grasp\non reality right now is\nhttps://www.contrived-example.com:8080/sub/page.php?p1=1🇳🇴&p2=2#fragment-identifier\n:)`;\n\n const result = parseLinksFromText(input);\n\n expect(result).toEqual([\n {\n encoded:\n 'www.contrived-example.com:8080/sub/page.php?p1=1%F0%9F%87%B3%F0%9F%87%B4&p2=2#fragment-identifier',\n raw: 'https://www.contrived-example.com:8080/sub/page.php?p1=1🇳🇴&p2=2#fragment-identifier',\n scheme: 'https://',\n },\n ]);\n });\n\n it.each([\n ['support+rn@getstream.io'],\n ['support.rn@getstream.io'],\n ['support-rn@getstream.io'],\n ['support_rn@getstream.io'],\n ])('Can parse the email address %p', (email) => {\n const result = parseLinksFromText(email);\n\n expect(result[0].encoded).toBe(email);\n expect(result[0].scheme).toBe('mailto:');\n });\n\n it(\"doesn't double the mailto prefix\", () => {\n const input = 'mailto:support@getstream.io';\n\n const result = parseLinksFromText(input);\n\n expect(result[0]).toEqual({\n encoded: 'support@getstream.io',\n raw: input,\n scheme: 'mailto:',\n });\n });\n\n it('Does not falsely parse LINKs from text content', () => {\n const input = `#This string exists to test that we don't produce false positives\n\nExisting links:\n[already a parsed link](https://getstream.io/blog/react-native-how-to-build-bidirectional-infinite-scroll/)\n[even a bogus one]( should not match )\n\n## These should, however, be parsed:\nwww.getstream.io\ngetstream.io\n`;\n const result = parseLinksFromText(input);\n\n expect(result).toHaveLength(2);\n });\n\n it('Encodes incomplete emoji unicode', () => {\n const input = 'https://getstream.io/�';\n const result = parseLinksFromText(input);\n\n expect(result[0]).toEqual({\n encoded: 'getstream.io/%EF%BF%BD',\n raw: 'https://getstream.io/�',\n scheme: 'https://',\n });\n });\n\n it('does not parse a decimal number as a URL', () => {\n const input = '123.456';\n const result = parseLinksFromText(input);\n\n expect(result).toHaveLength(0);\n });\n\n it.each([['@user'], ['@user.name']])('does not parse %p as a URL', (input) => {\n const result = parseLinksFromText(input);\n\n expect(result).toHaveLength(0);\n });\n});\n"],"mappings":"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"}
1
+ {"version":3,"names":["describe","it","each","undefined","link","expected","result","parseLinksFromText","expect","encodedUrl","toBe","input","toEqual","raw","email","console","log","toHaveLength"],"sources":["parseLinks.test.ts"],"sourcesContent":["import { parseLinksFromText } from './parseLinks';\n\ndescribe('parseLinksFromText', () => {\n it.each([\n ['https://www.getstream.io', 'https://www.getstream.io'],\n ['https://getstream.io', 'https://getstream.io'],\n ['scrn://team-chat', undefined],\n ['https://localhost', 'https://localhost'],\n [\n 'https://localhost/with/path?and=query&multiple=params',\n 'https://localhost/with/path?and=query&multiple=params',\n ],\n [\n 'https://localhost/with/path?and=query#fragment',\n 'https://localhost/with/path?and=query#fragment',\n ],\n ['reactnative.stream', undefined],\n [\n 'https://zh.wikipedia.org/wiki/挪威牛油危機',\n 'https://zh.wikipedia.org/wiki/%E6%8C%AA%E5%A8%81%E7%89%9B%E6%B2%B9%E5%8D%B1%E6%A9%9F',\n ],\n [\n 'https://getstream.io/chat/docs/react-native/?language=javascript',\n 'https://getstream.io/chat/docs/react-native/?language=javascript',\n ],\n ['127.0.0.1/local_(development)_server', undefined],\n ['https://a.co:8999/ab.php?p=12', 'https://a.co:8999/ab.php?p=12'],\n [\n 'https://help.apple.com/xcode/mac/current/#/devba7f53ad4',\n 'https://help.apple.com/xcode/mac/current/#/devba7f53ad4',\n ],\n ])('Returns the encoded value of %p as %p', (link, expected) => {\n const result = parseLinksFromText(link);\n expect(result[0]?.encodedUrl).toBe(expected);\n });\n it('parses fqdn', () => {\n const input = `We have put the apim bol,\n temporarily so :sj: we can later put the monitors on my grasp\n on reality right now is\n https://www.contrived-example.com:8080/sub/page.php?p1=1🇳🇴&p2=2#fragment-identifier\n :)`;\n const result = parseLinksFromText(input);\n expect(result).toEqual([\n {\n encodedUrl:\n 'https://www.contrived-example.com:8080/sub/page.php?p1=1%F0%9F%87%B3%F0%9F%87%B4&p2=2#fragment-identifier',\n raw: 'https://www.contrived-example.com:8080/sub/page.php?p1=1🇳🇴&p2=2#fragment-identifier',\n },\n ]);\n });\n it.each([\n ['support+rn@getstream.io'],\n ['support.rn@getstream.io'],\n ['support-rn@getstream.io'],\n ['support_rn@getstream.io'],\n ])('Can parse the email address %p', (email) => {\n const result = parseLinksFromText(email);\n expect(result[0].encodedUrl).toBe('mailto:' + email);\n expect(result[0].raw).toBe(email);\n });\n it(\"doesn't double the mailto prefix\", () => {\n const input = 'mailto:support@getstream.io';\n const result = parseLinksFromText(input);\n expect(result[0]).toEqual({\n encodedUrl: input,\n raw: input,\n });\n });\n it('Does not falsely parse LINKs from text content', () => {\n const input = `#This string exists to test that we don't produce false positives\n Existing links:\n [already a parsed link](https://getstream.io/blog/react-native-how-to-build-bidirectional-infinite-scroll/)\n [even a bogus one]( should not match )\n ## These should, however, be parsed:\n www.getstream.io\n getstream.io\n `;\n const result = parseLinksFromText(input);\n console.log({ result });\n expect(result).toHaveLength(2);\n });\n it('Encodes incomplete emoji unicode', () => {\n const input = 'https://getstream.io/�';\n const result = parseLinksFromText(input);\n expect(result[0]).toEqual({\n encodedUrl: 'https://getstream.io/%EF%BF%BD',\n raw: input,\n });\n });\n it('doest not report invalid tlds as urls', () => {\n const input = `\n %\n % Not links\n %\n example.invalid\n example.invalid/\n http://.example.com\n http://-example.com\n hppt://example.com\n example.coma\n -example.coma\n `;\n const result = parseLinksFromText(input);\n expect(result).toHaveLength(0);\n });\n it('does not parse a decimal number as a URL', () => {\n const input = '123.456';\n const result = parseLinksFromText(input);\n expect(result).toHaveLength(0);\n });\n it.each([['@user'], ['@user.name']])('does not parse %p as a URL', (input) => {\n const result = parseLinksFromText(input);\n expect(result).toHaveLength(0);\n });\n});\n"],"mappings":"AAAA;AAEAA,QAAQ,CAAC,oBAAoB,EAAE,YAAM;EACnCC,EAAE,CAACC,IAAI,CAAC,CACN,CAAC,0BAA0B,EAAE,0BAA0B,CAAC,EACxD,CAAC,sBAAsB,EAAE,sBAAsB,CAAC,EAChD,CAAC,kBAAkB,EAAEC,SAAS,CAAC,EAC/B,CAAC,mBAAmB,EAAE,mBAAmB,CAAC,EAC1C,CACE,uDAAuD,EACvD,uDAAuD,CACxD,EACD,CACE,gDAAgD,EAChD,gDAAgD,CACjD,EACD,CAAC,oBAAoB,EAAEA,SAAS,CAAC,EACjC,CACE,sCAAsC,EACtC,sFAAsF,CACvF,EACD,CACE,kEAAkE,EAClE,kEAAkE,CACnE,EACD,CAAC,sCAAsC,EAAEA,SAAS,CAAC,EACnD,CAAC,+BAA+B,EAAE,+BAA+B,CAAC,EAClE,CACE,yDAAyD,EACzD,yDAAyD,CAC1D,CACF,CAAC,CAAC,uCAAuC,EAAE,UAACC,IAAI,EAAEC,QAAQ,EAAK;IAAA;IAC9D,IAAMC,MAAM,GAAG,IAAAC,8BAAkB,EAACH,IAAI,CAAC;IACvCI,MAAM,aAACF,MAAM,CAAC,CAAC,CAAC,qBAAT,SAAWG,UAAU,CAAC,CAACC,IAAI,CAACL,QAAQ,CAAC;EAC9C,CAAC,CAAC;EACFJ,EAAE,CAAC,aAAa,EAAE,YAAM;IACtB,IAAMU,KAAK,6OAIV;IACD,IAAML,MAAM,GAAG,IAAAC,8BAAkB,EAACI,KAAK,CAAC;IACxCH,MAAM,CAACF,MAAM,CAAC,CAACM,OAAO,CAAC,CACrB;MACEH,UAAU,EACR,2GAA2G;MAC7GI,GAAG,EAAE;IACP,CAAC,CACF,CAAC;EACJ,CAAC,CAAC;EACFZ,EAAE,CAACC,IAAI,CAAC,CACN,CAAC,yBAAyB,CAAC,EAC3B,CAAC,yBAAyB,CAAC,EAC3B,CAAC,yBAAyB,CAAC,EAC3B,CAAC,yBAAyB,CAAC,CAC5B,CAAC,CAAC,gCAAgC,EAAE,UAACY,KAAK,EAAK;IAC9C,IAAMR,MAAM,GAAG,IAAAC,8BAAkB,EAACO,KAAK,CAAC;IACxCN,MAAM,CAACF,MAAM,CAAC,CAAC,CAAC,CAACG,UAAU,CAAC,CAACC,IAAI,CAAC,SAAS,GAAGI,KAAK,CAAC;IACpDN,MAAM,CAACF,MAAM,CAAC,CAAC,CAAC,CAACO,GAAG,CAAC,CAACH,IAAI,CAACI,KAAK,CAAC;EACnC,CAAC,CAAC;EACFb,EAAE,CAAC,kCAAkC,EAAE,YAAM;IAC3C,IAAMU,KAAK,GAAG,6BAA6B;IAC3C,IAAML,MAAM,GAAG,IAAAC,8BAAkB,EAACI,KAAK,CAAC;IACxCH,MAAM,CAACF,MAAM,CAAC,CAAC,CAAC,CAAC,CAACM,OAAO,CAAC;MACxBH,UAAU,EAAEE,KAAK;MACjBE,GAAG,EAAEF;IACP,CAAC,CAAC;EACJ,CAAC,CAAC;EACFV,EAAE,CAAC,gDAAgD,EAAE,YAAM;IACzD,IAAMU,KAAK,kUAOZ;IACC,IAAML,MAAM,GAAG,IAAAC,8BAAkB,EAACI,KAAK,CAAC;IACxCI,OAAO,CAACC,GAAG,CAAC;MAAEV,MAAM,EAANA;IAAO,CAAC,CAAC;IACvBE,MAAM,CAACF,MAAM,CAAC,CAACW,YAAY,CAAC,CAAC,CAAC;EAChC,CAAC,CAAC;EACFhB,EAAE,CAAC,kCAAkC,EAAE,YAAM;IAC3C,IAAMU,KAAK,GAAG,wBAAwB;IACtC,IAAML,MAAM,GAAG,IAAAC,8BAAkB,EAACI,KAAK,CAAC;IACxCH,MAAM,CAACF,MAAM,CAAC,CAAC,CAAC,CAAC,CAACM,OAAO,CAAC;MACxBH,UAAU,EAAE,gCAAgC;MAC5CI,GAAG,EAAEF;IACP,CAAC,CAAC;EACJ,CAAC,CAAC;EACFV,EAAE,CAAC,uCAAuC,EAAE,YAAM;IAChD,IAAMU,KAAK,wMAWN;IACL,IAAML,MAAM,GAAG,IAAAC,8BAAkB,EAACI,KAAK,CAAC;IACxCH,MAAM,CAACF,MAAM,CAAC,CAACW,YAAY,CAAC,CAAC,CAAC;EAChC,CAAC,CAAC;EACFhB,EAAE,CAAC,0CAA0C,EAAE,YAAM;IACnD,IAAMU,KAAK,GAAG,SAAS;IACvB,IAAML,MAAM,GAAG,IAAAC,8BAAkB,EAACI,KAAK,CAAC;IACxCH,MAAM,CAACF,MAAM,CAAC,CAACW,YAAY,CAAC,CAAC,CAAC;EAChC,CAAC,CAAC;EACFhB,EAAE,CAACC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,4BAA4B,EAAE,UAACS,KAAK,EAAK;IAC5E,IAAML,MAAM,GAAG,IAAAC,8BAAkB,EAACI,KAAK,CAAC;IACxCH,MAAM,CAACF,MAAM,CAAC,CAACW,YAAY,CAAC,CAAC,CAAC;EAChC,CAAC,CAAC;AACJ,CAAC,CAAC"}
@@ -72,15 +72,15 @@ var renderText = function renderText(params) {
72
72
  text = message.text;
73
73
  if (!text) return null;
74
74
  var newText = text.trim();
75
- var urls = (0, _parseLinks.parseLinksFromText)(newText);
76
- for (var _iterator = _createForOfIteratorHelperLoose(urls), _step; !(_step = _iterator()).done;) {
77
- var urlInfo = _step.value;
78
- var displayLink = (0, _truncate["default"])(urlInfo.encoded, {
75
+ var linkInfos = (0, _parseLinks.parseLinksFromText)(newText);
76
+ for (var _iterator = _createForOfIteratorHelperLoose(linkInfos), _step; !(_step = _iterator()).done;) {
77
+ var linkInfo = _step.value;
78
+ var displayLink = (0, _truncate["default"])(linkInfo.raw, {
79
79
  length: 200,
80
80
  omission: '...'
81
81
  });
82
- var markdown = "[" + displayLink + "](" + urlInfo.scheme + urlInfo.encoded + ")";
83
- newText = newText.replace(urlInfo.raw, markdown);
82
+ var markdown = "[" + displayLink + "](" + linkInfo.encodedUrl + ")";
83
+ newText = newText.replace(linkInfo.raw, markdown);
84
84
  }
85
85
  newText = newText.replace(/[<&"'>]/g, '\\$&');
86
86
  var styles = (0, _extends2["default"])({}, defaultMarkdownStyles, markdownStyles, {
@@ -1 +1 @@
1
- {"version":3,"names":["defaultMarkdownStyles","inlineCode","fontSize","padding","paddingHorizontal","list","marginBottom","marginTop","listItemNumber","fontWeight","listItemText","flex","listRow","flexDirection","mentions","paragraph","paragraphCenter","paragraphWithImage","parse","capture","state","content","parseInline","renderText","params","colors","markdownRules","markdownStyles","message","messageOverlay","messageTextNumberOfLines","onLinkParams","onLink","onLongPressParam","onLongPress","onlyEmojis","onPressParam","onPress","preventPress","mentioned_users","text","newText","trim","urls","parseLinksFromText","urlInfo","displayLink","truncate","encoded","length","omission","markdown","scheme","replace","raw","styles","autolink","color","accent_blue","backgroundColor","white_smoke","borderColor","grey_gainsboro","accent_red","black","url","pattern","RegExp","test","Linking","canOpenURL","then","canOpenUrl","openURL","link","node","output","target","event","additionalInfo","defaultHandler","emitter","key","withinLink","paragraphText","mentionedUsers","Array","isArray","reduce","acc","cur","userName","name","id","regEx","match","source","exec","mentionsReact","substring","user","find","current","customRules","image","react","reflink","sublist","order","defaultRules","JSON","stringify","undefined","ListOutput","isSublist","withinList","parentTypes","items","map","item","index","indexAfterStart","start","ordered","type","isSublistWithinText","includes","style","Bullet","ListRow","props","children","ListItem"],"sources":["renderText.tsx"],"sourcesContent":["import React, { PropsWithChildren } from 'react';\nimport { GestureResponderEvent, Linking, Text, TextProps, View, ViewProps } from 'react-native';\n\n// @ts-expect-error\nimport Markdown from 'react-native-markdown-package';\n\nimport truncate from 'lodash/truncate';\nimport {\n DefaultRules,\n defaultRules,\n MatchFunction,\n ParseFunction,\n parseInline,\n ReactNodeOutput,\n ReactOutput,\n SingleASTNode,\n State,\n} from 'simple-markdown';\n\nimport type { UserResponse } from 'stream-chat';\n\nimport { parseLinksFromText } from './parseLinks';\n\nimport type { MessageContextValue } from '../../../../contexts/messageContext/MessageContext';\nimport type { Colors, MarkdownStyle } from '../../../../contexts/themeContext/utils/theme';\nimport type { DefaultStreamChatGenerics } from '../../../../types/types';\nimport type { MessageType } from '../../../MessageList/hooks/useMessageList';\n\nconst defaultMarkdownStyles: MarkdownStyle = {\n inlineCode: {\n fontSize: 13,\n padding: 3,\n paddingHorizontal: 5,\n },\n list: {\n marginBottom: 8,\n marginTop: 8,\n },\n listItemNumber: {\n fontWeight: 'bold',\n },\n listItemText: {\n flex: 0,\n },\n listRow: {\n flexDirection: 'row',\n },\n mentions: {\n fontWeight: '700',\n },\n paragraph: {\n marginBottom: 8,\n marginTop: 8,\n },\n paragraphCenter: {\n marginBottom: 8,\n marginTop: 8,\n },\n paragraphWithImage: {\n marginBottom: 8,\n marginTop: 8,\n },\n};\n\nconst parse: ParseFunction = (capture, parse, state) => ({\n content: parseInline(parse, capture[0], state),\n});\n\nexport type MarkdownRules = Partial<DefaultRules>;\n\nexport type RenderTextParams<\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n> = Partial<\n Pick<MessageContextValue<StreamChatGenerics>, 'onLongPress' | 'onPress' | 'preventPress'>\n> & {\n colors: typeof Colors;\n message: MessageType<StreamChatGenerics>;\n markdownRules?: MarkdownRules;\n markdownStyles?: MarkdownStyle;\n messageOverlay?: boolean;\n messageTextNumberOfLines?: number;\n onLink?: (url: string) => Promise<void>;\n onlyEmojis?: boolean;\n};\n\nexport const renderText = <\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n>(\n params: RenderTextParams<StreamChatGenerics>,\n) => {\n const {\n colors,\n markdownRules,\n markdownStyles,\n message,\n messageOverlay,\n messageTextNumberOfLines,\n onLink: onLinkParams,\n onLongPress: onLongPressParam,\n onlyEmojis,\n onPress: onPressParam,\n preventPress,\n } = params;\n\n // take the @ mentions and turn them into markdown?\n // translate links\n const { mentioned_users, text } = message;\n\n if (!text) return null;\n\n let newText = text.trim();\n const urls = parseLinksFromText(newText);\n\n for (const urlInfo of urls) {\n const displayLink = truncate(urlInfo.encoded, {\n length: 200,\n omission: '...',\n });\n const markdown = `[${displayLink}](${urlInfo.scheme}${urlInfo.encoded})`;\n newText = newText.replace(urlInfo.raw, markdown);\n }\n\n newText = newText.replace(/[<&\"'>]/g, '\\\\$&');\n\n const styles: MarkdownStyle = {\n ...defaultMarkdownStyles,\n ...markdownStyles,\n autolink: {\n ...defaultMarkdownStyles.autolink,\n color: colors.accent_blue,\n ...markdownStyles?.autolink,\n },\n inlineCode: {\n ...defaultMarkdownStyles.inlineCode,\n backgroundColor: colors.white_smoke,\n borderColor: colors.grey_gainsboro,\n color: colors.accent_red,\n ...markdownStyles?.inlineCode,\n },\n mentions: {\n ...defaultMarkdownStyles.mentions,\n color: colors.accent_blue,\n ...markdownStyles?.mentions,\n },\n text: {\n ...defaultMarkdownStyles.text,\n color: colors.black,\n ...markdownStyles?.text,\n },\n };\n\n const onLink = (url: string) => {\n const pattern = new RegExp(/^\\S+:\\/\\//);\n if (!pattern.test(url)) {\n url = 'http://' + url;\n }\n\n return onLinkParams\n ? onLinkParams(url)\n : Linking.canOpenURL(url).then((canOpenUrl) => canOpenUrl && Linking.openURL(url));\n };\n\n const link: ReactNodeOutput = (node, output, { ...state }) => {\n const url = node.target;\n const onPress = (event: GestureResponderEvent) => {\n if (!preventPress && onPressParam) {\n onPressParam({\n additionalInfo: { url },\n defaultHandler: () => {\n onLink(url);\n },\n emitter: 'textLink',\n event,\n });\n }\n };\n\n const onLongPress = (event: GestureResponderEvent) => {\n if (!preventPress && onLongPressParam) {\n onLongPressParam({\n additionalInfo: { url },\n emitter: 'textLink',\n event,\n });\n }\n };\n\n return (\n <Text\n key={state.key}\n onLongPress={onLongPress}\n onPress={onPress}\n style={styles.autolink}\n suppressHighlighting={true}\n >\n {output(node.content, { ...state, withinLink: true })}\n </Text>\n );\n };\n\n const paragraphText: ReactNodeOutput = (node, output, { ...state }) => (\n <Text key={state.key} numberOfLines={messageTextNumberOfLines} style={styles.paragraph}>\n {output(node.content, state)}\n </Text>\n );\n\n const mentionedUsers = Array.isArray(mentioned_users)\n ? mentioned_users.reduce((acc, cur) => {\n const userName = cur.name || cur.id || '';\n if (userName) {\n acc += `${acc.length ? '|' : ''}@${userName}`;\n }\n return acc;\n }, '')\n : '';\n\n const regEx = new RegExp(`^\\\\B(${mentionedUsers})`, 'g');\n const match: MatchFunction = (source) => regEx.exec(source);\n\n const mentionsReact: ReactNodeOutput = (node, output, { ...state }) => {\n /**removes the @ prefix of username */\n const userName = node.content[0]?.content?.substring(1);\n const onPress = (event: GestureResponderEvent) => {\n if (!preventPress && onPressParam) {\n onPressParam({\n additionalInfo: {\n user: mentioned_users?.find(\n (user: UserResponse<StreamChatGenerics>) => userName === user.name,\n ),\n },\n emitter: 'textMention',\n event,\n });\n }\n };\n\n const onLongPress = (event: GestureResponderEvent) => {\n if (!preventPress && onLongPressParam) {\n onLongPressParam({\n emitter: 'textMention',\n event,\n });\n }\n };\n\n return (\n <Text key={state.key} onLongPress={onLongPress} onPress={onPress} style={styles.mentions}>\n {Array.isArray(node.content)\n ? node.content.reduce((acc, current) => acc + current.content, '') || ''\n : output(node.content, state)}\n </Text>\n );\n };\n\n const list: ReactNodeOutput = (node, output, state) => (\n <ListOutput\n key={`list-${state.key}`}\n node={node}\n output={output}\n state={state}\n styles={styles}\n />\n );\n\n const customRules = {\n // do not render images, we will scrape them out of the message and show on attachment card component\n image: { match: () => null },\n link: { react: link },\n list: { react: list },\n // Truncate long text content in the message overlay\n paragraph: messageTextNumberOfLines ? { react: paragraphText } : {},\n // we have no react rendering support for reflinks\n reflink: { match: () => null },\n sublist: { react: list },\n ...(mentionedUsers\n ? {\n mentions: {\n match,\n order: defaultRules.text.order - 0.5,\n parse,\n react: mentionsReact,\n },\n }\n : {}),\n };\n\n return (\n <Markdown\n key={`${JSON.stringify(mentioned_users)}-${onlyEmojis}-${\n messageOverlay ? JSON.stringify(markdownStyles) : undefined\n }-${JSON.stringify(colors)}`}\n onLink={onLink}\n rules={{\n ...customRules,\n ...markdownRules,\n }}\n styles={styles}\n >\n {newText}\n </Markdown>\n );\n};\n\nexport interface ListOutputProps {\n node: SingleASTNode;\n output: ReactOutput;\n state: State;\n styles?: Partial<MarkdownStyle>;\n}\n\n/**\n * For lists and sublists, the default behavior of the markdown library we use is\n * to always renumber any list, so all ordered lists start from 1.\n *\n * This custom rule overrides this behavior both for top level lists and sublists,\n * in order to start the numbering from the number of the first list item provided.\n */\nexport const ListOutput = ({ node, output, state, styles }: ListOutputProps) => {\n let isSublist = state.withinList;\n const parentTypes = ['text', 'paragraph', 'strong'];\n\n return (\n <View key={state.key} style={isSublist ? styles?.sublist : styles?.list}>\n {node.items.map((item: SingleASTNode, index: number) => {\n const indexAfterStart = node.start + index;\n\n if (item === null) {\n return (\n <ListRow key={index} style={styles?.listRow} testID='list-item'>\n <Bullet index={node.ordered && indexAfterStart} />\n </ListRow>\n );\n }\n\n isSublist = item.length > 1 && item[1].type === 'list';\n const isSublistWithinText = parentTypes.includes((item[0] ?? {}).type) && isSublist;\n const style = isSublistWithinText ? { marginBottom: 0 } : {};\n\n return (\n <ListRow key={index} style={styles?.listRow} testID='list-item'>\n <Bullet index={node.ordered && indexAfterStart} />\n <ListItem key={1} style={[styles?.listItemText, style]}>\n {output(item, state)}\n </ListItem>\n </ListRow>\n );\n })}\n </View>\n );\n};\n\ninterface BulletProps extends TextProps {\n index?: number;\n}\n\nconst Bullet = ({ index, style }: BulletProps) => (\n <Text key={0} style={[style, defaultMarkdownStyles.listItemNumber]}>\n {index ? `${index}. ` : '\\u2022 '}\n </Text>\n);\n\nconst ListRow = (props: PropsWithChildren<ViewProps>) => (\n <Text style={[props.style, defaultMarkdownStyles.listRow]}>{props.children}</Text>\n);\n\nconst ListItem = ({ children, style }: PropsWithChildren<TextProps>) => (\n <Text style={style}>{children}</Text>\n);\n"],"mappings":"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"}
1
+ {"version":3,"names":["defaultMarkdownStyles","inlineCode","fontSize","padding","paddingHorizontal","list","marginBottom","marginTop","listItemNumber","fontWeight","listItemText","flex","listRow","flexDirection","mentions","paragraph","paragraphCenter","paragraphWithImage","parse","capture","state","content","parseInline","renderText","params","colors","markdownRules","markdownStyles","message","messageOverlay","messageTextNumberOfLines","onLinkParams","onLink","onLongPressParam","onLongPress","onlyEmojis","onPressParam","onPress","preventPress","mentioned_users","text","newText","trim","linkInfos","parseLinksFromText","linkInfo","displayLink","truncate","raw","length","omission","markdown","encodedUrl","replace","styles","autolink","color","accent_blue","backgroundColor","white_smoke","borderColor","grey_gainsboro","accent_red","black","url","pattern","RegExp","test","Linking","canOpenURL","then","canOpenUrl","openURL","link","node","output","target","event","additionalInfo","defaultHandler","emitter","key","withinLink","paragraphText","mentionedUsers","Array","isArray","reduce","acc","cur","userName","name","id","regEx","match","source","exec","mentionsReact","substring","user","find","current","customRules","image","react","reflink","sublist","order","defaultRules","JSON","stringify","undefined","ListOutput","isSublist","withinList","parentTypes","items","map","item","index","indexAfterStart","start","ordered","type","isSublistWithinText","includes","style","Bullet","ListRow","props","children","ListItem"],"sources":["renderText.tsx"],"sourcesContent":["import React, { PropsWithChildren } from 'react';\nimport { GestureResponderEvent, Linking, Text, TextProps, View, ViewProps } from 'react-native';\n\n// @ts-expect-error\nimport Markdown from 'react-native-markdown-package';\n\nimport truncate from 'lodash/truncate';\nimport {\n DefaultRules,\n defaultRules,\n MatchFunction,\n ParseFunction,\n parseInline,\n ReactNodeOutput,\n ReactOutput,\n SingleASTNode,\n State,\n} from 'simple-markdown';\n\nimport type { UserResponse } from 'stream-chat';\n\nimport { parseLinksFromText } from './parseLinks';\n\nimport type { MessageContextValue } from '../../../../contexts/messageContext/MessageContext';\nimport type { Colors, MarkdownStyle } from '../../../../contexts/themeContext/utils/theme';\nimport type { DefaultStreamChatGenerics } from '../../../../types/types';\nimport type { MessageType } from '../../../MessageList/hooks/useMessageList';\n\nconst defaultMarkdownStyles: MarkdownStyle = {\n inlineCode: {\n fontSize: 13,\n padding: 3,\n paddingHorizontal: 5,\n },\n list: {\n marginBottom: 8,\n marginTop: 8,\n },\n listItemNumber: {\n fontWeight: 'bold',\n },\n listItemText: {\n flex: 0,\n },\n listRow: {\n flexDirection: 'row',\n },\n mentions: {\n fontWeight: '700',\n },\n paragraph: {\n marginBottom: 8,\n marginTop: 8,\n },\n paragraphCenter: {\n marginBottom: 8,\n marginTop: 8,\n },\n paragraphWithImage: {\n marginBottom: 8,\n marginTop: 8,\n },\n};\n\nconst parse: ParseFunction = (capture, parse, state) => ({\n content: parseInline(parse, capture[0], state),\n});\n\nexport type MarkdownRules = Partial<DefaultRules>;\n\nexport type RenderTextParams<\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n> = Partial<\n Pick<MessageContextValue<StreamChatGenerics>, 'onLongPress' | 'onPress' | 'preventPress'>\n> & {\n colors: typeof Colors;\n message: MessageType<StreamChatGenerics>;\n markdownRules?: MarkdownRules;\n markdownStyles?: MarkdownStyle;\n messageOverlay?: boolean;\n messageTextNumberOfLines?: number;\n onLink?: (url: string) => Promise<void>;\n onlyEmojis?: boolean;\n};\n\nexport const renderText = <\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n>(\n params: RenderTextParams<StreamChatGenerics>,\n) => {\n const {\n colors,\n markdownRules,\n markdownStyles,\n message,\n messageOverlay,\n messageTextNumberOfLines,\n onLink: onLinkParams,\n onLongPress: onLongPressParam,\n onlyEmojis,\n onPress: onPressParam,\n preventPress,\n } = params;\n\n // take the @ mentions and turn them into markdown?\n // translate links\n const { mentioned_users, text } = message;\n\n if (!text) return null;\n\n let newText = text.trim();\n const linkInfos = parseLinksFromText(newText);\n\n for (const linkInfo of linkInfos) {\n const displayLink = truncate(linkInfo.raw, {\n length: 200,\n omission: '...',\n });\n const markdown = `[${displayLink}](${linkInfo.encodedUrl})`;\n newText = newText.replace(linkInfo.raw, markdown);\n }\n\n newText = newText.replace(/[<&\"'>]/g, '\\\\$&');\n\n const styles: MarkdownStyle = {\n ...defaultMarkdownStyles,\n ...markdownStyles,\n autolink: {\n ...defaultMarkdownStyles.autolink,\n color: colors.accent_blue,\n ...markdownStyles?.autolink,\n },\n inlineCode: {\n ...defaultMarkdownStyles.inlineCode,\n backgroundColor: colors.white_smoke,\n borderColor: colors.grey_gainsboro,\n color: colors.accent_red,\n ...markdownStyles?.inlineCode,\n },\n mentions: {\n ...defaultMarkdownStyles.mentions,\n color: colors.accent_blue,\n ...markdownStyles?.mentions,\n },\n text: {\n ...defaultMarkdownStyles.text,\n color: colors.black,\n ...markdownStyles?.text,\n },\n };\n\n const onLink = (url: string) => {\n const pattern = new RegExp(/^\\S+:\\/\\//);\n if (!pattern.test(url)) {\n url = 'http://' + url;\n }\n\n return onLinkParams\n ? onLinkParams(url)\n : Linking.canOpenURL(url).then((canOpenUrl) => canOpenUrl && Linking.openURL(url));\n };\n\n const link: ReactNodeOutput = (node, output, { ...state }) => {\n const url = node.target;\n const onPress = (event: GestureResponderEvent) => {\n if (!preventPress && onPressParam) {\n onPressParam({\n additionalInfo: { url },\n defaultHandler: () => {\n onLink(url);\n },\n emitter: 'textLink',\n event,\n });\n }\n };\n\n const onLongPress = (event: GestureResponderEvent) => {\n if (!preventPress && onLongPressParam) {\n onLongPressParam({\n additionalInfo: { url },\n emitter: 'textLink',\n event,\n });\n }\n };\n\n return (\n <Text\n key={state.key}\n onLongPress={onLongPress}\n onPress={onPress}\n style={styles.autolink}\n suppressHighlighting={true}\n >\n {output(node.content, { ...state, withinLink: true })}\n </Text>\n );\n };\n\n const paragraphText: ReactNodeOutput = (node, output, { ...state }) => (\n <Text key={state.key} numberOfLines={messageTextNumberOfLines} style={styles.paragraph}>\n {output(node.content, state)}\n </Text>\n );\n\n const mentionedUsers = Array.isArray(mentioned_users)\n ? mentioned_users.reduce((acc, cur) => {\n const userName = cur.name || cur.id || '';\n if (userName) {\n acc += `${acc.length ? '|' : ''}@${userName}`;\n }\n return acc;\n }, '')\n : '';\n\n const regEx = new RegExp(`^\\\\B(${mentionedUsers})`, 'g');\n const match: MatchFunction = (source) => regEx.exec(source);\n\n const mentionsReact: ReactNodeOutput = (node, output, { ...state }) => {\n /**removes the @ prefix of username */\n const userName = node.content[0]?.content?.substring(1);\n const onPress = (event: GestureResponderEvent) => {\n if (!preventPress && onPressParam) {\n onPressParam({\n additionalInfo: {\n user: mentioned_users?.find(\n (user: UserResponse<StreamChatGenerics>) => userName === user.name,\n ),\n },\n emitter: 'textMention',\n event,\n });\n }\n };\n\n const onLongPress = (event: GestureResponderEvent) => {\n if (!preventPress && onLongPressParam) {\n onLongPressParam({\n emitter: 'textMention',\n event,\n });\n }\n };\n\n return (\n <Text key={state.key} onLongPress={onLongPress} onPress={onPress} style={styles.mentions}>\n {Array.isArray(node.content)\n ? node.content.reduce((acc, current) => acc + current.content, '') || ''\n : output(node.content, state)}\n </Text>\n );\n };\n\n const list: ReactNodeOutput = (node, output, state) => (\n <ListOutput\n key={`list-${state.key}`}\n node={node}\n output={output}\n state={state}\n styles={styles}\n />\n );\n\n const customRules = {\n // do not render images, we will scrape them out of the message and show on attachment card component\n image: { match: () => null },\n link: { react: link },\n list: { react: list },\n // Truncate long text content in the message overlay\n paragraph: messageTextNumberOfLines ? { react: paragraphText } : {},\n // we have no react rendering support for reflinks\n reflink: { match: () => null },\n sublist: { react: list },\n ...(mentionedUsers\n ? {\n mentions: {\n match,\n order: defaultRules.text.order - 0.5,\n parse,\n react: mentionsReact,\n },\n }\n : {}),\n };\n\n return (\n <Markdown\n key={`${JSON.stringify(mentioned_users)}-${onlyEmojis}-${\n messageOverlay ? JSON.stringify(markdownStyles) : undefined\n }-${JSON.stringify(colors)}`}\n onLink={onLink}\n rules={{\n ...customRules,\n ...markdownRules,\n }}\n styles={styles}\n >\n {newText}\n </Markdown>\n );\n};\n\nexport interface ListOutputProps {\n node: SingleASTNode;\n output: ReactOutput;\n state: State;\n styles?: Partial<MarkdownStyle>;\n}\n\n/**\n * For lists and sublists, the default behavior of the markdown library we use is\n * to always renumber any list, so all ordered lists start from 1.\n *\n * This custom rule overrides this behavior both for top level lists and sublists,\n * in order to start the numbering from the number of the first list item provided.\n */\nexport const ListOutput = ({ node, output, state, styles }: ListOutputProps) => {\n let isSublist = state.withinList;\n const parentTypes = ['text', 'paragraph', 'strong'];\n\n return (\n <View key={state.key} style={isSublist ? styles?.sublist : styles?.list}>\n {node.items.map((item: SingleASTNode, index: number) => {\n const indexAfterStart = node.start + index;\n\n if (item === null) {\n return (\n <ListRow key={index} style={styles?.listRow} testID='list-item'>\n <Bullet index={node.ordered && indexAfterStart} />\n </ListRow>\n );\n }\n\n isSublist = item.length > 1 && item[1].type === 'list';\n const isSublistWithinText = parentTypes.includes((item[0] ?? {}).type) && isSublist;\n const style = isSublistWithinText ? { marginBottom: 0 } : {};\n\n return (\n <ListRow key={index} style={styles?.listRow} testID='list-item'>\n <Bullet index={node.ordered && indexAfterStart} />\n <ListItem key={1} style={[styles?.listItemText, style]}>\n {output(item, state)}\n </ListItem>\n </ListRow>\n );\n })}\n </View>\n );\n};\n\ninterface BulletProps extends TextProps {\n index?: number;\n}\n\nconst Bullet = ({ index, style }: BulletProps) => (\n <Text key={0} style={[style, defaultMarkdownStyles.listItemNumber]}>\n {index ? `${index}. ` : '\\u2022 '}\n </Text>\n);\n\nconst ListRow = (props: PropsWithChildren<ViewProps>) => (\n <Text style={[props.style, defaultMarkdownStyles.listRow]}>{props.children}</Text>\n);\n\nconst ListItem = ({ children, style }: PropsWithChildren<TextProps>) => (\n <Text style={style}>{children}</Text>\n);\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "5.10.0-beta.1"
2
+ "version": "5.10.0"
3
3
  }
@@ -3,17 +3,7 @@ Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
5
  exports.parseLinksFromText = void 0;
6
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
7
- var emailUserName = '[\\w+\\.~$_-]+';
8
- var schema = "(\\w{2,15}:\\/\\/)";
9
- var domain = "((?:\\w+\\.[a-zA-Z]+)+(?:[^:\\/\\s]+)|(?:\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}))";
10
- var port = "(:[0-9]{1,5})";
11
- var path = "((?:\\/)?[^?\\s]+)";
12
- var queryString = "(\\?[^#\\s]+)";
13
- var fragment = "(#[\\w_-]+)";
14
- var emailPattern = "(mailto:)?((?:" + emailUserName + ")@(?:" + domain + "))";
15
- var schemePrefixedLinkPattern = schema + "(\\S+)";
16
- var fqdnLinkPattern = schema + "?" + domain + port + "?" + path + "?" + queryString + "?" + fragment + "?";
6
+ var _linkifyIt = _interopRequireDefault(require("linkify-it"));
17
7
  var removeMarkdownLinksFromText = function removeMarkdownLinksFromText(input) {
18
8
  return input.replace(/\[[\w\s]+\]\(.*\)/g, '');
19
9
  };
@@ -21,61 +11,21 @@ var removeUserNamesFromText = function removeUserNamesFromText(input) {
21
11
  return input.replace(/^@\w+\.?\w/, '');
22
12
  };
23
13
  var parseLinksFromText = function parseLinksFromText(input) {
24
- var matches;
14
+ var _linkify$match;
25
15
  var strippedInput = [removeMarkdownLinksFromText, removeUserNamesFromText].reduce(function (acc, fn) {
26
16
  return fn(acc);
27
17
  }, input);
28
- var results = [];
29
- var emailRegExp = new RegExp(emailPattern, 'gi');
30
- while ((matches = emailRegExp.exec(input)) !== null) {
31
- var _matches = matches,
32
- _matches2 = (0, _slicedToArray2["default"])(_matches, 3),
33
- raw = _matches2[0],
34
- _matches2$ = _matches2[1],
35
- scheme = _matches2$ === void 0 ? 'mailto:' : _matches2$,
36
- displayValue = _matches2[2];
37
- results.push({
38
- encoded: encodeURI(displayValue),
39
- raw: raw,
40
- scheme: scheme
41
- });
42
- }
43
- var linkRegex = new RegExp(fqdnLinkPattern + "|" + schemePrefixedLinkPattern, 'gi');
44
- while ((matches = linkRegex.exec(strippedInput)) !== null) {
45
- var _matches3 = matches,
46
- _matches4 = (0, _slicedToArray2["default"])(_matches3, 9),
47
- _raw = _matches4[0],
48
- _matches4$ = _matches4[1],
49
- fqdnScheme = _matches4$ === void 0 ? '' : _matches4$,
50
- _matches4$2 = _matches4[2],
51
- fqdnDomainName = _matches4$2 === void 0 ? '' : _matches4$2,
52
- _matches4$3 = _matches4[3],
53
- fqdnPort = _matches4$3 === void 0 ? '' : _matches4$3,
54
- _matches4$4 = _matches4[4],
55
- fqdnPath = _matches4$4 === void 0 ? '' : _matches4$4,
56
- _matches4$5 = _matches4[5],
57
- fqdnQueryStraing = _matches4$5 === void 0 ? '' : _matches4$5,
58
- _matches4$6 = _matches4[6],
59
- fqdnFragment = _matches4$6 === void 0 ? '' : _matches4$6,
60
- _matches4$7 = _matches4[7],
61
- schemePrefixedScheme = _matches4$7 === void 0 ? '' : _matches4$7,
62
- _matches4$8 = _matches4[8],
63
- schemePrefixedPath = _matches4$8 === void 0 ? '' : _matches4$8;
64
- if (schemePrefixedScheme !== '') {
65
- results.push({
66
- encoded: encodeURI(schemePrefixedPath),
67
- raw: _raw,
68
- scheme: schemePrefixedScheme
69
- });
70
- continue;
71
- }
72
- results.push({
73
- encoded: encodeURI([fqdnDomainName, fqdnPort, fqdnPath, fqdnQueryStraing, fqdnFragment].join('')),
74
- raw: _raw,
75
- scheme: fqdnScheme
76
- });
77
- }
78
- return results;
18
+ var linkify = (0, _linkifyIt["default"])();
19
+ var matches = (_linkify$match = linkify.match(strippedInput)) != null ? _linkify$match : [];
20
+ var result = matches.map(function (match) {
21
+ var raw = match.raw,
22
+ url = match.url;
23
+ return {
24
+ encodedUrl: encodeURI(url),
25
+ raw: raw
26
+ };
27
+ });
28
+ return result;
79
29
  };
80
30
  exports.parseLinksFromText = parseLinksFromText;
81
31
  //# sourceMappingURL=parseLinks.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["emailUserName","schema","domain","port","path","queryString","fragment","emailPattern","schemePrefixedLinkPattern","fqdnLinkPattern","removeMarkdownLinksFromText","input","replace","removeUserNamesFromText","parseLinksFromText","matches","strippedInput","reduce","acc","fn","results","emailRegExp","RegExp","exec","raw","scheme","displayValue","push","encoded","encodeURI","linkRegex","fqdnScheme","fqdnDomainName","fqdnPort","fqdnPath","fqdnQueryStraing","fqdnFragment","schemePrefixedScheme","schemePrefixedPath","join"],"sources":["parseLinks.ts"],"sourcesContent":["/**\n * 📣 Note: Do not use named capture groups, as\n * it is not yet available in Hermes.\n *\n * These helpers indend to make it easier to skim read\n * the patterns below, but note that some are optional,\n * specified in the patterns these are added to.\n * */\nconst emailUserName = '[\\\\w+\\\\.~$_-]+';\nconst schema = `(\\\\w{2,15}:\\\\/\\\\/)`;\n// something.tld OR 123.123.123.123\nconst domain = `((?:\\\\w+\\\\.[a-zA-Z]+)+(?:[^:\\\\/\\\\s]+)|(?:\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}\\\\.\\\\d{1,3}))`;\nconst port = `(:[0-9]{1,5})`;\nconst path = `((?:\\\\/)?[^?\\\\s]+)`;\nconst queryString = `(\\\\?[^#\\\\s]+)`;\nconst fragment = `(#[\\\\w_-]+)`;\n\n/**\n * Match any email address, with and without `mailto:`\n */\nconst emailPattern = `(mailto:)?((?:${emailUserName})@(?:${domain}))`;\n\n/**\n * Match any string starting with something that seems like it's a schema.\n * */\nconst schemePrefixedLinkPattern = `${schema}(\\\\S+)`;\n\n/**\n * Match as much as possible of a fqdn, at least with a domain name formed as\n * something.tld\n */\nconst fqdnLinkPattern = `${schema}?${domain}${port}?${path}?${queryString}?${fragment}?`;\n\ninterface Link {\n encoded: string;\n raw: string;\n scheme: string;\n}\n\n/**\n * This is done separately because of the version of javascript run\n * for expo\n * */\nconst removeMarkdownLinksFromText = (input: string) => input.replace(/\\[[\\w\\s]+\\]\\(.*\\)/g, '');\n\n/**\n * Hermes doesn't support lookbehind, so this is done separately to avoid\n * parsing user names as links.\n * */\nconst removeUserNamesFromText = (input: string) => input.replace(/^@\\w+\\.?\\w/, '');\n\nexport const parseLinksFromText = (input: string): Link[] => {\n let matches;\n\n const strippedInput = [removeMarkdownLinksFromText, removeUserNamesFromText].reduce(\n (acc, fn) => fn(acc),\n input,\n );\n\n const results: Link[] = [];\n\n const emailRegExp = new RegExp(emailPattern, 'gi');\n while ((matches = emailRegExp.exec(input)) !== null) {\n const [raw, scheme = 'mailto:', displayValue] = matches;\n results.push({ encoded: encodeURI(displayValue), raw, scheme });\n }\n\n /**\n * The two link patterns are checked with an \"or\" (`|`)\n * to avoid overlapping matches being duplicated in the output.\n * */\n const linkRegex = new RegExp(`${fqdnLinkPattern}|${schemePrefixedLinkPattern}`, 'gi');\n while ((matches = linkRegex.exec(strippedInput)) !== null) {\n const [\n raw,\n fqdnScheme = '',\n fqdnDomainName = '',\n fqdnPort = '',\n fqdnPath = '',\n fqdnQueryStraing = '',\n fqdnFragment = '',\n schemePrefixedScheme = '',\n schemePrefixedPath = '',\n ] = matches;\n\n if (schemePrefixedScheme !== '') {\n results.push({\n encoded: encodeURI(schemePrefixedPath),\n raw,\n scheme: schemePrefixedScheme,\n });\n continue;\n }\n\n results.push({\n encoded: encodeURI(\n [fqdnDomainName, fqdnPort, fqdnPath, fqdnQueryStraing, fqdnFragment].join(''),\n ),\n raw,\n scheme: fqdnScheme,\n });\n }\n\n return results;\n};\n"],"mappings":";;;;;;AAQA,IAAMA,aAAa,GAAG,gBAAgB;AACtC,IAAMC,MAAM,uBAAuB;AAEnC,IAAMC,MAAM,yFAAyF;AACrG,IAAMC,IAAI,kBAAkB;AAC5B,IAAMC,IAAI,uBAAuB;AACjC,IAAMC,WAAW,kBAAkB;AACnC,IAAMC,QAAQ,gBAAgB;AAK9B,IAAMC,YAAY,sBAAoBP,aAAa,aAAQE,MAAM,OAAI;AAKrE,IAAMM,yBAAyB,GAAMP,MAAM,WAAQ;AAMnD,IAAMQ,eAAe,GAAMR,MAAM,SAAIC,MAAM,GAAGC,IAAI,SAAIC,IAAI,SAAIC,WAAW,SAAIC,QAAQ,MAAG;AAYxF,IAAMI,2BAA2B,GAAG,SAA9BA,2BAA2B,CAAIC,KAAa;EAAA,OAAKA,KAAK,CAACC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC;AAAA;AAM9F,IAAMC,uBAAuB,GAAG,SAA1BA,uBAAuB,CAAIF,KAAa;EAAA,OAAKA,KAAK,CAACC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;AAAA;AAE3E,IAAME,kBAAkB,GAAG,SAArBA,kBAAkB,CAAIH,KAAa,EAAa;EAC3D,IAAII,OAAO;EAEX,IAAMC,aAAa,GAAG,CAACN,2BAA2B,EAAEG,uBAAuB,CAAC,CAACI,MAAM,CACjF,UAACC,GAAG,EAAEC,EAAE;IAAA,OAAKA,EAAE,CAACD,GAAG,CAAC;EAAA,GACpBP,KAAK,CACN;EAED,IAAMS,OAAe,GAAG,EAAE;EAE1B,IAAMC,WAAW,GAAG,IAAIC,MAAM,CAACf,YAAY,EAAE,IAAI,CAAC;EAClD,OAAO,CAACQ,OAAO,GAAGM,WAAW,CAACE,IAAI,CAACZ,KAAK,CAAC,MAAM,IAAI,EAAE;IACnD,eAAgDI,OAAO;MAAA;MAAhDS,GAAG;MAAA;MAAEC,MAAM,2BAAG,SAAS;MAAEC,YAAY;IAC5CN,OAAO,CAACO,IAAI,CAAC;MAAEC,OAAO,EAAEC,SAAS,CAACH,YAAY,CAAC;MAAEF,GAAG,EAAHA,GAAG;MAAEC,MAAM,EAANA;IAAO,CAAC,CAAC;EACjE;EAMA,IAAMK,SAAS,GAAG,IAAIR,MAAM,CAAIb,eAAe,SAAID,yBAAyB,EAAI,IAAI,CAAC;EACrF,OAAO,CAACO,OAAO,GAAGe,SAAS,CAACP,IAAI,CAACP,aAAa,CAAC,MAAM,IAAI,EAAE;IACzD,gBAUID,OAAO;MAAA;MATTS,IAAG;MAAA;MACHO,UAAU,2BAAG,EAAE;MAAA;MACfC,cAAc,4BAAG,EAAE;MAAA;MACnBC,QAAQ,4BAAG,EAAE;MAAA;MACbC,QAAQ,4BAAG,EAAE;MAAA;MACbC,gBAAgB,4BAAG,EAAE;MAAA;MACrBC,YAAY,4BAAG,EAAE;MAAA;MACjBC,oBAAoB,4BAAG,EAAE;MAAA;MACzBC,kBAAkB,4BAAG,EAAE;IAGzB,IAAID,oBAAoB,KAAK,EAAE,EAAE;MAC/BjB,OAAO,CAACO,IAAI,CAAC;QACXC,OAAO,EAAEC,SAAS,CAACS,kBAAkB,CAAC;QACtCd,GAAG,EAAHA,IAAG;QACHC,MAAM,EAAEY;MACV,CAAC,CAAC;MACF;IACF;IAEAjB,OAAO,CAACO,IAAI,CAAC;MACXC,OAAO,EAAEC,SAAS,CAChB,CAACG,cAAc,EAAEC,QAAQ,EAAEC,QAAQ,EAAEC,gBAAgB,EAAEC,YAAY,CAAC,CAACG,IAAI,CAAC,EAAE,CAAC,CAC9E;MACDf,GAAG,EAAHA,IAAG;MACHC,MAAM,EAAEM;IACV,CAAC,CAAC;EACJ;EAEA,OAAOX,OAAO;AAChB,CAAC;AAAC"}
1
+ {"version":3,"names":["removeMarkdownLinksFromText","input","replace","removeUserNamesFromText","parseLinksFromText","strippedInput","reduce","acc","fn","linkify","Linkify","matches","match","result","map","raw","url","encodedUrl","encodeURI"],"sources":["parseLinks.ts"],"sourcesContent":["import Linkify from 'linkify-it';\n\ninterface LinkInfo {\n encodedUrl: string;\n raw: string;\n}\n\n/**\n * This is done separately because of the version of javascript run\n * for expo\n * */\nconst removeMarkdownLinksFromText = (input: string) => input.replace(/\\[[\\w\\s]+\\]\\(.*\\)/g, '');\n\n/**\n * Hermes doesn't support lookbehind, so this is done separately to avoid\n * parsing user names as links.\n * */\nconst removeUserNamesFromText = (input: string) => input.replace(/^@\\w+\\.?\\w/, '');\n\nexport const parseLinksFromText = (input: string): LinkInfo[] => {\n const strippedInput = [removeMarkdownLinksFromText, removeUserNamesFromText].reduce(\n (acc, fn) => fn(acc),\n input,\n );\n\n const linkify = Linkify();\n const matches = linkify.match(strippedInput) ?? [];\n\n const result: LinkInfo[] = matches.map((match) => {\n const { raw, url } = match;\n return { encodedUrl: encodeURI(url), raw };\n });\n\n return result;\n};\n"],"mappings":";;;;;AAAA;AAWA,IAAMA,2BAA2B,GAAG,SAA9BA,2BAA2B,CAAIC,KAAa;EAAA,OAAKA,KAAK,CAACC,OAAO,CAAC,oBAAoB,EAAE,EAAE,CAAC;AAAA;AAM9F,IAAMC,uBAAuB,GAAG,SAA1BA,uBAAuB,CAAIF,KAAa;EAAA,OAAKA,KAAK,CAACC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;AAAA;AAE3E,IAAME,kBAAkB,GAAG,SAArBA,kBAAkB,CAAIH,KAAa,EAAiB;EAAA;EAC/D,IAAMI,aAAa,GAAG,CAACL,2BAA2B,EAAEG,uBAAuB,CAAC,CAACG,MAAM,CACjF,UAACC,GAAG,EAAEC,EAAE;IAAA,OAAKA,EAAE,CAACD,GAAG,CAAC;EAAA,GACpBN,KAAK,CACN;EAED,IAAMQ,OAAO,GAAG,IAAAC,qBAAO,GAAE;EACzB,IAAMC,OAAO,qBAAGF,OAAO,CAACG,KAAK,CAACP,aAAa,CAAC,6BAAI,EAAE;EAElD,IAAMQ,MAAkB,GAAGF,OAAO,CAACG,GAAG,CAAC,UAACF,KAAK,EAAK;IAChD,IAAQG,GAAG,GAAUH,KAAK,CAAlBG,GAAG;MAAEC,GAAG,GAAKJ,KAAK,CAAbI,GAAG;IAChB,OAAO;MAAEC,UAAU,EAAEC,SAAS,CAACF,GAAG,CAAC;MAAED,GAAG,EAAHA;IAAI,CAAC;EAC5C,CAAC,CAAC;EAEF,OAAOF,MAAM;AACf,CAAC;AAAC"}
@@ -1,46 +1,52 @@
1
1
  var _parseLinks = require("./parseLinks");
2
2
  describe('parseLinksFromText', function () {
3
- it.each([['www.getstream.io', 'www.getstream.io'], ['getstream.io', 'getstream.io'], ['scrn://team-chat', 'team-chat'], ['https://localhost', 'localhost'], ['https://localhost/with/path?and=query&multiple=params', 'localhost/with/path?and=query&multiple=params'], ['https://localhost/with/path?and=query#fragment', 'localhost/with/path?and=query#fragment'], ['reactnative.stream', 'reactnative.stream'], ['https://zh.wikipedia.org/wiki/挪威牛油危機', 'zh.wikipedia.org/wiki/%E6%8C%AA%E5%A8%81%E7%89%9B%E6%B2%B9%E5%8D%B1%E6%A9%9F'], ['https://getstream.io/chat/docs/react-native/?language=javascript', 'getstream.io/chat/docs/react-native/?language=javascript'], ['127.0.0.1/local_(development)_server', '127.0.0.1/local_(development)_server'], ['https://a.co:8999/ab.php?p=12', 'a.co:8999/ab.php?p=12'], ['http://help.apple.com/xcode/mac/current/#/devba7f53ad4', 'help.apple.com/xcode/mac/current/#/devba7f53ad4']])('Returns the encoded value of %p as %p', function (link, expected) {
3
+ it.each([['https://www.getstream.io', 'https://www.getstream.io'], ['https://getstream.io', 'https://getstream.io'], ['scrn://team-chat', undefined], ['https://localhost', 'https://localhost'], ['https://localhost/with/path?and=query&multiple=params', 'https://localhost/with/path?and=query&multiple=params'], ['https://localhost/with/path?and=query#fragment', 'https://localhost/with/path?and=query#fragment'], ['reactnative.stream', undefined], ['https://zh.wikipedia.org/wiki/挪威牛油危機', 'https://zh.wikipedia.org/wiki/%E6%8C%AA%E5%A8%81%E7%89%9B%E6%B2%B9%E5%8D%B1%E6%A9%9F'], ['https://getstream.io/chat/docs/react-native/?language=javascript', 'https://getstream.io/chat/docs/react-native/?language=javascript'], ['127.0.0.1/local_(development)_server', undefined], ['https://a.co:8999/ab.php?p=12', 'https://a.co:8999/ab.php?p=12'], ['https://help.apple.com/xcode/mac/current/#/devba7f53ad4', 'https://help.apple.com/xcode/mac/current/#/devba7f53ad4']])('Returns the encoded value of %p as %p', function (link, expected) {
4
+ var _result$;
4
5
  var result = (0, _parseLinks.parseLinksFromText)(link);
5
- expect(result[0].encoded).toBe(expected);
6
+ expect((_result$ = result[0]) == null ? void 0 : _result$.encodedUrl).toBe(expected);
6
7
  });
7
8
  it('parses fqdn', function () {
8
- var input = "We have put the apim bol,\ntemporarily so :sj: we can later put the monitors on my grasp\non reality right now is\nhttps://www.contrived-example.com:8080/sub/page.php?p1=1\uD83C\uDDF3\uD83C\uDDF4&p2=2#fragment-identifier\n:)";
9
+ var input = "We have put the apim bol,\n temporarily so :sj: we can later put the monitors on my grasp\n on reality right now is\n https://www.contrived-example.com:8080/sub/page.php?p1=1\uD83C\uDDF3\uD83C\uDDF4&p2=2#fragment-identifier\n :)";
9
10
  var result = (0, _parseLinks.parseLinksFromText)(input);
10
11
  expect(result).toEqual([{
11
- encoded: 'www.contrived-example.com:8080/sub/page.php?p1=1%F0%9F%87%B3%F0%9F%87%B4&p2=2#fragment-identifier',
12
- raw: 'https://www.contrived-example.com:8080/sub/page.php?p1=1🇳🇴&p2=2#fragment-identifier',
13
- scheme: 'https://'
12
+ encodedUrl: 'https://www.contrived-example.com:8080/sub/page.php?p1=1%F0%9F%87%B3%F0%9F%87%B4&p2=2#fragment-identifier',
13
+ raw: 'https://www.contrived-example.com:8080/sub/page.php?p1=1🇳🇴&p2=2#fragment-identifier'
14
14
  }]);
15
15
  });
16
16
  it.each([['support+rn@getstream.io'], ['support.rn@getstream.io'], ['support-rn@getstream.io'], ['support_rn@getstream.io']])('Can parse the email address %p', function (email) {
17
17
  var result = (0, _parseLinks.parseLinksFromText)(email);
18
- expect(result[0].encoded).toBe(email);
19
- expect(result[0].scheme).toBe('mailto:');
18
+ expect(result[0].encodedUrl).toBe('mailto:' + email);
19
+ expect(result[0].raw).toBe(email);
20
20
  });
21
21
  it("doesn't double the mailto prefix", function () {
22
22
  var input = 'mailto:support@getstream.io';
23
23
  var result = (0, _parseLinks.parseLinksFromText)(input);
24
24
  expect(result[0]).toEqual({
25
- encoded: 'support@getstream.io',
26
- raw: input,
27
- scheme: 'mailto:'
25
+ encodedUrl: input,
26
+ raw: input
28
27
  });
29
28
  });
30
29
  it('Does not falsely parse LINKs from text content', function () {
31
- var input = "#This string exists to test that we don't produce false positives\n\nExisting links:\n[already a parsed link](https://getstream.io/blog/react-native-how-to-build-bidirectional-infinite-scroll/)\n[even a bogus one]( should not match )\n\n## These should, however, be parsed:\nwww.getstream.io\ngetstream.io\n";
30
+ var input = "#This string exists to test that we don't produce false positives\n Existing links:\n [already a parsed link](https://getstream.io/blog/react-native-how-to-build-bidirectional-infinite-scroll/)\n [even a bogus one]( should not match )\n ## These should, however, be parsed:\n www.getstream.io\n getstream.io\n ";
32
31
  var result = (0, _parseLinks.parseLinksFromText)(input);
32
+ console.log({
33
+ result: result
34
+ });
33
35
  expect(result).toHaveLength(2);
34
36
  });
35
37
  it('Encodes incomplete emoji unicode', function () {
36
38
  var input = 'https://getstream.io/�';
37
39
  var result = (0, _parseLinks.parseLinksFromText)(input);
38
40
  expect(result[0]).toEqual({
39
- encoded: 'getstream.io/%EF%BF%BD',
40
- raw: 'https://getstream.io/�',
41
- scheme: 'https://'
41
+ encodedUrl: 'https://getstream.io/%EF%BF%BD',
42
+ raw: input
42
43
  });
43
44
  });
45
+ it('doest not report invalid tlds as urls', function () {
46
+ var input = "\n %\n % Not links\n %\n example.invalid\n example.invalid/\n http://.example.com\n http://-example.com\n hppt://example.com\n example.coma\n -example.coma\n ";
47
+ var result = (0, _parseLinks.parseLinksFromText)(input);
48
+ expect(result).toHaveLength(0);
49
+ });
44
50
  it('does not parse a decimal number as a URL', function () {
45
51
  var input = '123.456';
46
52
  var result = (0, _parseLinks.parseLinksFromText)(input);
@@ -1 +1 @@
1
- {"version":3,"names":["describe","it","each","link","expected","result","parseLinksFromText","expect","encoded","toBe","input","toEqual","raw","scheme","email","toHaveLength"],"sources":["parseLinks.test.ts"],"sourcesContent":["import { parseLinksFromText } from './parseLinks';\n\ndescribe('parseLinksFromText', () => {\n it.each([\n ['www.getstream.io', 'www.getstream.io'],\n ['getstream.io', 'getstream.io'],\n ['scrn://team-chat', 'team-chat'],\n ['https://localhost', 'localhost'],\n [\n 'https://localhost/with/path?and=query&multiple=params',\n 'localhost/with/path?and=query&multiple=params',\n ],\n ['https://localhost/with/path?and=query#fragment', 'localhost/with/path?and=query#fragment'],\n ['reactnative.stream', 'reactnative.stream'],\n [\n 'https://zh.wikipedia.org/wiki/挪威牛油危機',\n 'zh.wikipedia.org/wiki/%E6%8C%AA%E5%A8%81%E7%89%9B%E6%B2%B9%E5%8D%B1%E6%A9%9F',\n ],\n [\n 'https://getstream.io/chat/docs/react-native/?language=javascript',\n 'getstream.io/chat/docs/react-native/?language=javascript',\n ],\n ['127.0.0.1/local_(development)_server', '127.0.0.1/local_(development)_server'],\n ['https://a.co:8999/ab.php?p=12', 'a.co:8999/ab.php?p=12'],\n [\n 'http://help.apple.com/xcode/mac/current/#/devba7f53ad4',\n 'help.apple.com/xcode/mac/current/#/devba7f53ad4',\n ],\n ])('Returns the encoded value of %p as %p', (link, expected) => {\n const result = parseLinksFromText(link);\n\n expect(result[0].encoded).toBe(expected);\n });\n\n it('parses fqdn', () => {\n const input = `We have put the apim bol,\ntemporarily so :sj: we can later put the monitors on my grasp\non reality right now is\nhttps://www.contrived-example.com:8080/sub/page.php?p1=1🇳🇴&p2=2#fragment-identifier\n:)`;\n\n const result = parseLinksFromText(input);\n\n expect(result).toEqual([\n {\n encoded:\n 'www.contrived-example.com:8080/sub/page.php?p1=1%F0%9F%87%B3%F0%9F%87%B4&p2=2#fragment-identifier',\n raw: 'https://www.contrived-example.com:8080/sub/page.php?p1=1🇳🇴&p2=2#fragment-identifier',\n scheme: 'https://',\n },\n ]);\n });\n\n it.each([\n ['support+rn@getstream.io'],\n ['support.rn@getstream.io'],\n ['support-rn@getstream.io'],\n ['support_rn@getstream.io'],\n ])('Can parse the email address %p', (email) => {\n const result = parseLinksFromText(email);\n\n expect(result[0].encoded).toBe(email);\n expect(result[0].scheme).toBe('mailto:');\n });\n\n it(\"doesn't double the mailto prefix\", () => {\n const input = 'mailto:support@getstream.io';\n\n const result = parseLinksFromText(input);\n\n expect(result[0]).toEqual({\n encoded: 'support@getstream.io',\n raw: input,\n scheme: 'mailto:',\n });\n });\n\n it('Does not falsely parse LINKs from text content', () => {\n const input = `#This string exists to test that we don't produce false positives\n\nExisting links:\n[already a parsed link](https://getstream.io/blog/react-native-how-to-build-bidirectional-infinite-scroll/)\n[even a bogus one]( should not match )\n\n## These should, however, be parsed:\nwww.getstream.io\ngetstream.io\n`;\n const result = parseLinksFromText(input);\n\n expect(result).toHaveLength(2);\n });\n\n it('Encodes incomplete emoji unicode', () => {\n const input = 'https://getstream.io/�';\n const result = parseLinksFromText(input);\n\n expect(result[0]).toEqual({\n encoded: 'getstream.io/%EF%BF%BD',\n raw: 'https://getstream.io/�',\n scheme: 'https://',\n });\n });\n\n it('does not parse a decimal number as a URL', () => {\n const input = '123.456';\n const result = parseLinksFromText(input);\n\n expect(result).toHaveLength(0);\n });\n\n it.each([['@user'], ['@user.name']])('does not parse %p as a URL', (input) => {\n const result = parseLinksFromText(input);\n\n expect(result).toHaveLength(0);\n });\n});\n"],"mappings":"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"}
1
+ {"version":3,"names":["describe","it","each","undefined","link","expected","result","parseLinksFromText","expect","encodedUrl","toBe","input","toEqual","raw","email","console","log","toHaveLength"],"sources":["parseLinks.test.ts"],"sourcesContent":["import { parseLinksFromText } from './parseLinks';\n\ndescribe('parseLinksFromText', () => {\n it.each([\n ['https://www.getstream.io', 'https://www.getstream.io'],\n ['https://getstream.io', 'https://getstream.io'],\n ['scrn://team-chat', undefined],\n ['https://localhost', 'https://localhost'],\n [\n 'https://localhost/with/path?and=query&multiple=params',\n 'https://localhost/with/path?and=query&multiple=params',\n ],\n [\n 'https://localhost/with/path?and=query#fragment',\n 'https://localhost/with/path?and=query#fragment',\n ],\n ['reactnative.stream', undefined],\n [\n 'https://zh.wikipedia.org/wiki/挪威牛油危機',\n 'https://zh.wikipedia.org/wiki/%E6%8C%AA%E5%A8%81%E7%89%9B%E6%B2%B9%E5%8D%B1%E6%A9%9F',\n ],\n [\n 'https://getstream.io/chat/docs/react-native/?language=javascript',\n 'https://getstream.io/chat/docs/react-native/?language=javascript',\n ],\n ['127.0.0.1/local_(development)_server', undefined],\n ['https://a.co:8999/ab.php?p=12', 'https://a.co:8999/ab.php?p=12'],\n [\n 'https://help.apple.com/xcode/mac/current/#/devba7f53ad4',\n 'https://help.apple.com/xcode/mac/current/#/devba7f53ad4',\n ],\n ])('Returns the encoded value of %p as %p', (link, expected) => {\n const result = parseLinksFromText(link);\n expect(result[0]?.encodedUrl).toBe(expected);\n });\n it('parses fqdn', () => {\n const input = `We have put the apim bol,\n temporarily so :sj: we can later put the monitors on my grasp\n on reality right now is\n https://www.contrived-example.com:8080/sub/page.php?p1=1🇳🇴&p2=2#fragment-identifier\n :)`;\n const result = parseLinksFromText(input);\n expect(result).toEqual([\n {\n encodedUrl:\n 'https://www.contrived-example.com:8080/sub/page.php?p1=1%F0%9F%87%B3%F0%9F%87%B4&p2=2#fragment-identifier',\n raw: 'https://www.contrived-example.com:8080/sub/page.php?p1=1🇳🇴&p2=2#fragment-identifier',\n },\n ]);\n });\n it.each([\n ['support+rn@getstream.io'],\n ['support.rn@getstream.io'],\n ['support-rn@getstream.io'],\n ['support_rn@getstream.io'],\n ])('Can parse the email address %p', (email) => {\n const result = parseLinksFromText(email);\n expect(result[0].encodedUrl).toBe('mailto:' + email);\n expect(result[0].raw).toBe(email);\n });\n it(\"doesn't double the mailto prefix\", () => {\n const input = 'mailto:support@getstream.io';\n const result = parseLinksFromText(input);\n expect(result[0]).toEqual({\n encodedUrl: input,\n raw: input,\n });\n });\n it('Does not falsely parse LINKs from text content', () => {\n const input = `#This string exists to test that we don't produce false positives\n Existing links:\n [already a parsed link](https://getstream.io/blog/react-native-how-to-build-bidirectional-infinite-scroll/)\n [even a bogus one]( should not match )\n ## These should, however, be parsed:\n www.getstream.io\n getstream.io\n `;\n const result = parseLinksFromText(input);\n console.log({ result });\n expect(result).toHaveLength(2);\n });\n it('Encodes incomplete emoji unicode', () => {\n const input = 'https://getstream.io/�';\n const result = parseLinksFromText(input);\n expect(result[0]).toEqual({\n encodedUrl: 'https://getstream.io/%EF%BF%BD',\n raw: input,\n });\n });\n it('doest not report invalid tlds as urls', () => {\n const input = `\n %\n % Not links\n %\n example.invalid\n example.invalid/\n http://.example.com\n http://-example.com\n hppt://example.com\n example.coma\n -example.coma\n `;\n const result = parseLinksFromText(input);\n expect(result).toHaveLength(0);\n });\n it('does not parse a decimal number as a URL', () => {\n const input = '123.456';\n const result = parseLinksFromText(input);\n expect(result).toHaveLength(0);\n });\n it.each([['@user'], ['@user.name']])('does not parse %p as a URL', (input) => {\n const result = parseLinksFromText(input);\n expect(result).toHaveLength(0);\n });\n});\n"],"mappings":"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"}
@@ -72,15 +72,15 @@ var renderText = function renderText(params) {
72
72
  text = message.text;
73
73
  if (!text) return null;
74
74
  var newText = text.trim();
75
- var urls = (0, _parseLinks.parseLinksFromText)(newText);
76
- for (var _iterator = _createForOfIteratorHelperLoose(urls), _step; !(_step = _iterator()).done;) {
77
- var urlInfo = _step.value;
78
- var displayLink = (0, _truncate["default"])(urlInfo.encoded, {
75
+ var linkInfos = (0, _parseLinks.parseLinksFromText)(newText);
76
+ for (var _iterator = _createForOfIteratorHelperLoose(linkInfos), _step; !(_step = _iterator()).done;) {
77
+ var linkInfo = _step.value;
78
+ var displayLink = (0, _truncate["default"])(linkInfo.raw, {
79
79
  length: 200,
80
80
  omission: '...'
81
81
  });
82
- var markdown = "[" + displayLink + "](" + urlInfo.scheme + urlInfo.encoded + ")";
83
- newText = newText.replace(urlInfo.raw, markdown);
82
+ var markdown = "[" + displayLink + "](" + linkInfo.encodedUrl + ")";
83
+ newText = newText.replace(linkInfo.raw, markdown);
84
84
  }
85
85
  newText = newText.replace(/[<&"'>]/g, '\\$&');
86
86
  var styles = (0, _extends2["default"])({}, defaultMarkdownStyles, markdownStyles, {
@@ -1 +1 @@
1
- {"version":3,"names":["defaultMarkdownStyles","inlineCode","fontSize","padding","paddingHorizontal","list","marginBottom","marginTop","listItemNumber","fontWeight","listItemText","flex","listRow","flexDirection","mentions","paragraph","paragraphCenter","paragraphWithImage","parse","capture","state","content","parseInline","renderText","params","colors","markdownRules","markdownStyles","message","messageOverlay","messageTextNumberOfLines","onLinkParams","onLink","onLongPressParam","onLongPress","onlyEmojis","onPressParam","onPress","preventPress","mentioned_users","text","newText","trim","urls","parseLinksFromText","urlInfo","displayLink","truncate","encoded","length","omission","markdown","scheme","replace","raw","styles","autolink","color","accent_blue","backgroundColor","white_smoke","borderColor","grey_gainsboro","accent_red","black","url","pattern","RegExp","test","Linking","canOpenURL","then","canOpenUrl","openURL","link","node","output","target","event","additionalInfo","defaultHandler","emitter","key","withinLink","paragraphText","mentionedUsers","Array","isArray","reduce","acc","cur","userName","name","id","regEx","match","source","exec","mentionsReact","substring","user","find","current","customRules","image","react","reflink","sublist","order","defaultRules","JSON","stringify","undefined","ListOutput","isSublist","withinList","parentTypes","items","map","item","index","indexAfterStart","start","ordered","type","isSublistWithinText","includes","style","Bullet","ListRow","props","children","ListItem"],"sources":["renderText.tsx"],"sourcesContent":["import React, { PropsWithChildren } from 'react';\nimport { GestureResponderEvent, Linking, Text, TextProps, View, ViewProps } from 'react-native';\n\n// @ts-expect-error\nimport Markdown from 'react-native-markdown-package';\n\nimport truncate from 'lodash/truncate';\nimport {\n DefaultRules,\n defaultRules,\n MatchFunction,\n ParseFunction,\n parseInline,\n ReactNodeOutput,\n ReactOutput,\n SingleASTNode,\n State,\n} from 'simple-markdown';\n\nimport type { UserResponse } from 'stream-chat';\n\nimport { parseLinksFromText } from './parseLinks';\n\nimport type { MessageContextValue } from '../../../../contexts/messageContext/MessageContext';\nimport type { Colors, MarkdownStyle } from '../../../../contexts/themeContext/utils/theme';\nimport type { DefaultStreamChatGenerics } from '../../../../types/types';\nimport type { MessageType } from '../../../MessageList/hooks/useMessageList';\n\nconst defaultMarkdownStyles: MarkdownStyle = {\n inlineCode: {\n fontSize: 13,\n padding: 3,\n paddingHorizontal: 5,\n },\n list: {\n marginBottom: 8,\n marginTop: 8,\n },\n listItemNumber: {\n fontWeight: 'bold',\n },\n listItemText: {\n flex: 0,\n },\n listRow: {\n flexDirection: 'row',\n },\n mentions: {\n fontWeight: '700',\n },\n paragraph: {\n marginBottom: 8,\n marginTop: 8,\n },\n paragraphCenter: {\n marginBottom: 8,\n marginTop: 8,\n },\n paragraphWithImage: {\n marginBottom: 8,\n marginTop: 8,\n },\n};\n\nconst parse: ParseFunction = (capture, parse, state) => ({\n content: parseInline(parse, capture[0], state),\n});\n\nexport type MarkdownRules = Partial<DefaultRules>;\n\nexport type RenderTextParams<\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n> = Partial<\n Pick<MessageContextValue<StreamChatGenerics>, 'onLongPress' | 'onPress' | 'preventPress'>\n> & {\n colors: typeof Colors;\n message: MessageType<StreamChatGenerics>;\n markdownRules?: MarkdownRules;\n markdownStyles?: MarkdownStyle;\n messageOverlay?: boolean;\n messageTextNumberOfLines?: number;\n onLink?: (url: string) => Promise<void>;\n onlyEmojis?: boolean;\n};\n\nexport const renderText = <\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n>(\n params: RenderTextParams<StreamChatGenerics>,\n) => {\n const {\n colors,\n markdownRules,\n markdownStyles,\n message,\n messageOverlay,\n messageTextNumberOfLines,\n onLink: onLinkParams,\n onLongPress: onLongPressParam,\n onlyEmojis,\n onPress: onPressParam,\n preventPress,\n } = params;\n\n // take the @ mentions and turn them into markdown?\n // translate links\n const { mentioned_users, text } = message;\n\n if (!text) return null;\n\n let newText = text.trim();\n const urls = parseLinksFromText(newText);\n\n for (const urlInfo of urls) {\n const displayLink = truncate(urlInfo.encoded, {\n length: 200,\n omission: '...',\n });\n const markdown = `[${displayLink}](${urlInfo.scheme}${urlInfo.encoded})`;\n newText = newText.replace(urlInfo.raw, markdown);\n }\n\n newText = newText.replace(/[<&\"'>]/g, '\\\\$&');\n\n const styles: MarkdownStyle = {\n ...defaultMarkdownStyles,\n ...markdownStyles,\n autolink: {\n ...defaultMarkdownStyles.autolink,\n color: colors.accent_blue,\n ...markdownStyles?.autolink,\n },\n inlineCode: {\n ...defaultMarkdownStyles.inlineCode,\n backgroundColor: colors.white_smoke,\n borderColor: colors.grey_gainsboro,\n color: colors.accent_red,\n ...markdownStyles?.inlineCode,\n },\n mentions: {\n ...defaultMarkdownStyles.mentions,\n color: colors.accent_blue,\n ...markdownStyles?.mentions,\n },\n text: {\n ...defaultMarkdownStyles.text,\n color: colors.black,\n ...markdownStyles?.text,\n },\n };\n\n const onLink = (url: string) => {\n const pattern = new RegExp(/^\\S+:\\/\\//);\n if (!pattern.test(url)) {\n url = 'http://' + url;\n }\n\n return onLinkParams\n ? onLinkParams(url)\n : Linking.canOpenURL(url).then((canOpenUrl) => canOpenUrl && Linking.openURL(url));\n };\n\n const link: ReactNodeOutput = (node, output, { ...state }) => {\n const url = node.target;\n const onPress = (event: GestureResponderEvent) => {\n if (!preventPress && onPressParam) {\n onPressParam({\n additionalInfo: { url },\n defaultHandler: () => {\n onLink(url);\n },\n emitter: 'textLink',\n event,\n });\n }\n };\n\n const onLongPress = (event: GestureResponderEvent) => {\n if (!preventPress && onLongPressParam) {\n onLongPressParam({\n additionalInfo: { url },\n emitter: 'textLink',\n event,\n });\n }\n };\n\n return (\n <Text\n key={state.key}\n onLongPress={onLongPress}\n onPress={onPress}\n style={styles.autolink}\n suppressHighlighting={true}\n >\n {output(node.content, { ...state, withinLink: true })}\n </Text>\n );\n };\n\n const paragraphText: ReactNodeOutput = (node, output, { ...state }) => (\n <Text key={state.key} numberOfLines={messageTextNumberOfLines} style={styles.paragraph}>\n {output(node.content, state)}\n </Text>\n );\n\n const mentionedUsers = Array.isArray(mentioned_users)\n ? mentioned_users.reduce((acc, cur) => {\n const userName = cur.name || cur.id || '';\n if (userName) {\n acc += `${acc.length ? '|' : ''}@${userName}`;\n }\n return acc;\n }, '')\n : '';\n\n const regEx = new RegExp(`^\\\\B(${mentionedUsers})`, 'g');\n const match: MatchFunction = (source) => regEx.exec(source);\n\n const mentionsReact: ReactNodeOutput = (node, output, { ...state }) => {\n /**removes the @ prefix of username */\n const userName = node.content[0]?.content?.substring(1);\n const onPress = (event: GestureResponderEvent) => {\n if (!preventPress && onPressParam) {\n onPressParam({\n additionalInfo: {\n user: mentioned_users?.find(\n (user: UserResponse<StreamChatGenerics>) => userName === user.name,\n ),\n },\n emitter: 'textMention',\n event,\n });\n }\n };\n\n const onLongPress = (event: GestureResponderEvent) => {\n if (!preventPress && onLongPressParam) {\n onLongPressParam({\n emitter: 'textMention',\n event,\n });\n }\n };\n\n return (\n <Text key={state.key} onLongPress={onLongPress} onPress={onPress} style={styles.mentions}>\n {Array.isArray(node.content)\n ? node.content.reduce((acc, current) => acc + current.content, '') || ''\n : output(node.content, state)}\n </Text>\n );\n };\n\n const list: ReactNodeOutput = (node, output, state) => (\n <ListOutput\n key={`list-${state.key}`}\n node={node}\n output={output}\n state={state}\n styles={styles}\n />\n );\n\n const customRules = {\n // do not render images, we will scrape them out of the message and show on attachment card component\n image: { match: () => null },\n link: { react: link },\n list: { react: list },\n // Truncate long text content in the message overlay\n paragraph: messageTextNumberOfLines ? { react: paragraphText } : {},\n // we have no react rendering support for reflinks\n reflink: { match: () => null },\n sublist: { react: list },\n ...(mentionedUsers\n ? {\n mentions: {\n match,\n order: defaultRules.text.order - 0.5,\n parse,\n react: mentionsReact,\n },\n }\n : {}),\n };\n\n return (\n <Markdown\n key={`${JSON.stringify(mentioned_users)}-${onlyEmojis}-${\n messageOverlay ? JSON.stringify(markdownStyles) : undefined\n }-${JSON.stringify(colors)}`}\n onLink={onLink}\n rules={{\n ...customRules,\n ...markdownRules,\n }}\n styles={styles}\n >\n {newText}\n </Markdown>\n );\n};\n\nexport interface ListOutputProps {\n node: SingleASTNode;\n output: ReactOutput;\n state: State;\n styles?: Partial<MarkdownStyle>;\n}\n\n/**\n * For lists and sublists, the default behavior of the markdown library we use is\n * to always renumber any list, so all ordered lists start from 1.\n *\n * This custom rule overrides this behavior both for top level lists and sublists,\n * in order to start the numbering from the number of the first list item provided.\n */\nexport const ListOutput = ({ node, output, state, styles }: ListOutputProps) => {\n let isSublist = state.withinList;\n const parentTypes = ['text', 'paragraph', 'strong'];\n\n return (\n <View key={state.key} style={isSublist ? styles?.sublist : styles?.list}>\n {node.items.map((item: SingleASTNode, index: number) => {\n const indexAfterStart = node.start + index;\n\n if (item === null) {\n return (\n <ListRow key={index} style={styles?.listRow} testID='list-item'>\n <Bullet index={node.ordered && indexAfterStart} />\n </ListRow>\n );\n }\n\n isSublist = item.length > 1 && item[1].type === 'list';\n const isSublistWithinText = parentTypes.includes((item[0] ?? {}).type) && isSublist;\n const style = isSublistWithinText ? { marginBottom: 0 } : {};\n\n return (\n <ListRow key={index} style={styles?.listRow} testID='list-item'>\n <Bullet index={node.ordered && indexAfterStart} />\n <ListItem key={1} style={[styles?.listItemText, style]}>\n {output(item, state)}\n </ListItem>\n </ListRow>\n );\n })}\n </View>\n );\n};\n\ninterface BulletProps extends TextProps {\n index?: number;\n}\n\nconst Bullet = ({ index, style }: BulletProps) => (\n <Text key={0} style={[style, defaultMarkdownStyles.listItemNumber]}>\n {index ? `${index}. ` : '\\u2022 '}\n </Text>\n);\n\nconst ListRow = (props: PropsWithChildren<ViewProps>) => (\n <Text style={[props.style, defaultMarkdownStyles.listRow]}>{props.children}</Text>\n);\n\nconst ListItem = ({ children, style }: PropsWithChildren<TextProps>) => (\n <Text style={style}>{children}</Text>\n);\n"],"mappings":"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"}
1
+ {"version":3,"names":["defaultMarkdownStyles","inlineCode","fontSize","padding","paddingHorizontal","list","marginBottom","marginTop","listItemNumber","fontWeight","listItemText","flex","listRow","flexDirection","mentions","paragraph","paragraphCenter","paragraphWithImage","parse","capture","state","content","parseInline","renderText","params","colors","markdownRules","markdownStyles","message","messageOverlay","messageTextNumberOfLines","onLinkParams","onLink","onLongPressParam","onLongPress","onlyEmojis","onPressParam","onPress","preventPress","mentioned_users","text","newText","trim","linkInfos","parseLinksFromText","linkInfo","displayLink","truncate","raw","length","omission","markdown","encodedUrl","replace","styles","autolink","color","accent_blue","backgroundColor","white_smoke","borderColor","grey_gainsboro","accent_red","black","url","pattern","RegExp","test","Linking","canOpenURL","then","canOpenUrl","openURL","link","node","output","target","event","additionalInfo","defaultHandler","emitter","key","withinLink","paragraphText","mentionedUsers","Array","isArray","reduce","acc","cur","userName","name","id","regEx","match","source","exec","mentionsReact","substring","user","find","current","customRules","image","react","reflink","sublist","order","defaultRules","JSON","stringify","undefined","ListOutput","isSublist","withinList","parentTypes","items","map","item","index","indexAfterStart","start","ordered","type","isSublistWithinText","includes","style","Bullet","ListRow","props","children","ListItem"],"sources":["renderText.tsx"],"sourcesContent":["import React, { PropsWithChildren } from 'react';\nimport { GestureResponderEvent, Linking, Text, TextProps, View, ViewProps } from 'react-native';\n\n// @ts-expect-error\nimport Markdown from 'react-native-markdown-package';\n\nimport truncate from 'lodash/truncate';\nimport {\n DefaultRules,\n defaultRules,\n MatchFunction,\n ParseFunction,\n parseInline,\n ReactNodeOutput,\n ReactOutput,\n SingleASTNode,\n State,\n} from 'simple-markdown';\n\nimport type { UserResponse } from 'stream-chat';\n\nimport { parseLinksFromText } from './parseLinks';\n\nimport type { MessageContextValue } from '../../../../contexts/messageContext/MessageContext';\nimport type { Colors, MarkdownStyle } from '../../../../contexts/themeContext/utils/theme';\nimport type { DefaultStreamChatGenerics } from '../../../../types/types';\nimport type { MessageType } from '../../../MessageList/hooks/useMessageList';\n\nconst defaultMarkdownStyles: MarkdownStyle = {\n inlineCode: {\n fontSize: 13,\n padding: 3,\n paddingHorizontal: 5,\n },\n list: {\n marginBottom: 8,\n marginTop: 8,\n },\n listItemNumber: {\n fontWeight: 'bold',\n },\n listItemText: {\n flex: 0,\n },\n listRow: {\n flexDirection: 'row',\n },\n mentions: {\n fontWeight: '700',\n },\n paragraph: {\n marginBottom: 8,\n marginTop: 8,\n },\n paragraphCenter: {\n marginBottom: 8,\n marginTop: 8,\n },\n paragraphWithImage: {\n marginBottom: 8,\n marginTop: 8,\n },\n};\n\nconst parse: ParseFunction = (capture, parse, state) => ({\n content: parseInline(parse, capture[0], state),\n});\n\nexport type MarkdownRules = Partial<DefaultRules>;\n\nexport type RenderTextParams<\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n> = Partial<\n Pick<MessageContextValue<StreamChatGenerics>, 'onLongPress' | 'onPress' | 'preventPress'>\n> & {\n colors: typeof Colors;\n message: MessageType<StreamChatGenerics>;\n markdownRules?: MarkdownRules;\n markdownStyles?: MarkdownStyle;\n messageOverlay?: boolean;\n messageTextNumberOfLines?: number;\n onLink?: (url: string) => Promise<void>;\n onlyEmojis?: boolean;\n};\n\nexport const renderText = <\n StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,\n>(\n params: RenderTextParams<StreamChatGenerics>,\n) => {\n const {\n colors,\n markdownRules,\n markdownStyles,\n message,\n messageOverlay,\n messageTextNumberOfLines,\n onLink: onLinkParams,\n onLongPress: onLongPressParam,\n onlyEmojis,\n onPress: onPressParam,\n preventPress,\n } = params;\n\n // take the @ mentions and turn them into markdown?\n // translate links\n const { mentioned_users, text } = message;\n\n if (!text) return null;\n\n let newText = text.trim();\n const linkInfos = parseLinksFromText(newText);\n\n for (const linkInfo of linkInfos) {\n const displayLink = truncate(linkInfo.raw, {\n length: 200,\n omission: '...',\n });\n const markdown = `[${displayLink}](${linkInfo.encodedUrl})`;\n newText = newText.replace(linkInfo.raw, markdown);\n }\n\n newText = newText.replace(/[<&\"'>]/g, '\\\\$&');\n\n const styles: MarkdownStyle = {\n ...defaultMarkdownStyles,\n ...markdownStyles,\n autolink: {\n ...defaultMarkdownStyles.autolink,\n color: colors.accent_blue,\n ...markdownStyles?.autolink,\n },\n inlineCode: {\n ...defaultMarkdownStyles.inlineCode,\n backgroundColor: colors.white_smoke,\n borderColor: colors.grey_gainsboro,\n color: colors.accent_red,\n ...markdownStyles?.inlineCode,\n },\n mentions: {\n ...defaultMarkdownStyles.mentions,\n color: colors.accent_blue,\n ...markdownStyles?.mentions,\n },\n text: {\n ...defaultMarkdownStyles.text,\n color: colors.black,\n ...markdownStyles?.text,\n },\n };\n\n const onLink = (url: string) => {\n const pattern = new RegExp(/^\\S+:\\/\\//);\n if (!pattern.test(url)) {\n url = 'http://' + url;\n }\n\n return onLinkParams\n ? onLinkParams(url)\n : Linking.canOpenURL(url).then((canOpenUrl) => canOpenUrl && Linking.openURL(url));\n };\n\n const link: ReactNodeOutput = (node, output, { ...state }) => {\n const url = node.target;\n const onPress = (event: GestureResponderEvent) => {\n if (!preventPress && onPressParam) {\n onPressParam({\n additionalInfo: { url },\n defaultHandler: () => {\n onLink(url);\n },\n emitter: 'textLink',\n event,\n });\n }\n };\n\n const onLongPress = (event: GestureResponderEvent) => {\n if (!preventPress && onLongPressParam) {\n onLongPressParam({\n additionalInfo: { url },\n emitter: 'textLink',\n event,\n });\n }\n };\n\n return (\n <Text\n key={state.key}\n onLongPress={onLongPress}\n onPress={onPress}\n style={styles.autolink}\n suppressHighlighting={true}\n >\n {output(node.content, { ...state, withinLink: true })}\n </Text>\n );\n };\n\n const paragraphText: ReactNodeOutput = (node, output, { ...state }) => (\n <Text key={state.key} numberOfLines={messageTextNumberOfLines} style={styles.paragraph}>\n {output(node.content, state)}\n </Text>\n );\n\n const mentionedUsers = Array.isArray(mentioned_users)\n ? mentioned_users.reduce((acc, cur) => {\n const userName = cur.name || cur.id || '';\n if (userName) {\n acc += `${acc.length ? '|' : ''}@${userName}`;\n }\n return acc;\n }, '')\n : '';\n\n const regEx = new RegExp(`^\\\\B(${mentionedUsers})`, 'g');\n const match: MatchFunction = (source) => regEx.exec(source);\n\n const mentionsReact: ReactNodeOutput = (node, output, { ...state }) => {\n /**removes the @ prefix of username */\n const userName = node.content[0]?.content?.substring(1);\n const onPress = (event: GestureResponderEvent) => {\n if (!preventPress && onPressParam) {\n onPressParam({\n additionalInfo: {\n user: mentioned_users?.find(\n (user: UserResponse<StreamChatGenerics>) => userName === user.name,\n ),\n },\n emitter: 'textMention',\n event,\n });\n }\n };\n\n const onLongPress = (event: GestureResponderEvent) => {\n if (!preventPress && onLongPressParam) {\n onLongPressParam({\n emitter: 'textMention',\n event,\n });\n }\n };\n\n return (\n <Text key={state.key} onLongPress={onLongPress} onPress={onPress} style={styles.mentions}>\n {Array.isArray(node.content)\n ? node.content.reduce((acc, current) => acc + current.content, '') || ''\n : output(node.content, state)}\n </Text>\n );\n };\n\n const list: ReactNodeOutput = (node, output, state) => (\n <ListOutput\n key={`list-${state.key}`}\n node={node}\n output={output}\n state={state}\n styles={styles}\n />\n );\n\n const customRules = {\n // do not render images, we will scrape them out of the message and show on attachment card component\n image: { match: () => null },\n link: { react: link },\n list: { react: list },\n // Truncate long text content in the message overlay\n paragraph: messageTextNumberOfLines ? { react: paragraphText } : {},\n // we have no react rendering support for reflinks\n reflink: { match: () => null },\n sublist: { react: list },\n ...(mentionedUsers\n ? {\n mentions: {\n match,\n order: defaultRules.text.order - 0.5,\n parse,\n react: mentionsReact,\n },\n }\n : {}),\n };\n\n return (\n <Markdown\n key={`${JSON.stringify(mentioned_users)}-${onlyEmojis}-${\n messageOverlay ? JSON.stringify(markdownStyles) : undefined\n }-${JSON.stringify(colors)}`}\n onLink={onLink}\n rules={{\n ...customRules,\n ...markdownRules,\n }}\n styles={styles}\n >\n {newText}\n </Markdown>\n );\n};\n\nexport interface ListOutputProps {\n node: SingleASTNode;\n output: ReactOutput;\n state: State;\n styles?: Partial<MarkdownStyle>;\n}\n\n/**\n * For lists and sublists, the default behavior of the markdown library we use is\n * to always renumber any list, so all ordered lists start from 1.\n *\n * This custom rule overrides this behavior both for top level lists and sublists,\n * in order to start the numbering from the number of the first list item provided.\n */\nexport const ListOutput = ({ node, output, state, styles }: ListOutputProps) => {\n let isSublist = state.withinList;\n const parentTypes = ['text', 'paragraph', 'strong'];\n\n return (\n <View key={state.key} style={isSublist ? styles?.sublist : styles?.list}>\n {node.items.map((item: SingleASTNode, index: number) => {\n const indexAfterStart = node.start + index;\n\n if (item === null) {\n return (\n <ListRow key={index} style={styles?.listRow} testID='list-item'>\n <Bullet index={node.ordered && indexAfterStart} />\n </ListRow>\n );\n }\n\n isSublist = item.length > 1 && item[1].type === 'list';\n const isSublistWithinText = parentTypes.includes((item[0] ?? {}).type) && isSublist;\n const style = isSublistWithinText ? { marginBottom: 0 } : {};\n\n return (\n <ListRow key={index} style={styles?.listRow} testID='list-item'>\n <Bullet index={node.ordered && indexAfterStart} />\n <ListItem key={1} style={[styles?.listItemText, style]}>\n {output(item, state)}\n </ListItem>\n </ListRow>\n );\n })}\n </View>\n );\n};\n\ninterface BulletProps extends TextProps {\n index?: number;\n}\n\nconst Bullet = ({ index, style }: BulletProps) => (\n <Text key={0} style={[style, defaultMarkdownStyles.listItemNumber]}>\n {index ? `${index}. ` : '\\u2022 '}\n </Text>\n);\n\nconst ListRow = (props: PropsWithChildren<ViewProps>) => (\n <Text style={[props.style, defaultMarkdownStyles.listRow]}>{props.children}</Text>\n);\n\nconst ListItem = ({ children, style }: PropsWithChildren<TextProps>) => (\n <Text style={style}>{children}</Text>\n);\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "5.10.0-beta.1"
2
+ "version": "5.10.0"
3
3
  }
@@ -1,7 +1,6 @@
1
- interface Link {
2
- encoded: string;
1
+ interface LinkInfo {
2
+ encodedUrl: string;
3
3
  raw: string;
4
- scheme: string;
5
4
  }
6
- export declare const parseLinksFromText: (input: string) => Link[];
5
+ export declare const parseLinksFromText: (input: string) => LinkInfo[];
7
6
  export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "stream-chat-react-native-core",
3
3
  "description": "The official React Native and Expo components for Stream Chat, a service for building chat applications",
4
- "version": "5.10.0-beta.1",
4
+ "version": "5.10.0",
5
5
  "author": {
6
6
  "company": "Stream.io Inc",
7
7
  "name": "Stream.io Inc"
@@ -72,6 +72,7 @@
72
72
  "dayjs": "1.10.5",
73
73
  "file-loader": "6.2.0",
74
74
  "i18next": "20.2.4",
75
+ "linkify-it": "^4.0.1",
75
76
  "lodash-es": "4.17.21",
76
77
  "metro-react-native-babel-preset": "0.66.2",
77
78
  "mime-types": "^2.1.34",
@@ -106,6 +107,7 @@
106
107
  "@types/react": "17.0.5",
107
108
  "@types/react-native": "0.67.3",
108
109
  "@types/react-test-renderer": "17.0.1",
110
+ "@types/linkify-it": "3.0.2",
109
111
  "@types/uuid": "^8.3.4",
110
112
  "@typescript-eslint/eslint-plugin": "^5.7.0",
111
113
  "@typescript-eslint/parser": "^5.7.0",
@@ -2,55 +2,52 @@ import { parseLinksFromText } from './parseLinks';
2
2
 
3
3
  describe('parseLinksFromText', () => {
4
4
  it.each([
5
- ['www.getstream.io', 'www.getstream.io'],
6
- ['getstream.io', 'getstream.io'],
7
- ['scrn://team-chat', 'team-chat'],
8
- ['https://localhost', 'localhost'],
5
+ ['https://www.getstream.io', 'https://www.getstream.io'],
6
+ ['https://getstream.io', 'https://getstream.io'],
7
+ ['scrn://team-chat', undefined],
8
+ ['https://localhost', 'https://localhost'],
9
9
  [
10
10
  'https://localhost/with/path?and=query&multiple=params',
11
- 'localhost/with/path?and=query&multiple=params',
11
+ 'https://localhost/with/path?and=query&multiple=params',
12
+ ],
13
+ [
14
+ 'https://localhost/with/path?and=query#fragment',
15
+ 'https://localhost/with/path?and=query#fragment',
12
16
  ],
13
- ['https://localhost/with/path?and=query#fragment', 'localhost/with/path?and=query#fragment'],
14
- ['reactnative.stream', 'reactnative.stream'],
17
+ ['reactnative.stream', undefined],
15
18
  [
16
19
  'https://zh.wikipedia.org/wiki/挪威牛油危機',
17
- 'zh.wikipedia.org/wiki/%E6%8C%AA%E5%A8%81%E7%89%9B%E6%B2%B9%E5%8D%B1%E6%A9%9F',
20
+ 'https://zh.wikipedia.org/wiki/%E6%8C%AA%E5%A8%81%E7%89%9B%E6%B2%B9%E5%8D%B1%E6%A9%9F',
18
21
  ],
19
22
  [
20
23
  'https://getstream.io/chat/docs/react-native/?language=javascript',
21
- 'getstream.io/chat/docs/react-native/?language=javascript',
24
+ 'https://getstream.io/chat/docs/react-native/?language=javascript',
22
25
  ],
23
- ['127.0.0.1/local_(development)_server', '127.0.0.1/local_(development)_server'],
24
- ['https://a.co:8999/ab.php?p=12', 'a.co:8999/ab.php?p=12'],
26
+ ['127.0.0.1/local_(development)_server', undefined],
27
+ ['https://a.co:8999/ab.php?p=12', 'https://a.co:8999/ab.php?p=12'],
25
28
  [
26
- 'http://help.apple.com/xcode/mac/current/#/devba7f53ad4',
27
- 'help.apple.com/xcode/mac/current/#/devba7f53ad4',
29
+ 'https://help.apple.com/xcode/mac/current/#/devba7f53ad4',
30
+ 'https://help.apple.com/xcode/mac/current/#/devba7f53ad4',
28
31
  ],
29
32
  ])('Returns the encoded value of %p as %p', (link, expected) => {
30
33
  const result = parseLinksFromText(link);
31
-
32
- expect(result[0].encoded).toBe(expected);
34
+ expect(result[0]?.encodedUrl).toBe(expected);
33
35
  });
34
-
35
36
  it('parses fqdn', () => {
36
37
  const input = `We have put the apim bol,
37
- temporarily so :sj: we can later put the monitors on my grasp
38
- on reality right now is
39
- https://www.contrived-example.com:8080/sub/page.php?p1=1🇳🇴&p2=2#fragment-identifier
40
- :)`;
41
-
38
+ temporarily so :sj: we can later put the monitors on my grasp
39
+ on reality right now is
40
+ https://www.contrived-example.com:8080/sub/page.php?p1=1🇳🇴&p2=2#fragment-identifier
41
+ :)`;
42
42
  const result = parseLinksFromText(input);
43
-
44
43
  expect(result).toEqual([
45
44
  {
46
- encoded:
47
- 'www.contrived-example.com:8080/sub/page.php?p1=1%F0%9F%87%B3%F0%9F%87%B4&p2=2#fragment-identifier',
45
+ encodedUrl:
46
+ 'https://www.contrived-example.com:8080/sub/page.php?p1=1%F0%9F%87%B3%F0%9F%87%B4&p2=2#fragment-identifier',
48
47
  raw: 'https://www.contrived-example.com:8080/sub/page.php?p1=1🇳🇴&p2=2#fragment-identifier',
49
- scheme: 'https://',
50
48
  },
51
49
  ]);
52
50
  });
53
-
54
51
  it.each([
55
52
  ['support+rn@getstream.io'],
56
53
  ['support.rn@getstream.io'],
@@ -58,60 +55,61 @@ https://www.contrived-example.com:8080/sub/page.php?p1=1🇳🇴&p2=2#fragment-i
58
55
  ['support_rn@getstream.io'],
59
56
  ])('Can parse the email address %p', (email) => {
60
57
  const result = parseLinksFromText(email);
61
-
62
- expect(result[0].encoded).toBe(email);
63
- expect(result[0].scheme).toBe('mailto:');
58
+ expect(result[0].encodedUrl).toBe('mailto:' + email);
59
+ expect(result[0].raw).toBe(email);
64
60
  });
65
-
66
61
  it("doesn't double the mailto prefix", () => {
67
62
  const input = 'mailto:support@getstream.io';
68
-
69
63
  const result = parseLinksFromText(input);
70
-
71
64
  expect(result[0]).toEqual({
72
- encoded: 'support@getstream.io',
65
+ encodedUrl: input,
73
66
  raw: input,
74
- scheme: 'mailto:',
75
67
  });
76
68
  });
77
-
78
69
  it('Does not falsely parse LINKs from text content', () => {
79
70
  const input = `#This string exists to test that we don't produce false positives
80
-
81
- Existing links:
82
- [already a parsed link](https://getstream.io/blog/react-native-how-to-build-bidirectional-infinite-scroll/)
83
- [even a bogus one]( should not match )
84
-
85
- ## These should, however, be parsed:
86
- www.getstream.io
87
- getstream.io
88
- `;
71
+ Existing links:
72
+ [already a parsed link](https://getstream.io/blog/react-native-how-to-build-bidirectional-infinite-scroll/)
73
+ [even a bogus one]( should not match )
74
+ ## These should, however, be parsed:
75
+ www.getstream.io
76
+ getstream.io
77
+ `;
89
78
  const result = parseLinksFromText(input);
90
-
79
+ console.log({ result });
91
80
  expect(result).toHaveLength(2);
92
81
  });
93
-
94
82
  it('Encodes incomplete emoji unicode', () => {
95
83
  const input = 'https://getstream.io/�';
96
84
  const result = parseLinksFromText(input);
97
-
98
85
  expect(result[0]).toEqual({
99
- encoded: 'getstream.io/%EF%BF%BD',
100
- raw: 'https://getstream.io/�',
101
- scheme: 'https://',
86
+ encodedUrl: 'https://getstream.io/%EF%BF%BD',
87
+ raw: input,
102
88
  });
103
89
  });
104
-
90
+ it('doest not report invalid tlds as urls', () => {
91
+ const input = `
92
+ %
93
+ % Not links
94
+ %
95
+ example.invalid
96
+ example.invalid/
97
+ http://.example.com
98
+ http://-example.com
99
+ hppt://example.com
100
+ example.coma
101
+ -example.coma
102
+ `;
103
+ const result = parseLinksFromText(input);
104
+ expect(result).toHaveLength(0);
105
+ });
105
106
  it('does not parse a decimal number as a URL', () => {
106
107
  const input = '123.456';
107
108
  const result = parseLinksFromText(input);
108
-
109
109
  expect(result).toHaveLength(0);
110
110
  });
111
-
112
111
  it.each([['@user'], ['@user.name']])('does not parse %p as a URL', (input) => {
113
112
  const result = parseLinksFromText(input);
114
-
115
113
  expect(result).toHaveLength(0);
116
114
  });
117
115
  });
@@ -1,40 +1,8 @@
1
- /**
2
- * 📣 Note: Do not use named capture groups, as
3
- * it is not yet available in Hermes.
4
- *
5
- * These helpers indend to make it easier to skim read
6
- * the patterns below, but note that some are optional,
7
- * specified in the patterns these are added to.
8
- * */
9
- const emailUserName = '[\\w+\\.~$_-]+';
10
- const schema = `(\\w{2,15}:\\/\\/)`;
11
- // something.tld OR 123.123.123.123
12
- const domain = `((?:\\w+\\.[a-zA-Z]+)+(?:[^:\\/\\s]+)|(?:\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}))`;
13
- const port = `(:[0-9]{1,5})`;
14
- const path = `((?:\\/)?[^?\\s]+)`;
15
- const queryString = `(\\?[^#\\s]+)`;
16
- const fragment = `(#[\\w_-]+)`;
17
-
18
- /**
19
- * Match any email address, with and without `mailto:`
20
- */
21
- const emailPattern = `(mailto:)?((?:${emailUserName})@(?:${domain}))`;
22
-
23
- /**
24
- * Match any string starting with something that seems like it's a schema.
25
- * */
26
- const schemePrefixedLinkPattern = `${schema}(\\S+)`;
1
+ import Linkify from 'linkify-it';
27
2
 
28
- /**
29
- * Match as much as possible of a fqdn, at least with a domain name formed as
30
- * something.tld
31
- */
32
- const fqdnLinkPattern = `${schema}?${domain}${port}?${path}?${queryString}?${fragment}?`;
33
-
34
- interface Link {
35
- encoded: string;
3
+ interface LinkInfo {
4
+ encodedUrl: string;
36
5
  raw: string;
37
- scheme: string;
38
6
  }
39
7
 
40
8
  /**
@@ -49,57 +17,19 @@ const removeMarkdownLinksFromText = (input: string) => input.replace(/\[[\w\s]+\
49
17
  * */
50
18
  const removeUserNamesFromText = (input: string) => input.replace(/^@\w+\.?\w/, '');
51
19
 
52
- export const parseLinksFromText = (input: string): Link[] => {
53
- let matches;
54
-
20
+ export const parseLinksFromText = (input: string): LinkInfo[] => {
55
21
  const strippedInput = [removeMarkdownLinksFromText, removeUserNamesFromText].reduce(
56
22
  (acc, fn) => fn(acc),
57
23
  input,
58
24
  );
59
25
 
60
- const results: Link[] = [];
61
-
62
- const emailRegExp = new RegExp(emailPattern, 'gi');
63
- while ((matches = emailRegExp.exec(input)) !== null) {
64
- const [raw, scheme = 'mailto:', displayValue] = matches;
65
- results.push({ encoded: encodeURI(displayValue), raw, scheme });
66
- }
67
-
68
- /**
69
- * The two link patterns are checked with an "or" (`|`)
70
- * to avoid overlapping matches being duplicated in the output.
71
- * */
72
- const linkRegex = new RegExp(`${fqdnLinkPattern}|${schemePrefixedLinkPattern}`, 'gi');
73
- while ((matches = linkRegex.exec(strippedInput)) !== null) {
74
- const [
75
- raw,
76
- fqdnScheme = '',
77
- fqdnDomainName = '',
78
- fqdnPort = '',
79
- fqdnPath = '',
80
- fqdnQueryStraing = '',
81
- fqdnFragment = '',
82
- schemePrefixedScheme = '',
83
- schemePrefixedPath = '',
84
- ] = matches;
85
-
86
- if (schemePrefixedScheme !== '') {
87
- results.push({
88
- encoded: encodeURI(schemePrefixedPath),
89
- raw,
90
- scheme: schemePrefixedScheme,
91
- });
92
- continue;
93
- }
26
+ const linkify = Linkify();
27
+ const matches = linkify.match(strippedInput) ?? [];
94
28
 
95
- results.push({
96
- encoded: encodeURI(
97
- [fqdnDomainName, fqdnPort, fqdnPath, fqdnQueryStraing, fqdnFragment].join(''),
98
- ),
99
- raw,
100
- scheme: fqdnScheme,
101
- });
102
- }
29
+ const result: LinkInfo[] = matches.map((match) => {
30
+ const { raw, url } = match;
31
+ return { encodedUrl: encodeURI(url), raw };
32
+ });
103
33
 
104
- return results;
34
+ return result;
105
35
  };
@@ -109,15 +109,15 @@ export const renderText = <
109
109
  if (!text) return null;
110
110
 
111
111
  let newText = text.trim();
112
- const urls = parseLinksFromText(newText);
112
+ const linkInfos = parseLinksFromText(newText);
113
113
 
114
- for (const urlInfo of urls) {
115
- const displayLink = truncate(urlInfo.encoded, {
114
+ for (const linkInfo of linkInfos) {
115
+ const displayLink = truncate(linkInfo.raw, {
116
116
  length: 200,
117
117
  omission: '...',
118
118
  });
119
- const markdown = `[${displayLink}](${urlInfo.scheme}${urlInfo.encoded})`;
120
- newText = newText.replace(urlInfo.raw, markdown);
119
+ const markdown = `[${displayLink}](${linkInfo.encodedUrl})`;
120
+ newText = newText.replace(linkInfo.raw, markdown);
121
121
  }
122
122
 
123
123
  newText = newText.replace(/[<&"'>]/g, '\\$&');
package/src/version.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "5.10.0-beta.1"
2
+ "version": "5.10.0"
3
3
  }