@readme/markdown 11.13.0 → 11.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ declare const utils: {
|
|
|
6
6
|
getHref: typeof getHref;
|
|
7
7
|
calloutIcons: {};
|
|
8
8
|
};
|
|
9
|
-
export { compile, exports, hast, run, mdast, mdastV6, mdx, mdxish, mdxishAstProcessor, mdxishMdastToMd, mdxishTags, migrate, mix, plain, renderMdxish, remarkPlugins, stripComments, tags, } from './lib';
|
|
9
|
+
export { compile, exports, hast, run, mdast, mdastV6, mdx, mdxish, mdxishAstProcessor, mdxishMdastToMd, mdxishTags, migrate, mix, plain, renderMdxish, remarkPlugins, stripComments, tags, isPlainText, } from './lib';
|
|
10
10
|
export { default as Owlmoji } from './lib/owlmoji';
|
|
11
11
|
export { Components, utils };
|
|
12
12
|
export { tailwindCompiler } from './utils/tailwind-compiler';
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -3,6 +3,14 @@ export interface BlockHit {
|
|
|
3
3
|
raw: string;
|
|
4
4
|
token: string;
|
|
5
5
|
}
|
|
6
|
+
/**
|
|
7
|
+
* The content matching in this regex captures everything between `[block:TYPE]`
|
|
8
|
+
* and `[/block]`, including new lines. Negative lookahead for the closing
|
|
9
|
+
* `[/block]` tag is required to prevent greedy matching to ensure it stops at
|
|
10
|
+
* the first closing tag it encounters preventing vulnerability to polynomial
|
|
11
|
+
* backtracking issues.
|
|
12
|
+
*/
|
|
13
|
+
export declare const MAGIC_BLOCK_REGEX: RegExp;
|
|
6
14
|
/**
|
|
7
15
|
* Extract legacy magic block syntax from a markdown string.
|
|
8
16
|
* Returns the modified markdown and an array of extracted blocks.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detects if content contains HTML, magic blocks, or MDX syntax.
|
|
3
|
+
*
|
|
4
|
+
* We can use this in some pipelines to determine if we should have to parse content through
|
|
5
|
+
* `.plain() or if it is already plain text and it should be able to detect everything that would
|
|
6
|
+
* be stripped or sanitized by `.plain()`.
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
export default function isPlainText(content: string): boolean;
|
package/dist/main.js
CHANGED
|
@@ -11362,6 +11362,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
11362
11362
|
exports: () => (/* reexport */ lib_exports),
|
|
11363
11363
|
gemojiRegex: () => (/* reexport */ gemoji_regex),
|
|
11364
11364
|
hast: () => (/* reexport */ lib_hast),
|
|
11365
|
+
isPlainText: () => (/* reexport */ isPlainText),
|
|
11365
11366
|
mdast: () => (/* reexport */ lib_mdast),
|
|
11366
11367
|
mdastV6: () => (/* reexport */ lib_mdastV6),
|
|
11367
11368
|
mdx: () => (/* reexport */ lib_mdx),
|
|
@@ -95294,6 +95295,89 @@ async function stripComments(doc, { mdx } = {}) {
|
|
|
95294
95295
|
}
|
|
95295
95296
|
/* harmony default export */ const lib_stripComments = (stripComments);
|
|
95296
95297
|
|
|
95298
|
+
;// ./lib/utils/isPlainText.ts
|
|
95299
|
+
|
|
95300
|
+
/**
|
|
95301
|
+
* Detects if content contains HTML, magic blocks, or MDX syntax.
|
|
95302
|
+
*
|
|
95303
|
+
* We can use this in some pipelines to determine if we should have to parse content through
|
|
95304
|
+
* `.plain() or if it is already plain text and it should be able to detect everything that would
|
|
95305
|
+
* be stripped or sanitized by `.plain()`.
|
|
95306
|
+
*
|
|
95307
|
+
*/
|
|
95308
|
+
function isPlainText(content) {
|
|
95309
|
+
if (!content || typeof content !== 'string') {
|
|
95310
|
+
return true;
|
|
95311
|
+
}
|
|
95312
|
+
// Exclude markdown code blocks and inline code to avoid false positives
|
|
95313
|
+
// Match code blocks with optional language identifier: ```lang\n...\n```
|
|
95314
|
+
const codeBlockRegex = /```[^\n]*\n[\s\S]*?```/g;
|
|
95315
|
+
// Match inline code: `code` (but not escaped backticks)
|
|
95316
|
+
const inlineCodeRegex = /`[^`\n]+`/g;
|
|
95317
|
+
// Remove code blocks and inline code to avoid false positives
|
|
95318
|
+
let contentWithoutCode = structuredClone(content);
|
|
95319
|
+
contentWithoutCode = contentWithoutCode.replace(codeBlockRegex, '');
|
|
95320
|
+
contentWithoutCode = contentWithoutCode.replace(inlineCodeRegex, '');
|
|
95321
|
+
// Check for magic blocks: `[block:TYPE]...[/block]`
|
|
95322
|
+
// Only check after removing code blocks to avoid detecting magic blocks in code
|
|
95323
|
+
if (contentWithoutCode.match(MAGIC_BLOCK_REGEX) !== null) {
|
|
95324
|
+
return false;
|
|
95325
|
+
}
|
|
95326
|
+
// Check for markdown links: [text](url) or [text][reference]
|
|
95327
|
+
// Pattern matches inline links and reference-style links
|
|
95328
|
+
// Exclude images which start with ! before the bracket
|
|
95329
|
+
// Only check after removing code blocks
|
|
95330
|
+
const markdownLinkPattern = /(?<!!)\[([^\]]+)\]\(([^)]+)\)|(?<!!)\[([^\]]+)\]\[([^\]]*)\]/;
|
|
95331
|
+
if (markdownLinkPattern.test(contentWithoutCode)) {
|
|
95332
|
+
return false;
|
|
95333
|
+
}
|
|
95334
|
+
// Check for JSX elements (PascalCase components) in the original content
|
|
95335
|
+
// This includes code blocks since JSX code examples should be detected
|
|
95336
|
+
// Pattern matches:
|
|
95337
|
+
// - Self-closing: <Component /> or <Component/>
|
|
95338
|
+
// - With attributes: <Component prop="value" />
|
|
95339
|
+
// - With children: <Component>...</Component>
|
|
95340
|
+
// Use simpler, safer patterns to avoid ReDoS from backtracking
|
|
95341
|
+
// Match self-closing tags with bounded attribute length to prevent excessive backtracking
|
|
95342
|
+
const jsxSelfClosingPattern = /<[A-Z][a-zA-Z0-9]*(?:\s[^>]{0,50})?\/>/;
|
|
95343
|
+
if (jsxSelfClosingPattern.test(content)) {
|
|
95344
|
+
return false;
|
|
95345
|
+
}
|
|
95346
|
+
// For components with children, use a safer pattern that limits backtracking
|
|
95347
|
+
// Match opening tag with bounded attributes, then look for closing tag with same name
|
|
95348
|
+
const jsxWithChildrenPattern = /<([A-Z][a-zA-Z0-9]*)(?:\s[^>]{0,50})?>[\s\S]{0,50}<\/\1>/;
|
|
95349
|
+
if (jsxWithChildrenPattern.test(content)) {
|
|
95350
|
+
return false;
|
|
95351
|
+
}
|
|
95352
|
+
// Check for MDX expressions and HTML tags in the original content
|
|
95353
|
+
// HTML/JSX/MDX in code blocks should be detected (as per test requirements)
|
|
95354
|
+
// But exclude inline code that contains magic block patterns to avoid false positives
|
|
95355
|
+
let contentForHtmlMdx = content;
|
|
95356
|
+
// Find inline code blocks and check if they contain [block: pattern
|
|
95357
|
+
// Exclude these from HTML/MDX detection to avoid false positives
|
|
95358
|
+
const inlineCodePattern = /`[^`\n]+`/g;
|
|
95359
|
+
let inlineCodeMatch;
|
|
95360
|
+
inlineCodePattern.lastIndex = 0;
|
|
95361
|
+
while ((inlineCodeMatch = inlineCodePattern.exec(content)) !== null) {
|
|
95362
|
+
if (inlineCodeMatch[0].includes('[block:')) {
|
|
95363
|
+
contentForHtmlMdx = contentForHtmlMdx.replace(inlineCodeMatch[0], '');
|
|
95364
|
+
}
|
|
95365
|
+
}
|
|
95366
|
+
// Match simple MDX variable expressions like {variable}, {user.name}, {getValue()}, {}
|
|
95367
|
+
// Use bounded quantifier to prevent ReDoS - limit to reasonable variable name length
|
|
95368
|
+
// Allow empty braces {} to be detected as well
|
|
95369
|
+
const jsxExpressionPattern = /\{[^}"]{0,50}\}/;
|
|
95370
|
+
if (jsxExpressionPattern.test(contentForHtmlMdx)) {
|
|
95371
|
+
return false;
|
|
95372
|
+
}
|
|
95373
|
+
// Match HTML tags with bounded attribute length to prevent ReDoS
|
|
95374
|
+
const htmlTagPattern = /<[a-z][a-z0-9]*(?:\s[^>]{0,50})?(?:\/>|>)/i;
|
|
95375
|
+
if (htmlTagPattern.test(contentForHtmlMdx)) {
|
|
95376
|
+
return false;
|
|
95377
|
+
}
|
|
95378
|
+
return true;
|
|
95379
|
+
}
|
|
95380
|
+
|
|
95297
95381
|
;// ./lib/index.ts
|
|
95298
95382
|
|
|
95299
95383
|
|
|
@@ -95312,6 +95396,7 @@ async function stripComments(doc, { mdx } = {}) {
|
|
|
95312
95396
|
|
|
95313
95397
|
|
|
95314
95398
|
|
|
95399
|
+
|
|
95315
95400
|
;// ./index.tsx
|
|
95316
95401
|
|
|
95317
95402
|
|
package/dist/main.node.js
CHANGED
|
@@ -19024,6 +19024,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
19024
19024
|
exports: () => (/* reexport */ lib_exports),
|
|
19025
19025
|
gemojiRegex: () => (/* reexport */ gemoji_regex),
|
|
19026
19026
|
hast: () => (/* reexport */ lib_hast),
|
|
19027
|
+
isPlainText: () => (/* reexport */ isPlainText),
|
|
19027
19028
|
mdast: () => (/* reexport */ lib_mdast),
|
|
19028
19029
|
mdastV6: () => (/* reexport */ lib_mdastV6),
|
|
19029
19030
|
mdx: () => (/* reexport */ lib_mdx),
|
|
@@ -115498,6 +115499,89 @@ async function stripComments(doc, { mdx } = {}) {
|
|
|
115498
115499
|
}
|
|
115499
115500
|
/* harmony default export */ const lib_stripComments = (stripComments);
|
|
115500
115501
|
|
|
115502
|
+
;// ./lib/utils/isPlainText.ts
|
|
115503
|
+
|
|
115504
|
+
/**
|
|
115505
|
+
* Detects if content contains HTML, magic blocks, or MDX syntax.
|
|
115506
|
+
*
|
|
115507
|
+
* We can use this in some pipelines to determine if we should have to parse content through
|
|
115508
|
+
* `.plain() or if it is already plain text and it should be able to detect everything that would
|
|
115509
|
+
* be stripped or sanitized by `.plain()`.
|
|
115510
|
+
*
|
|
115511
|
+
*/
|
|
115512
|
+
function isPlainText(content) {
|
|
115513
|
+
if (!content || typeof content !== 'string') {
|
|
115514
|
+
return true;
|
|
115515
|
+
}
|
|
115516
|
+
// Exclude markdown code blocks and inline code to avoid false positives
|
|
115517
|
+
// Match code blocks with optional language identifier: ```lang\n...\n```
|
|
115518
|
+
const codeBlockRegex = /```[^\n]*\n[\s\S]*?```/g;
|
|
115519
|
+
// Match inline code: `code` (but not escaped backticks)
|
|
115520
|
+
const inlineCodeRegex = /`[^`\n]+`/g;
|
|
115521
|
+
// Remove code blocks and inline code to avoid false positives
|
|
115522
|
+
let contentWithoutCode = structuredClone(content);
|
|
115523
|
+
contentWithoutCode = contentWithoutCode.replace(codeBlockRegex, '');
|
|
115524
|
+
contentWithoutCode = contentWithoutCode.replace(inlineCodeRegex, '');
|
|
115525
|
+
// Check for magic blocks: `[block:TYPE]...[/block]`
|
|
115526
|
+
// Only check after removing code blocks to avoid detecting magic blocks in code
|
|
115527
|
+
if (contentWithoutCode.match(MAGIC_BLOCK_REGEX) !== null) {
|
|
115528
|
+
return false;
|
|
115529
|
+
}
|
|
115530
|
+
// Check for markdown links: [text](url) or [text][reference]
|
|
115531
|
+
// Pattern matches inline links and reference-style links
|
|
115532
|
+
// Exclude images which start with ! before the bracket
|
|
115533
|
+
// Only check after removing code blocks
|
|
115534
|
+
const markdownLinkPattern = /(?<!!)\[([^\]]+)\]\(([^)]+)\)|(?<!!)\[([^\]]+)\]\[([^\]]*)\]/;
|
|
115535
|
+
if (markdownLinkPattern.test(contentWithoutCode)) {
|
|
115536
|
+
return false;
|
|
115537
|
+
}
|
|
115538
|
+
// Check for JSX elements (PascalCase components) in the original content
|
|
115539
|
+
// This includes code blocks since JSX code examples should be detected
|
|
115540
|
+
// Pattern matches:
|
|
115541
|
+
// - Self-closing: <Component /> or <Component/>
|
|
115542
|
+
// - With attributes: <Component prop="value" />
|
|
115543
|
+
// - With children: <Component>...</Component>
|
|
115544
|
+
// Use simpler, safer patterns to avoid ReDoS from backtracking
|
|
115545
|
+
// Match self-closing tags with bounded attribute length to prevent excessive backtracking
|
|
115546
|
+
const jsxSelfClosingPattern = /<[A-Z][a-zA-Z0-9]*(?:\s[^>]{0,50})?\/>/;
|
|
115547
|
+
if (jsxSelfClosingPattern.test(content)) {
|
|
115548
|
+
return false;
|
|
115549
|
+
}
|
|
115550
|
+
// For components with children, use a safer pattern that limits backtracking
|
|
115551
|
+
// Match opening tag with bounded attributes, then look for closing tag with same name
|
|
115552
|
+
const jsxWithChildrenPattern = /<([A-Z][a-zA-Z0-9]*)(?:\s[^>]{0,50})?>[\s\S]{0,50}<\/\1>/;
|
|
115553
|
+
if (jsxWithChildrenPattern.test(content)) {
|
|
115554
|
+
return false;
|
|
115555
|
+
}
|
|
115556
|
+
// Check for MDX expressions and HTML tags in the original content
|
|
115557
|
+
// HTML/JSX/MDX in code blocks should be detected (as per test requirements)
|
|
115558
|
+
// But exclude inline code that contains magic block patterns to avoid false positives
|
|
115559
|
+
let contentForHtmlMdx = content;
|
|
115560
|
+
// Find inline code blocks and check if they contain [block: pattern
|
|
115561
|
+
// Exclude these from HTML/MDX detection to avoid false positives
|
|
115562
|
+
const inlineCodePattern = /`[^`\n]+`/g;
|
|
115563
|
+
let inlineCodeMatch;
|
|
115564
|
+
inlineCodePattern.lastIndex = 0;
|
|
115565
|
+
while ((inlineCodeMatch = inlineCodePattern.exec(content)) !== null) {
|
|
115566
|
+
if (inlineCodeMatch[0].includes('[block:')) {
|
|
115567
|
+
contentForHtmlMdx = contentForHtmlMdx.replace(inlineCodeMatch[0], '');
|
|
115568
|
+
}
|
|
115569
|
+
}
|
|
115570
|
+
// Match simple MDX variable expressions like {variable}, {user.name}, {getValue()}, {}
|
|
115571
|
+
// Use bounded quantifier to prevent ReDoS - limit to reasonable variable name length
|
|
115572
|
+
// Allow empty braces {} to be detected as well
|
|
115573
|
+
const jsxExpressionPattern = /\{[^}"]{0,50}\}/;
|
|
115574
|
+
if (jsxExpressionPattern.test(contentForHtmlMdx)) {
|
|
115575
|
+
return false;
|
|
115576
|
+
}
|
|
115577
|
+
// Match HTML tags with bounded attribute length to prevent ReDoS
|
|
115578
|
+
const htmlTagPattern = /<[a-z][a-z0-9]*(?:\s[^>]{0,50})?(?:\/>|>)/i;
|
|
115579
|
+
if (htmlTagPattern.test(contentForHtmlMdx)) {
|
|
115580
|
+
return false;
|
|
115581
|
+
}
|
|
115582
|
+
return true;
|
|
115583
|
+
}
|
|
115584
|
+
|
|
115501
115585
|
;// ./lib/index.ts
|
|
115502
115586
|
|
|
115503
115587
|
|
|
@@ -115516,6 +115600,7 @@ async function stripComments(doc, { mdx } = {}) {
|
|
|
115516
115600
|
|
|
115517
115601
|
|
|
115518
115602
|
|
|
115603
|
+
|
|
115519
115604
|
;// ./index.tsx
|
|
115520
115605
|
|
|
115521
115606
|
|