stream-markdown-parser 0.0.59-beta.9 → 0.0.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -227,7 +227,7 @@ Processes raw markdown-it tokens into a flat array.
227
227
 
228
228
  #### `parseInlineTokens(tokens, content?, preToken?, options?)`
229
229
 
230
- Parses inline markdown-it-ts tokens into renderer nodes. Pass the inline token array plus the optional raw `content` string (from the parent token), an optional previous token, and inline parse options (`requireClosingStrong`, `customHtmlTags`).
230
+ Parses inline markdown-it-ts tokens into renderer nodes. Pass the inline token array plus the optional raw `content` string (from the parent token), an optional previous token, and inline parse options (`requireClosingStrong`, `customHtmlTags`, `validateLink`).
231
231
 
232
232
  ### Configuration Functions
233
233
 
@@ -255,6 +255,8 @@ interface ParseOptions {
255
255
  postTransformTokens?: (tokens: Token[]) => Token[]
256
256
  // Custom HTML-like tags to emit as custom nodes (e.g. ['thinking'])
257
257
  customHtmlTags?: string[]
258
+ // Validate link href before emitting a `link` node; false -> plain text
259
+ validateLink?: (url: string) => boolean
258
260
  // When true, treats the input as complete (end-of-stream)
259
261
  final?: boolean
260
262
  // Require closing `**` for strong parsing (default: false)
@@ -279,6 +281,22 @@ const tagged = nodes.map(node =>
279
281
 
280
282
  Use the metadata in your renderer to show custom UI without mangling the original Markdown.
281
283
 
284
+ Example — enforce safe link protocols:
285
+
286
+ ```ts
287
+ const md = getMarkdown('safe-links')
288
+ md.set?.({
289
+ validateLink: (url: string) => !/^\s*javascript:/i.test(url.trim()),
290
+ })
291
+
292
+ const nodes = parseMarkdownToStructure(
293
+ '[ok](https://example.com) [bad](javascript:alert(1))',
294
+ md,
295
+ { final: true },
296
+ )
297
+ // "ok" stays a link node; "bad" is downgraded to plain text
298
+ ```
299
+
282
300
  ### Unknown HTML-like tags
283
301
 
284
302
  By default, non-standard HTML-like tags (for example `<question>`) are rendered as raw HTML elements once they are complete; during streaming, partial tags are kept as **literal text** to avoid flicker. If you want them emitted as custom nodes (`type: 'question'` with parsed attrs/content), opt in via `customHtmlTags`.
package/README.zh-CN.md CHANGED
@@ -226,7 +226,7 @@ interface GetMarkdownOptions {
226
226
 
227
227
  #### `parseInlineTokens(tokens, content?, preToken?, options?)`
228
228
 
229
- 解析内联 markdown-it-ts tokens 并产出节点。可传入原始 `content`(来自父 token)、可选的前一个 token,以及 inline 解析选项(`requireClosingStrong`、`customHtmlTags`)。
229
+ 解析内联 markdown-it-ts tokens 并产出节点。可传入原始 `content`(来自父 token)、可选的前一个 token,以及 inline 解析选项(`requireClosingStrong`、`customHtmlTags`、`validateLink`)。
230
230
 
231
231
  ### 配置函数
232
232
 
@@ -254,6 +254,8 @@ interface ParseOptions {
254
254
  postTransformTokens?: (tokens: Token[]) => Token[]
255
255
  // 自定义 HTML 类标签,作为自定义节点输出(如 ['thinking'])
256
256
  customHtmlTags?: string[]
257
+ // 输出 link 节点前校验 href;返回 false 时降级为纯文本
258
+ validateLink?: (url: string) => boolean
257
259
  // true 表示输入已结束(end-of-stream)
258
260
  final?: boolean
259
261
  // 解析 strong 时要求闭合 `**`(默认 false)
@@ -278,6 +280,22 @@ const tagged = nodes.map(node =>
278
280
 
279
281
  在渲染器中读取 `node.meta` 即可渲染自定义 UI,而无需直接修改 Markdown 文本。
280
282
 
283
+ 示例 —— 限制链接协议,拦截不安全链接:
284
+
285
+ ```ts
286
+ const md = getMarkdown('safe-links')
287
+ md.set?.({
288
+ validateLink: (url: string) => !/^\s*javascript:/i.test(url.trim()),
289
+ })
290
+
291
+ const nodes = parseMarkdownToStructure(
292
+ '[ok](https://example.com) [bad](javascript:alert(1))',
293
+ md,
294
+ { final: true },
295
+ )
296
+ // "ok" 保持为 link 节点;"bad" 会降级为纯文本
297
+ ```
298
+
281
299
  ### 未知 HTML 类标签
282
300
 
283
301
  默认情况下,非标准的 HTML 类标签(例如 `<question>`)在完整闭合时会按原生 HTML 渲染(作为自定义元素输出);流式场景下未闭合的片段会先按**纯文本**处理以避免闪烁。若希望它们作为自定义节点输出(`type: 'question'`,携带 attrs/content),需要在 `customHtmlTags` 中显式声明。
package/dist/index.d.ts CHANGED
@@ -336,6 +336,14 @@ interface ParseOptions {
336
336
  * to enable mid-state suppression for the same tags during streaming.
337
337
  */
338
338
  customHtmlTags?: string[];
339
+ /**
340
+ * If provided, link nodes are only emitted when this returns true for the href.
341
+ * When it returns false, the link is rendered as plain text (the link text only).
342
+ * Typically set from the MarkdownIt instance (e.g. md.options.validateLink or
343
+ * md.set({ validateLink })) so that unsafe URLs (e.g. javascript:) are not
344
+ * output as links.
345
+ */
346
+ validateLink?: (url: string) => boolean;
339
347
  debug?: boolean;
340
348
  }
341
349
  type PostTransformNodesHook = (nodes: ParsedNode[]) => ParsedNode[];
@@ -344,6 +352,7 @@ type PostTransformNodesHook = (nodes: ParsedNode[]) => ParsedNode[];
344
352
  declare function parseInlineTokens(tokens: MarkdownToken[], raw?: string, pPreToken?: MarkdownToken, options?: {
345
353
  requireClosingStrong?: boolean;
346
354
  customHtmlTags?: readonly string[];
355
+ validateLink?: (url: string) => boolean;
347
356
  }): ParsedNode[];
348
357
  //#endregion
349
358
  //#region src/parser/index.d.ts
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/factory.ts","../src/types.ts","../src/parser/inline-parsers/index.ts","../src/parser/index.ts","../src/config.ts","../src/findMatchingClose.ts","../src/parser/inline-parsers/fence-parser.ts","../src/plugins/containers.ts","../src/plugins/isMathLike.ts","../src/plugins/math.ts","../src/index.ts"],"sourcesContent":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/factory.ts","../src/types.ts","../src/parser/inline-parsers/index.ts","../src/parser/index.ts","../src/config.ts","../src/findMatchingClose.ts","../src/parser/inline-parsers/fence-parser.ts","../src/plugins/containers.ts","../src/plugins/isMathLike.ts","../src/plugins/math.ts","../src/index.ts"],"sourcesContent":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -9504,7 +9504,8 @@ function parseEmphasisToken(tokens, startIndex, options) {
9504
9504
  }
9505
9505
  children.push(...parseInlineTokens(innerTokens, void 0, void 0, {
9506
9506
  requireClosingStrong: options?.requireClosingStrong,
9507
- customHtmlTags: options?.customHtmlTags
9507
+ customHtmlTags: options?.customHtmlTags,
9508
+ validateLink: options?.validateLink
9508
9509
  }));
9509
9510
  return {
9510
9511
  node: {
@@ -10026,7 +10027,8 @@ function parseStrongToken(tokens, startIndex, raw, options) {
10026
10027
  }
10027
10028
  children.push(...parseInlineTokens(innerTokens, raw, void 0, {
10028
10029
  requireClosingStrong: options?.requireClosingStrong,
10029
- customHtmlTags: options?.customHtmlTags
10030
+ customHtmlTags: options?.customHtmlTags,
10031
+ validateLink: options?.validateLink
10030
10032
  }));
10031
10033
  return {
10032
10034
  node: {
@@ -10129,6 +10131,28 @@ function countUnescapedAsterisks(str) {
10129
10131
  }
10130
10132
  return count;
10131
10133
  }
10134
+ const WORD_CHAR_RE = /[\p{L}\p{N}]/u;
10135
+ const WORD_ONLY_RE = /^[\p{L}\p{N}]+$/u;
10136
+ function isWordChar(ch) {
10137
+ if (!ch) return false;
10138
+ return WORD_CHAR_RE.test(ch);
10139
+ }
10140
+ function isWordOnly(text$1) {
10141
+ if (!text$1) return false;
10142
+ return WORD_ONLY_RE.test(text$1);
10143
+ }
10144
+ function getAsteriskRunInfo(content, start) {
10145
+ let end = start;
10146
+ while (end < content.length && content[end] === "*") end++;
10147
+ const prev = start > 0 ? content[start - 1] : void 0;
10148
+ const next = end < content.length ? content[end] : void 0;
10149
+ return {
10150
+ len: end - start,
10151
+ prev,
10152
+ next,
10153
+ intraword: isWordChar(prev) && isWordChar(next)
10154
+ };
10155
+ }
10132
10156
  function parseInlineTokens(tokens, raw, pPreToken, options) {
10133
10157
  if (!tokens || tokens.length === 0) return [];
10134
10158
  const result = [];
@@ -10220,15 +10244,32 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
10220
10244
  return true;
10221
10245
  }
10222
10246
  }
10247
+ const runInfo = getAsteriskRunInfo(content, openIdx);
10223
10248
  const exec = STRONG_PAIR_RE.exec(content);
10224
10249
  let inner = "";
10225
10250
  let after = "";
10226
10251
  if (exec && typeof exec.index === "number") {
10227
10252
  inner = exec[1];
10228
10253
  after = content.slice(exec.index + exec[0].length);
10254
+ const closeRunInfo = getAsteriskRunInfo(content, exec.index + exec[0].length - 2);
10255
+ if (runInfo.intraword && closeRunInfo.intraword && !isWordOnly(inner)) {
10256
+ pushText(content.slice(beforeText.length), content.slice(beforeText.length));
10257
+ i++;
10258
+ return true;
10259
+ }
10260
+ if (!inner && runInfo.len >= 4 && runInfo.intraword) {
10261
+ pushText(content.slice(beforeText.length), content.slice(beforeText.length));
10262
+ i++;
10263
+ return true;
10264
+ }
10229
10265
  } else {
10230
10266
  if (requireClosingStrong) {
10231
- pushText(content, content);
10267
+ pushText(content.slice(beforeText.length), content.slice(beforeText.length));
10268
+ i++;
10269
+ return true;
10270
+ }
10271
+ if (runInfo.intraword) {
10272
+ pushText(content.slice(beforeText.length), content.slice(beforeText.length));
10232
10273
  i++;
10233
10274
  return true;
10234
10275
  }
@@ -10294,7 +10335,13 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
10294
10335
  };
10295
10336
  result.push(currentTextNode);
10296
10337
  }
10338
+ const runInfo = getAsteriskRunInfo(content, idx);
10297
10339
  const closeIndex = content.indexOf("*", idx + 1);
10340
+ if (closeIndex === -1 && runInfo.intraword) {
10341
+ pushText(content.slice(idx), content.slice(idx));
10342
+ i++;
10343
+ return true;
10344
+ }
10298
10345
  const { node } = parseEmphasisToken([
10299
10346
  {
10300
10347
  type: "em_open",
@@ -10590,7 +10637,11 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
10590
10637
  i++;
10591
10638
  break;
10592
10639
  default:
10593
- pushToken(token);
10640
+ if (token.type === "link" && token.href != null && options?.validateLink && !options.validateLink(token.href)) {
10641
+ resetCurrentTextNode();
10642
+ const displayText = String(token.text ?? "");
10643
+ pushText(displayText, displayText);
10644
+ } else pushToken(token);
10594
10645
  i++;
10595
10646
  break;
10596
10647
  }
@@ -10670,6 +10721,10 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
10670
10721
  resetCurrentTextNode();
10671
10722
  const { node, nextIndex } = parseLinkToken(tokens, i, { requireClosingStrong });
10672
10723
  i = nextIndex;
10724
+ if (options?.validateLink && !options.validateLink(node.href)) {
10725
+ pushText(node.text, node.text);
10726
+ return;
10727
+ }
10673
10728
  const hrefAttr = token.attrs?.find(([name]) => name === "href")?.[1];
10674
10729
  const hrefStr = String(hrefAttr ?? "");
10675
10730
  if (raw && hrefStr) {
@@ -10723,9 +10778,11 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
10723
10778
  loading$1 = false;
10724
10779
  } else if (last?.type === "text" && last.content === ".") i++;
10725
10780
  if (textNodeContent) pushText(textNodeContent, textNodeContent);
10726
- pushParsed({
10781
+ const hrefFromToken = String(textToken$1.content ?? "");
10782
+ if (options?.validateLink && !options.validateLink(hrefFromToken)) pushText(text$1, text$1);
10783
+ else pushParsed({
10727
10784
  type: "link",
10728
- href: String(textToken$1.content ?? ""),
10785
+ href: hrefFromToken,
10729
10786
  title: null,
10730
10787
  text: text$1,
10731
10788
  children: [{
@@ -10816,7 +10873,8 @@ function parseInlineTokens(tokens, raw, pPreToken, options) {
10816
10873
  const { node } = parseEmphasisToken(newTokens, 0, options);
10817
10874
  pushNode(node);
10818
10875
  }
10819
- } else pushParsed({
10876
+ } else if (options?.validateLink && !options.validateLink(href)) pushText(text$1, text$1);
10877
+ else pushParsed({
10820
10878
  type: "link",
10821
10879
  href,
10822
10880
  title: null,
@@ -10959,7 +11017,8 @@ function parseList(tokens, index, options) {
10959
11017
  type: "paragraph",
10960
11018
  children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), preToken, {
10961
11019
  requireClosingStrong: options?.requireClosingStrong,
10962
- customHtmlTags: options?.customHtmlTags
11020
+ customHtmlTags: options?.customHtmlTags,
11021
+ validateLink: options?.validateLink
10963
11022
  }),
10964
11023
  raw: String(contentToken.content ?? "")
10965
11024
  });
@@ -11016,7 +11075,8 @@ function parseAdmonition(tokens, index, match, options) {
11016
11075
  type: "paragraph",
11017
11076
  children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, {
11018
11077
  requireClosingStrong: options?.requireClosingStrong,
11019
- customHtmlTags: options?.customHtmlTags
11078
+ customHtmlTags: options?.customHtmlTags,
11079
+ validateLink: options?.validateLink
11020
11080
  }),
11021
11081
  raw: String(contentToken.content ?? "")
11022
11082
  });
@@ -11088,7 +11148,8 @@ function parseContainer(tokens, index, options) {
11088
11148
  type: "paragraph",
11089
11149
  children: parseInlineTokens(_children || [], void 0, void 0, {
11090
11150
  requireClosingStrong: options?.requireClosingStrong,
11091
- customHtmlTags: options?.customHtmlTags
11151
+ customHtmlTags: options?.customHtmlTags,
11152
+ validateLink: options?.validateLink
11092
11153
  }),
11093
11154
  raw: String(contentToken.content ?? "").replace(/\n:+$/, "").replace(/\n\s*:::\s*$/, "")
11094
11155
  });
@@ -11145,7 +11206,8 @@ function parseBlockquote(tokens, index, options) {
11145
11206
  type: "paragraph",
11146
11207
  children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, {
11147
11208
  requireClosingStrong: options?.requireClosingStrong,
11148
- customHtmlTags: options?.customHtmlTags
11209
+ customHtmlTags: options?.customHtmlTags,
11210
+ validateLink: options?.validateLink
11149
11211
  }),
11150
11212
  raw: String(contentToken.content ?? "")
11151
11213
  });
@@ -11209,7 +11271,8 @@ function parseDefinitionList(tokens, index, options) {
11209
11271
  const termToken = tokens[j + 1];
11210
11272
  termNodes = parseInlineTokens(termToken.children || [], void 0, void 0, {
11211
11273
  requireClosingStrong: options?.requireClosingStrong,
11212
- customHtmlTags: options?.customHtmlTags
11274
+ customHtmlTags: options?.customHtmlTags,
11275
+ validateLink: options?.validateLink
11213
11276
  });
11214
11277
  j += 3;
11215
11278
  } else if (tokens[j].type === "dd_open") {
@@ -11221,7 +11284,8 @@ function parseDefinitionList(tokens, index, options) {
11221
11284
  type: "paragraph",
11222
11285
  children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, {
11223
11286
  requireClosingStrong: options?.requireClosingStrong,
11224
- customHtmlTags: options?.customHtmlTags
11287
+ customHtmlTags: options?.customHtmlTags,
11288
+ validateLink: options?.validateLink
11225
11289
  }),
11226
11290
  raw: String(contentToken.content ?? "")
11227
11291
  });
@@ -11260,7 +11324,8 @@ function parseFootnote(tokens, index, options) {
11260
11324
  type: "paragraph",
11261
11325
  children: parseInlineTokens(contentToken.children || [], String(contentToken.content ?? ""), void 0, {
11262
11326
  requireClosingStrong: options?.requireClosingStrong,
11263
- customHtmlTags: options?.customHtmlTags
11327
+ customHtmlTags: options?.customHtmlTags,
11328
+ validateLink: options?.validateLink
11264
11329
  }),
11265
11330
  raw: String(contentToken.content ?? "")
11266
11331
  });
@@ -11291,7 +11356,8 @@ function parseHeading(tokens, index, options) {
11291
11356
  ...attrsRecord ? { attrs: attrsRecord } : {},
11292
11357
  children: parseInlineTokens(headingContentToken.children || [], headingContent, void 0, {
11293
11358
  requireClosingStrong: options?.requireClosingStrong,
11294
- customHtmlTags: options?.customHtmlTags
11359
+ customHtmlTags: options?.customHtmlTags,
11360
+ validateLink: options?.validateLink
11295
11361
  }),
11296
11362
  raw: headingContent
11297
11363
  };
@@ -11406,7 +11472,8 @@ function parseTable(tokens, index, options) {
11406
11472
  header: isHeaderCell || isHeader,
11407
11473
  children: parseInlineTokens(contentToken.children || [], content, void 0, {
11408
11474
  requireClosingStrong: options?.requireClosingStrong,
11409
- customHtmlTags: options?.customHtmlTags
11475
+ customHtmlTags: options?.customHtmlTags,
11476
+ validateLink: options?.validateLink
11410
11477
  }),
11411
11478
  raw: content,
11412
11479
  align
@@ -11506,7 +11573,8 @@ function parseVmrContainer(tokens, index, options) {
11506
11573
  type: "paragraph",
11507
11574
  children: parseInlineTokens(childrenArr || [], void 0, void 0, {
11508
11575
  requireClosingStrong: options?.requireClosingStrong,
11509
- customHtmlTags: options?.customHtmlTags
11576
+ customHtmlTags: options?.customHtmlTags,
11577
+ validateLink: options?.validateLink
11510
11578
  }),
11511
11579
  raw: String(contentToken.content ?? "")
11512
11580
  });
@@ -11769,7 +11837,8 @@ function parseParagraph(tokens, index, options) {
11769
11837
  type: "paragraph",
11770
11838
  children: parseInlineTokens(paragraphContentToken.children || [], paragraphContent, void 0, {
11771
11839
  requireClosingStrong: options?.requireClosingStrong,
11772
- customHtmlTags: options?.customHtmlTags
11840
+ customHtmlTags: options?.customHtmlTags,
11841
+ validateLink: options?.validateLink
11773
11842
  }),
11774
11843
  raw: paragraphContent
11775
11844
  };
@@ -12431,8 +12500,11 @@ function parseMarkdownToStructure(markdown, md, options = {}) {
12431
12500
  const post = options.postTransformTokens;
12432
12501
  let transformedTokens = tokens;
12433
12502
  if (pre && typeof pre === "function") transformedTokens = pre(transformedTokens) || transformedTokens;
12503
+ const mdAny = md;
12504
+ const validateLink$1 = options.validateLink ?? mdAny.options?.validateLink ?? (typeof mdAny.validateLink === "function" ? mdAny.validateLink : void 0);
12434
12505
  const internalOptions = {
12435
12506
  ...options,
12507
+ validateLink: validateLink$1,
12436
12508
  __sourceMarkdown: safeMarkdown,
12437
12509
  __customHtmlBlockCursor: 0
12438
12510
  };
@@ -12512,7 +12584,8 @@ function processTokens(tokens, options) {
12512
12584
  {
12513
12585
  const parsed = parseInlineTokens(token.children || [], String(token.content ?? ""), void 0, {
12514
12586
  requireClosingStrong: options?.requireClosingStrong,
12515
- customHtmlTags: options?.customHtmlTags
12587
+ customHtmlTags: options?.customHtmlTags,
12588
+ validateLink: options?.validateLink
12516
12589
  });
12517
12590
  if (parsed.length === 0) {} else if (parsed.every((n) => n.type === "html_block")) result.push(...parsed);
12518
12591
  else result.push({