pd-markdown 1.0.0 → 1.0.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.
Files changed (170) hide show
  1. package/README.md +293 -0
  2. package/package.json +68 -1
  3. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/index.d.ts +0 -4
  4. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/index.d.ts.map +0 -1
  5. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/index.js +0 -5
  6. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/index.js.map +0 -1
  7. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/index.d.ts +0 -4
  8. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/index.d.ts.map +0 -1
  9. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/index.js +0 -4
  10. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/index.js.map +0 -1
  11. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/heading.d.ts +0 -6
  12. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/heading.d.ts.map +0 -1
  13. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/heading.js +0 -36
  14. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/heading.js.map +0 -1
  15. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/list.d.ts +0 -14
  16. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/list.d.ts.map +0 -1
  17. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/list.js +0 -18
  18. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/list.js.map +0 -1
  19. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/table.d.ts +0 -27
  20. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/table.d.ts.map +0 -1
  21. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/table.js +0 -37
  22. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/plugins/transform/table.js.map +0 -1
  23. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/processor.d.ts +0 -22
  24. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/processor.d.ts.map +0 -1
  25. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/processor.js +0 -95
  26. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/processor.js.map +0 -1
  27. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/types/index.d.ts +0 -55
  28. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/types/index.d.ts.map +0 -1
  29. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/types/index.js +0 -2
  30. package/packages/parser/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/parser/dist/types/index.js.map +0 -1
  31. package/packages/parser/__tests__/frontmatter.test.ts +0 -69
  32. package/packages/parser/__tests__/gfm.test.ts +0 -83
  33. package/packages/parser/__tests__/processor.test.ts +0 -136
  34. package/packages/parser/__tests__/transform/heading.test.ts +0 -56
  35. package/packages/parser/__tests__/transform/list.test.ts +0 -67
  36. package/packages/parser/__tests__/transform/table.test.ts +0 -85
  37. package/packages/parser/node_modules/.bin/yaml +0 -17
  38. package/packages/parser/package.json +0 -38
  39. package/packages/parser/rollup.config.ts +0 -38
  40. package/packages/parser/src/index.ts +0 -15
  41. package/packages/parser/src/plugins/index.ts +0 -3
  42. package/packages/parser/src/plugins/transform/heading.ts +0 -40
  43. package/packages/parser/src/plugins/transform/list.ts +0 -29
  44. package/packages/parser/src/plugins/transform/table.ts +0 -62
  45. package/packages/parser/src/processor.ts +0 -119
  46. package/packages/parser/src/types/index.ts +0 -60
  47. package/packages/parser/tsconfig.json +0 -9
  48. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/ast/query.d.ts +0 -36
  49. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/ast/query.d.ts.map +0 -1
  50. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/ast/query.js +0 -99
  51. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/ast/query.js.map +0 -1
  52. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/ast/traverse.d.ts +0 -22
  53. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/ast/traverse.d.ts.map +0 -1
  54. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/ast/traverse.js +0 -46
  55. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/ast/traverse.js.map +0 -1
  56. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/index.d.ts +0 -7
  57. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/index.d.ts.map +0 -1
  58. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/index.js +0 -8
  59. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/index.js.map +0 -1
  60. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/string/sanitize.d.ts +0 -22
  61. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/string/sanitize.d.ts.map +0 -1
  62. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/string/sanitize.js +0 -140
  63. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/string/sanitize.js.map +0 -1
  64. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/string/slugify.d.ts +0 -16
  65. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/string/slugify.d.ts.map +0 -1
  66. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/string/slugify.js +0 -39
  67. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/string/slugify.js.map +0 -1
  68. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/types/index.d.ts +0 -49
  69. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/types/index.d.ts.map +0 -1
  70. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/types/index.js +0 -19
  71. package/packages/utils/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/utils/dist/types/index.js.map +0 -1
  72. package/packages/utils/__tests__/query.test.ts +0 -155
  73. package/packages/utils/__tests__/sanitize.test.ts +0 -96
  74. package/packages/utils/__tests__/slugify.test.ts +0 -71
  75. package/packages/utils/__tests__/traverse.test.ts +0 -131
  76. package/packages/utils/package.json +0 -27
  77. package/packages/utils/rollup.config.ts +0 -26
  78. package/packages/utils/src/ast/query.ts +0 -127
  79. package/packages/utils/src/ast/traverse.ts +0 -73
  80. package/packages/utils/src/index.ts +0 -20
  81. package/packages/utils/src/string/sanitize.ts +0 -155
  82. package/packages/utils/src/string/slugify.ts +0 -43
  83. package/packages/utils/src/types/index.ts +0 -72
  84. package/packages/utils/tsconfig.json +0 -8
  85. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/MarkdownRenderer.d.ts +0 -27
  86. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/MarkdownRenderer.d.ts.map +0 -1
  87. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/MarkdownRenderer.js +0 -39
  88. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/MarkdownRenderer.js.map +0 -1
  89. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/NodeRenderer.d.ts +0 -10
  90. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/NodeRenderer.d.ts.map +0 -1
  91. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/NodeRenderer.js +0 -130
  92. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/NodeRenderer.js.map +0 -1
  93. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/context.d.ts +0 -17
  94. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/context.d.ts.map +0 -1
  95. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/context.js +0 -14
  96. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/context.js.map +0 -1
  97. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Blockquote.d.ts +0 -8
  98. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Blockquote.d.ts.map +0 -1
  99. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Blockquote.js +0 -5
  100. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Blockquote.js.map +0 -1
  101. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Code.d.ts +0 -13
  102. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Code.d.ts.map +0 -1
  103. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Code.js +0 -9
  104. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Code.js.map +0 -1
  105. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Heading.d.ts +0 -8
  106. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Heading.d.ts.map +0 -1
  107. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Heading.js +0 -7
  108. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Heading.js.map +0 -1
  109. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Image.d.ts +0 -7
  110. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Image.d.ts.map +0 -1
  111. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Image.js +0 -5
  112. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Image.js.map +0 -1
  113. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Link.d.ts +0 -8
  114. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Link.d.ts.map +0 -1
  115. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Link.js +0 -7
  116. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Link.js.map +0 -1
  117. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/List.d.ts +0 -13
  118. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/List.d.ts.map +0 -1
  119. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/List.js +0 -14
  120. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/List.js.map +0 -1
  121. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Paragraph.d.ts +0 -8
  122. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Paragraph.d.ts.map +0 -1
  123. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Paragraph.js +0 -5
  124. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Paragraph.js.map +0 -1
  125. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Table.d.ts +0 -19
  126. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Table.d.ts.map +0 -1
  127. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Table.js +0 -18
  128. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/Table.js.map +0 -1
  129. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/index.d.ts +0 -34
  130. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/index.d.ts.map +0 -1
  131. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/index.js +0 -28
  132. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/components/defaults/index.js.map +0 -1
  133. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/hooks/useMarkdown.d.ts +0 -11
  134. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/hooks/useMarkdown.d.ts.map +0 -1
  135. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/hooks/useMarkdown.js +0 -28
  136. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/hooks/useMarkdown.js.map +0 -1
  137. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/index.d.ts +0 -6
  138. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/index.d.ts.map +0 -1
  139. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/index.js +0 -9
  140. package/packages/web/.rollup.cache/Users/pidan/Work/Learn/pd-markdown/packages/web/dist/index.js.map +0 -1
  141. package/packages/web/__tests__/MarkdownRenderer.test.tsx +0 -89
  142. package/packages/web/__tests__/NodeRenderer.test.tsx +0 -97
  143. package/packages/web/__tests__/components/Code.test.tsx +0 -71
  144. package/packages/web/__tests__/components/Heading.test.tsx +0 -65
  145. package/packages/web/__tests__/components/List.test.tsx +0 -100
  146. package/packages/web/__tests__/components/Table.test.tsx +0 -105
  147. package/packages/web/__tests__/useMarkdown.test.ts +0 -63
  148. package/packages/web/package.json +0 -40
  149. package/packages/web/rollup.config.ts +0 -36
  150. package/packages/web/src/components/MarkdownRenderer.tsx +0 -70
  151. package/packages/web/src/components/NodeRenderer.tsx +0 -205
  152. package/packages/web/src/components/context.ts +0 -24
  153. package/packages/web/src/components/defaults/Blockquote.tsx +0 -11
  154. package/packages/web/src/components/defaults/Code.tsx +0 -26
  155. package/packages/web/src/components/defaults/Heading.tsx +0 -14
  156. package/packages/web/src/components/defaults/Image.tsx +0 -10
  157. package/packages/web/src/components/defaults/Link.tsx +0 -18
  158. package/packages/web/src/components/defaults/List.tsx +0 -33
  159. package/packages/web/src/components/defaults/Paragraph.tsx +0 -11
  160. package/packages/web/src/components/defaults/Table.tsx +0 -50
  161. package/packages/web/src/components/defaults/index.tsx +0 -80
  162. package/packages/web/src/hooks/useMarkdown.ts +0 -32
  163. package/packages/web/src/index.ts +0 -37
  164. package/packages/web/tsconfig.json +0 -11
  165. package/packages/web/vitest.config.ts +0 -9
  166. package/pnpm-workspace.yaml +0 -2
  167. package/tsconfig.base.json +0 -26
  168. package/tsconfig.json +0 -8
  169. package/vitest.config.ts +0 -28
  170. package/vitest.setup.ts +0 -1
@@ -1,22 +0,0 @@
1
- /**
2
- * Escape HTML special characters
3
- *
4
- * @param text - Text to escape
5
- * @returns Escaped text safe for HTML insertion
6
- */
7
- export declare function escapeHtml(text: string): string;
8
- /**
9
- * Sanitize HTML string by removing dangerous content
10
- *
11
- * @param html - HTML string to sanitize
12
- * @returns Sanitized HTML string
13
- */
14
- export declare function sanitizeHtml(html: string): string;
15
- /**
16
- * Strip all HTML tags from a string
17
- *
18
- * @param html - HTML string to strip
19
- * @returns Plain text without HTML tags
20
- */
21
- export declare function stripHtml(html: string): string;
22
- //# sourceMappingURL=sanitize.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/string/sanitize.ts"],"names":[],"mappings":"AAWA;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAwED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA+CjD;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C"}
@@ -1,140 +0,0 @@
1
- /**
2
- * HTML entities that need escaping
3
- */
4
- const HTML_ESCAPE_MAP = {
5
- '&': '&',
6
- '<': '&lt;',
7
- '>': '&gt;',
8
- '"': '&quot;',
9
- "'": '&#39;',
10
- };
11
- /**
12
- * Escape HTML special characters
13
- *
14
- * @param text - Text to escape
15
- * @returns Escaped text safe for HTML insertion
16
- */
17
- export function escapeHtml(text) {
18
- return text.replace(/[&<>"']/g, (char) => HTML_ESCAPE_MAP[char] || char);
19
- }
20
- /**
21
- * Allowed HTML tags for sanitization
22
- */
23
- const ALLOWED_TAGS = new Set([
24
- 'a',
25
- 'abbr',
26
- 'b',
27
- 'blockquote',
28
- 'br',
29
- 'code',
30
- 'dd',
31
- 'del',
32
- 'div',
33
- 'dl',
34
- 'dt',
35
- 'em',
36
- 'h1',
37
- 'h2',
38
- 'h3',
39
- 'h4',
40
- 'h5',
41
- 'h6',
42
- 'hr',
43
- 'i',
44
- 'img',
45
- 'ins',
46
- 'kbd',
47
- 'li',
48
- 'ol',
49
- 'p',
50
- 'pre',
51
- 'q',
52
- 's',
53
- 'samp',
54
- 'small',
55
- 'span',
56
- 'strong',
57
- 'sub',
58
- 'sup',
59
- 'table',
60
- 'tbody',
61
- 'td',
62
- 'tfoot',
63
- 'th',
64
- 'thead',
65
- 'tr',
66
- 'u',
67
- 'ul',
68
- ]);
69
- /**
70
- * Allowed attributes for sanitization
71
- */
72
- const ALLOWED_ATTRS = new Set([
73
- 'href',
74
- 'src',
75
- 'alt',
76
- 'title',
77
- 'class',
78
- 'id',
79
- 'name',
80
- 'target',
81
- 'rel',
82
- 'width',
83
- 'height',
84
- 'align',
85
- 'colspan',
86
- 'rowspan',
87
- ]);
88
- /**
89
- * Sanitize HTML string by removing dangerous content
90
- *
91
- * @param html - HTML string to sanitize
92
- * @returns Sanitized HTML string
93
- */
94
- export function sanitizeHtml(html) {
95
- let result = html;
96
- // Remove script tags first
97
- result = result.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
98
- // Remove event handlers
99
- result = result.replace(/\s+on\w+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]*)/gi, '');
100
- // Remove disallowed tags (keep content) and sanitize attributes
101
- result = result.replace(/<\/?(\w+)([^>]*)>/g, (match, tagName, attrs) => {
102
- const tag = tagName.toLowerCase();
103
- if (!ALLOWED_TAGS.has(tag)) {
104
- return '';
105
- }
106
- // For closing tags, just return them
107
- if (match.startsWith('</')) {
108
- return `</${tag}>`;
109
- }
110
- // Sanitize attributes
111
- const sanitizedAttrs = [];
112
- const attrRegex = /\s+([\w-]+)\s*=\s*(?:"([^"]*)"|'([^']*)'|(\S+))/g;
113
- let attrMatch;
114
- while ((attrMatch = attrRegex.exec(attrs)) !== null) {
115
- const [, attrName, v1, v2, v3] = attrMatch;
116
- const attr = attrName.toLowerCase();
117
- if (ALLOWED_ATTRS.has(attr)) {
118
- let value = v1 ?? v2 ?? v3 ?? '';
119
- // Check for dangerous URLs in href/src
120
- if ((attr === 'href' || attr === 'src') && /^\s*javascript\s*:/i.test(value)) {
121
- value = '';
122
- }
123
- sanitizedAttrs.push(`${attr}="${value}"`);
124
- }
125
- }
126
- const attrStr = sanitizedAttrs.length > 0 ? ' ' + sanitizedAttrs.join(' ') : '';
127
- return `<${tag}${attrStr}>`;
128
- });
129
- return result;
130
- }
131
- /**
132
- * Strip all HTML tags from a string
133
- *
134
- * @param html - HTML string to strip
135
- * @returns Plain text without HTML tags
136
- */
137
- export function stripHtml(html) {
138
- return html.replace(/<[^>]*>/g, '');
139
- }
140
- //# sourceMappingURL=sanitize.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../../src/string/sanitize.ts"],"names":[],"mappings":"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"}
@@ -1,16 +0,0 @@
1
- /**
2
- * Convert text to URL-safe slug
3
- *
4
- * @param text - Text to slugify
5
- * @returns URL-safe slug
6
- */
7
- export declare function slugify(text: string): string;
8
- /**
9
- * Generate unique slug with counter suffix for duplicates
10
- *
11
- * @param text - Text to slugify
12
- * @param existingSlugs - Set of existing slugs to check against
13
- * @returns Unique slug
14
- */
15
- export declare function uniqueSlugify(text: string, existingSlugs: Set<string>): string;
16
- //# sourceMappingURL=slugify.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"slugify.d.ts","sourceRoot":"","sources":["../../src/string/slugify.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAe5C;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,MAAM,CAY9E"}
@@ -1,39 +0,0 @@
1
- /**
2
- * Convert text to URL-safe slug
3
- *
4
- * @param text - Text to slugify
5
- * @returns URL-safe slug
6
- */
7
- export function slugify(text) {
8
- return (text
9
- // Convert to lowercase
10
- .toLowerCase()
11
- // Replace Chinese characters with pinyin-like representation (keep as-is for simplicity)
12
- // Replace spaces and special chars with hyphens
13
- .replace(/[\s_]+/g, '-')
14
- // Remove characters that aren't alphanumeric, hyphens, or common CJK
15
- .replace(/[^\w\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff-]/g, '')
16
- // Replace multiple consecutive hyphens with single hyphen
17
- .replace(/-+/g, '-')
18
- // Remove leading/trailing hyphens
19
- .replace(/^-+|-+$/g, ''));
20
- }
21
- /**
22
- * Generate unique slug with counter suffix for duplicates
23
- *
24
- * @param text - Text to slugify
25
- * @param existingSlugs - Set of existing slugs to check against
26
- * @returns Unique slug
27
- */
28
- export function uniqueSlugify(text, existingSlugs) {
29
- const baseSlug = slugify(text);
30
- let slug = baseSlug;
31
- let counter = 1;
32
- while (existingSlugs.has(slug)) {
33
- slug = `${baseSlug}-${counter}`;
34
- counter++;
35
- }
36
- existingSlugs.add(slug);
37
- return slug;
38
- }
39
- //# sourceMappingURL=slugify.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"slugify.js","sourceRoot":"","sources":["../../src/string/slugify.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,CACL,IAAI;QACF,uBAAuB;SACtB,WAAW,EAAE;QACd,yFAAyF;QACzF,gDAAgD;SAC/C,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;QACxB,qEAAqE;SACpE,OAAO,CAAC,gDAAgD,EAAE,EAAE,CAAC;QAC9D,0DAA0D;SACzD,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;QACpB,kCAAkC;SACjC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAC3B,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,aAA0B;IACpE,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9B,IAAI,IAAI,GAAG,QAAQ,CAAA;IACnB,IAAI,OAAO,GAAG,CAAC,CAAA;IAEf,OAAO,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,IAAI,GAAG,GAAG,QAAQ,IAAI,OAAO,EAAE,CAAA;QAC/B,OAAO,EAAE,CAAA;IACX,CAAC;IAED,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IACvB,OAAO,IAAI,CAAA;AACb,CAAC"}
@@ -1,49 +0,0 @@
1
- import type { Root, Content, Parent, Literal } from 'mdast';
2
- import type { Node as UnistNode } from 'unist';
3
- export type { Root, Content, Parent, Literal };
4
- /**
5
- * All possible markdown node types
6
- */
7
- export type MdNode = Root | Content;
8
- /**
9
- * Root node of markdown AST
10
- */
11
- export type MdRoot = Root;
12
- /**
13
- * Visitor function for AST traversal
14
- */
15
- export type Visitor<T extends UnistNode = MdNode> = (node: T, index: number | undefined, parent: Parent | undefined) => void | boolean;
16
- /**
17
- * Plugin options base interface
18
- */
19
- export interface PluginOptions {
20
- [key: string]: unknown;
21
- }
22
- /**
23
- * Position information in source
24
- */
25
- export interface Position {
26
- line: number;
27
- column: number;
28
- offset?: number;
29
- }
30
- /**
31
- * Location in source
32
- */
33
- export interface Location {
34
- start: Position;
35
- end: Position;
36
- }
37
- /**
38
- * Type guard to check if node is a parent node
39
- */
40
- export declare function isParent(node: UnistNode): node is Parent;
41
- /**
42
- * Type guard to check if node is a literal node
43
- */
44
- export declare function isLiteral(node: UnistNode): node is Literal;
45
- /**
46
- * Type guard to check if node has specific type
47
- */
48
- export declare function isNodeType<T extends MdNode>(node: UnistNode, type: T['type']): node is T;
49
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAC3D,OAAO,KAAK,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,OAAO,CAAA;AAG9C,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAA;AAE9C;;GAEG;AACH,MAAM,MAAM,MAAM,GAAG,IAAI,GAAG,OAAO,CAAA;AAEnC;;GAEG;AACH,MAAM,MAAM,MAAM,GAAG,IAAI,CAAA;AAEzB;;GAEG;AACH,MAAM,MAAM,OAAO,CAAC,CAAC,SAAS,SAAS,GAAG,MAAM,IAAI,CAClD,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,MAAM,EAAE,MAAM,GAAG,SAAS,KACvB,IAAI,GAAG,OAAO,CAAA;AAEnB;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,QAAQ,CAAA;IACf,GAAG,EAAE,QAAQ,CAAA;CACd;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,IAAI,MAAM,CAExD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,IAAI,OAAO,CAE1D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EACzC,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,GACd,IAAI,IAAI,CAAC,CAEX"}
@@ -1,19 +0,0 @@
1
- /**
2
- * Type guard to check if node is a parent node
3
- */
4
- export function isParent(node) {
5
- return 'children' in node && Array.isArray(node.children);
6
- }
7
- /**
8
- * Type guard to check if node is a literal node
9
- */
10
- export function isLiteral(node) {
11
- return 'value' in node && typeof node.value === 'string';
12
- }
13
- /**
14
- * Type guard to check if node has specific type
15
- */
16
- export function isNodeType(node, type) {
17
- return node.type === type;
18
- }
19
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAiDA;;GAEG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAe;IACtC,OAAO,UAAU,IAAI,IAAI,IAAI,KAAK,CAAC,OAAO,CAAE,IAAe,CAAC,QAAQ,CAAC,CAAA;AACvE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,IAAe;IACvC,OAAO,OAAO,IAAI,IAAI,IAAI,OAAQ,IAAgB,CAAC,KAAK,KAAK,QAAQ,CAAA;AACvE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CACxB,IAAe,EACf,IAAe;IAEf,OAAO,IAAI,CAAC,IAAI,KAAK,IAAI,CAAA;AAC3B,CAAC"}
@@ -1,155 +0,0 @@
1
- import { describe, it, expect } from 'vitest'
2
- import { findNodes, findNode, findNodesBy, findParent } from '../src/ast/query'
3
- import type { Root, Paragraph, Text, Heading, Strong } from 'mdast'
4
-
5
- describe('findNodes', () => {
6
- const createAst = (): Root => ({
7
- type: 'root',
8
- children: [
9
- {
10
- type: 'heading',
11
- depth: 1,
12
- children: [{ type: 'text', value: 'Title' }],
13
- } as Heading,
14
- {
15
- type: 'paragraph',
16
- children: [
17
- { type: 'text', value: 'Hello ' },
18
- {
19
- type: 'strong',
20
- children: [{ type: 'text', value: 'world' }],
21
- } as Strong,
22
- ],
23
- } as Paragraph,
24
- {
25
- type: 'heading',
26
- depth: 2,
27
- children: [{ type: 'text', value: 'Subtitle' }],
28
- } as Heading,
29
- ],
30
- })
31
-
32
- it('should find all nodes of specified type', () => {
33
- const ast = createAst()
34
- const headings = findNodes<Heading>(ast, 'heading')
35
-
36
- expect(headings).toHaveLength(2)
37
- expect(headings[0].depth).toBe(1)
38
- expect(headings[1].depth).toBe(2)
39
- })
40
-
41
- it('should find nested nodes', () => {
42
- const ast = createAst()
43
- const texts = findNodes<Text>(ast, 'text')
44
-
45
- expect(texts).toHaveLength(4)
46
- expect(texts.map((t) => t.value)).toEqual([
47
- 'Title',
48
- 'Hello ',
49
- 'world',
50
- 'Subtitle',
51
- ])
52
- })
53
-
54
- it('should return empty array when no matches', () => {
55
- const ast = createAst()
56
- const codes = findNodes(ast, 'code')
57
-
58
- expect(codes).toEqual([])
59
- })
60
- })
61
-
62
- describe('findNode', () => {
63
- const createAst = (): Root => ({
64
- type: 'root',
65
- children: [
66
- {
67
- type: 'heading',
68
- depth: 1,
69
- children: [{ type: 'text', value: 'First' }],
70
- } as Heading,
71
- {
72
- type: 'heading',
73
- depth: 2,
74
- children: [{ type: 'text', value: 'Second' }],
75
- } as Heading,
76
- ],
77
- })
78
-
79
- it('should find first matching node', () => {
80
- const ast = createAst()
81
- const heading = findNode<Heading>(ast, 'heading')
82
-
83
- expect(heading).toBeDefined()
84
- expect(heading!.depth).toBe(1)
85
- })
86
-
87
- it('should return undefined when no match', () => {
88
- const ast = createAst()
89
- const code = findNode(ast, 'code')
90
-
91
- expect(code).toBeUndefined()
92
- })
93
- })
94
-
95
- describe('findNodesBy', () => {
96
- const createAst = (): Root => ({
97
- type: 'root',
98
- children: [
99
- {
100
- type: 'heading',
101
- depth: 1,
102
- children: [{ type: 'text', value: 'H1' }],
103
- } as Heading,
104
- {
105
- type: 'heading',
106
- depth: 2,
107
- children: [{ type: 'text', value: 'H2' }],
108
- } as Heading,
109
- {
110
- type: 'heading',
111
- depth: 1,
112
- children: [{ type: 'text', value: 'Another H1' }],
113
- } as Heading,
114
- ],
115
- })
116
-
117
- it('should find nodes matching predicate', () => {
118
- const ast = createAst()
119
- const h1s = findNodesBy<Heading>(
120
- ast,
121
- (node) => node.type === 'heading' && (node as Heading).depth === 1
122
- )
123
-
124
- expect(h1s).toHaveLength(2)
125
- expect(h1s[0].children[0]).toHaveProperty('value', 'H1')
126
- expect(h1s[1].children[0]).toHaveProperty('value', 'Another H1')
127
- })
128
- })
129
-
130
- describe('findParent', () => {
131
- it('should find parent of a node', () => {
132
- const textNode: Text = { type: 'text', value: 'Hello' }
133
- const paragraph: Paragraph = {
134
- type: 'paragraph',
135
- children: [textNode],
136
- }
137
- const ast: Root = {
138
- type: 'root',
139
- children: [paragraph],
140
- }
141
-
142
- const parent = findParent(ast, textNode)
143
- expect(parent).toBe(paragraph)
144
- })
145
-
146
- it('should return undefined for root node', () => {
147
- const ast: Root = {
148
- type: 'root',
149
- children: [],
150
- }
151
-
152
- const parent = findParent(ast, ast)
153
- expect(parent).toBeUndefined()
154
- })
155
- })
@@ -1,96 +0,0 @@
1
- import { describe, it, expect } from 'vitest'
2
- import { escapeHtml, sanitizeHtml, stripHtml } from '../src/string/sanitize'
3
-
4
- describe('escapeHtml', () => {
5
- it('should escape ampersand', () => {
6
- expect(escapeHtml('foo & bar')).toBe('foo &amp; bar')
7
- })
8
-
9
- it('should escape less than', () => {
10
- expect(escapeHtml('a < b')).toBe('a &lt; b')
11
- })
12
-
13
- it('should escape greater than', () => {
14
- expect(escapeHtml('a > b')).toBe('a &gt; b')
15
- })
16
-
17
- it('should escape double quotes', () => {
18
- expect(escapeHtml('say "hello"')).toBe('say &quot;hello&quot;')
19
- })
20
-
21
- it('should escape single quotes', () => {
22
- expect(escapeHtml("it's")).toBe('it&#39;s')
23
- })
24
-
25
- it('should escape multiple characters', () => {
26
- expect(escapeHtml('<script>alert("xss")</script>')).toBe(
27
- '&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;'
28
- )
29
- })
30
-
31
- it('should preserve safe text', () => {
32
- expect(escapeHtml('Hello World 123')).toBe('Hello World 123')
33
- })
34
- })
35
-
36
- describe('sanitizeHtml', () => {
37
- it('should remove script tags', () => {
38
- expect(sanitizeHtml('<script>alert("xss")</script>')).toBe('')
39
- })
40
-
41
- it('should remove event handlers', () => {
42
- expect(sanitizeHtml('<div onclick="alert(1)">text</div>')).toBe(
43
- '<div>text</div>'
44
- )
45
- })
46
-
47
- it('should remove javascript: URLs', () => {
48
- expect(sanitizeHtml('<a href="javascript:alert(1)">click</a>')).toBe(
49
- '<a href="">click</a>'
50
- )
51
- })
52
-
53
- it('should preserve allowed tags', () => {
54
- expect(sanitizeHtml('<p>Hello <strong>world</strong></p>')).toBe(
55
- '<p>Hello <strong>world</strong></p>'
56
- )
57
- })
58
-
59
- it('should preserve allowed attributes', () => {
60
- expect(sanitizeHtml('<a href="https://example.com" title="link">text</a>')).toBe(
61
- '<a href="https://example.com" title="link">text</a>'
62
- )
63
- })
64
-
65
- it('should remove disallowed tags', () => {
66
- expect(sanitizeHtml('<iframe src="evil.com"></iframe>')).toBe('')
67
- })
68
-
69
- it('should remove disallowed attributes', () => {
70
- expect(sanitizeHtml('<div data-evil="bad">text</div>')).toBe('<div>text</div>')
71
- })
72
-
73
- it('should handle nested script content', () => {
74
- expect(
75
- sanitizeHtml('<div><script>bad()</script>safe</div>')
76
- ).toBe('<div>safe</div>')
77
- })
78
- })
79
-
80
- describe('stripHtml', () => {
81
- it('should remove all HTML tags', () => {
82
- expect(stripHtml('<p>Hello <strong>world</strong></p>')).toBe('Hello world')
83
- })
84
-
85
- it('should handle self-closing tags', () => {
86
- expect(stripHtml('Hello<br/>World')).toBe('HelloWorld')
87
- })
88
-
89
- it('should preserve text content', () => {
90
- expect(stripHtml('No tags here')).toBe('No tags here')
91
- })
92
-
93
- it('should handle nested tags', () => {
94
- expect(stripHtml('<div><p><span>Deep</span></p></div>')).toBe('Deep')
95
- })
96
- })
@@ -1,71 +0,0 @@
1
- import { describe, it, expect } from 'vitest'
2
- import { slugify, uniqueSlugify } from '../src/string/slugify'
3
-
4
- describe('slugify', () => {
5
- it('should convert text to lowercase', () => {
6
- expect(slugify('Hello World')).toBe('hello-world')
7
- })
8
-
9
- it('should replace spaces with hyphens', () => {
10
- expect(slugify('hello world')).toBe('hello-world')
11
- })
12
-
13
- it('should replace underscores with hyphens', () => {
14
- expect(slugify('hello_world')).toBe('hello-world')
15
- })
16
-
17
- it('should remove special characters', () => {
18
- expect(slugify('Hello! World?')).toBe('hello-world')
19
- })
20
-
21
- it('should handle multiple consecutive spaces', () => {
22
- expect(slugify('hello world')).toBe('hello-world')
23
- })
24
-
25
- it('should remove leading and trailing hyphens', () => {
26
- expect(slugify(' hello world ')).toBe('hello-world')
27
- })
28
-
29
- it('should preserve Chinese characters', () => {
30
- expect(slugify('你好世界')).toBe('你好世界')
31
- })
32
-
33
- it('should handle mixed Chinese and English', () => {
34
- expect(slugify('Hello 你好 World')).toBe('hello-你好-world')
35
- })
36
-
37
- it('should handle Japanese characters', () => {
38
- expect(slugify('こんにちは')).toBe('こんにちは')
39
- })
40
-
41
- it('should return empty string for only special characters', () => {
42
- expect(slugify('!@#$%')).toBe('')
43
- })
44
-
45
- it('should handle numbers', () => {
46
- expect(slugify('Chapter 1')).toBe('chapter-1')
47
- })
48
- })
49
-
50
- describe('uniqueSlugify', () => {
51
- it('should return base slug when no duplicates', () => {
52
- const existing = new Set<string>()
53
- expect(uniqueSlugify('Hello World', existing)).toBe('hello-world')
54
- })
55
-
56
- it('should add counter for duplicates', () => {
57
- const existing = new Set(['hello-world'])
58
- expect(uniqueSlugify('Hello World', existing)).toBe('hello-world-1')
59
- })
60
-
61
- it('should increment counter for multiple duplicates', () => {
62
- const existing = new Set(['hello-world', 'hello-world-1', 'hello-world-2'])
63
- expect(uniqueSlugify('Hello World', existing)).toBe('hello-world-3')
64
- })
65
-
66
- it('should add generated slug to existing set', () => {
67
- const existing = new Set<string>()
68
- uniqueSlugify('Hello World', existing)
69
- expect(existing.has('hello-world')).toBe(true)
70
- })
71
- })