@codefluss/sandbox 0.0.1-alpha.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 (233) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/README.md +413 -0
  3. package/dist/__tests__/auto-resize-script.test.d.ts +2 -0
  4. package/dist/__tests__/auto-resize-script.test.d.ts.map +1 -0
  5. package/dist/__tests__/auto-resize-script.test.js +49 -0
  6. package/dist/__tests__/auto-resize-script.test.js.map +1 -0
  7. package/dist/__tests__/sandbox-component.test.d.ts +2 -0
  8. package/dist/__tests__/sandbox-component.test.d.ts.map +1 -0
  9. package/dist/__tests__/sandbox-component.test.js +281 -0
  10. package/dist/__tests__/sandbox-component.test.js.map +1 -0
  11. package/dist/__tests__/sandbox-config.test.d.ts +2 -0
  12. package/dist/__tests__/sandbox-config.test.d.ts.map +1 -0
  13. package/dist/__tests__/sandbox-config.test.js +148 -0
  14. package/dist/__tests__/sandbox-config.test.js.map +1 -0
  15. package/dist/__tests__/sandbox-iframe.test.d.ts +2 -0
  16. package/dist/__tests__/sandbox-iframe.test.d.ts.map +1 -0
  17. package/dist/__tests__/sandbox-iframe.test.js +212 -0
  18. package/dist/__tests__/sandbox-iframe.test.js.map +1 -0
  19. package/dist/__tests__/setup.d.ts +2 -0
  20. package/dist/__tests__/setup.d.ts.map +1 -0
  21. package/dist/__tests__/setup.js +27 -0
  22. package/dist/__tests__/setup.js.map +1 -0
  23. package/dist/components/index.d.ts +5 -0
  24. package/dist/components/index.d.ts.map +1 -0
  25. package/dist/components/index.js +5 -0
  26. package/dist/components/index.js.map +1 -0
  27. package/dist/components/performance-wrapper.d.ts +12 -0
  28. package/dist/components/performance-wrapper.d.ts.map +1 -0
  29. package/dist/components/performance-wrapper.js +162 -0
  30. package/dist/components/performance-wrapper.js.map +1 -0
  31. package/dist/components/sandbox-component.d.ts +3 -0
  32. package/dist/components/sandbox-component.d.ts.map +1 -0
  33. package/dist/components/sandbox-component.js +123 -0
  34. package/dist/components/sandbox-component.js.map +1 -0
  35. package/dist/components/sandbox-iframe-cached.d.ts +3 -0
  36. package/dist/components/sandbox-iframe-cached.d.ts.map +1 -0
  37. package/dist/components/sandbox-iframe-cached.js +176 -0
  38. package/dist/components/sandbox-iframe-cached.js.map +1 -0
  39. package/dist/components/sandbox-iframe.d.ts +3 -0
  40. package/dist/components/sandbox-iframe.d.ts.map +1 -0
  41. package/dist/components/sandbox-iframe.js +131 -0
  42. package/dist/components/sandbox-iframe.js.map +1 -0
  43. package/dist/converters/auto-detect/auto-detect.d.ts +13 -0
  44. package/dist/converters/auto-detect/auto-detect.d.ts.map +1 -0
  45. package/dist/converters/auto-detect/auto-detect.js +224 -0
  46. package/dist/converters/auto-detect/auto-detect.js.map +1 -0
  47. package/dist/converters/auto-detect/index.d.ts +3 -0
  48. package/dist/converters/auto-detect/index.d.ts.map +1 -0
  49. package/dist/converters/auto-detect/index.js +2 -0
  50. package/dist/converters/auto-detect/index.js.map +1 -0
  51. package/dist/converters/codepen/codepen-converter.d.ts +9 -0
  52. package/dist/converters/codepen/codepen-converter.d.ts.map +1 -0
  53. package/dist/converters/codepen/codepen-converter.js +99 -0
  54. package/dist/converters/codepen/codepen-converter.js.map +1 -0
  55. package/dist/converters/codepen/index.d.ts +2 -0
  56. package/dist/converters/codepen/index.d.ts.map +1 -0
  57. package/dist/converters/codepen/index.js +2 -0
  58. package/dist/converters/codepen/index.js.map +1 -0
  59. package/dist/converters/gist/gist-converter.d.ts +31 -0
  60. package/dist/converters/gist/gist-converter.d.ts.map +1 -0
  61. package/dist/converters/gist/gist-converter.js +162 -0
  62. package/dist/converters/gist/gist-converter.js.map +1 -0
  63. package/dist/converters/gist/index.d.ts +2 -0
  64. package/dist/converters/gist/index.d.ts.map +1 -0
  65. package/dist/converters/gist/index.js +2 -0
  66. package/dist/converters/gist/index.js.map +1 -0
  67. package/dist/converters/shared/html-parser.d.ts +4 -0
  68. package/dist/converters/shared/html-parser.d.ts.map +1 -0
  69. package/dist/converters/shared/html-parser.js +39 -0
  70. package/dist/converters/shared/html-parser.js.map +1 -0
  71. package/dist/converters/shared/index.d.ts +4 -0
  72. package/dist/converters/shared/index.d.ts.map +1 -0
  73. package/dist/converters/shared/index.js +3 -0
  74. package/dist/converters/shared/index.js.map +1 -0
  75. package/dist/converters/shared/sanitization.d.ts +5 -0
  76. package/dist/converters/shared/sanitization.d.ts.map +1 -0
  77. package/dist/converters/shared/sanitization.js +176 -0
  78. package/dist/converters/shared/sanitization.js.map +1 -0
  79. package/dist/converters/shared/types.d.ts +23 -0
  80. package/dist/converters/shared/types.d.ts.map +1 -0
  81. package/dist/converters/shared/types.js +2 -0
  82. package/dist/converters/shared/types.js.map +1 -0
  83. package/dist/core/index.d.ts +13 -0
  84. package/dist/core/index.d.ts.map +1 -0
  85. package/dist/core/index.js +10 -0
  86. package/dist/core/index.js.map +1 -0
  87. package/dist/frameworks/__tests__/file-utils.test.d.ts +2 -0
  88. package/dist/frameworks/__tests__/file-utils.test.d.ts.map +1 -0
  89. package/dist/frameworks/__tests__/file-utils.test.js +408 -0
  90. package/dist/frameworks/__tests__/file-utils.test.js.map +1 -0
  91. package/dist/frameworks/__tests__/sandpack-wrapper.test.d.ts +2 -0
  92. package/dist/frameworks/__tests__/sandpack-wrapper.test.d.ts.map +1 -0
  93. package/dist/frameworks/__tests__/sandpack-wrapper.test.js +147 -0
  94. package/dist/frameworks/__tests__/sandpack-wrapper.test.js.map +1 -0
  95. package/dist/frameworks/file-utils.d.ts +20 -0
  96. package/dist/frameworks/file-utils.d.ts.map +1 -0
  97. package/dist/frameworks/file-utils.js +293 -0
  98. package/dist/frameworks/file-utils.js.map +1 -0
  99. package/dist/frameworks/framework-detector.d.ts +5 -0
  100. package/dist/frameworks/framework-detector.d.ts.map +1 -0
  101. package/dist/frameworks/framework-detector.js +117 -0
  102. package/dist/frameworks/framework-detector.js.map +1 -0
  103. package/dist/frameworks/index.d.ts +6 -0
  104. package/dist/frameworks/index.d.ts.map +1 -0
  105. package/dist/frameworks/index.js +5 -0
  106. package/dist/frameworks/index.js.map +1 -0
  107. package/dist/frameworks/sandpack-wrapper.d.ts +28 -0
  108. package/dist/frameworks/sandpack-wrapper.d.ts.map +1 -0
  109. package/dist/frameworks/sandpack-wrapper.js +55 -0
  110. package/dist/frameworks/sandpack-wrapper.js.map +1 -0
  111. package/dist/frameworks/templates/index.d.ts +8 -0
  112. package/dist/frameworks/templates/index.d.ts.map +1 -0
  113. package/dist/frameworks/templates/index.js +29 -0
  114. package/dist/frameworks/templates/index.js.map +1 -0
  115. package/dist/frameworks/templates/react-template.d.ts +3 -0
  116. package/dist/frameworks/templates/react-template.d.ts.map +1 -0
  117. package/dist/frameworks/templates/react-template.js +376 -0
  118. package/dist/frameworks/templates/react-template.js.map +1 -0
  119. package/dist/frameworks/templates/svelte-template.d.ts +3 -0
  120. package/dist/frameworks/templates/svelte-template.d.ts.map +1 -0
  121. package/dist/frameworks/templates/svelte-template.js +373 -0
  122. package/dist/frameworks/templates/svelte-template.js.map +1 -0
  123. package/dist/frameworks/templates/vanilla-template.d.ts +3 -0
  124. package/dist/frameworks/templates/vanilla-template.d.ts.map +1 -0
  125. package/dist/frameworks/templates/vanilla-template.js +455 -0
  126. package/dist/frameworks/templates/vanilla-template.js.map +1 -0
  127. package/dist/frameworks/templates/vue-template.d.ts +3 -0
  128. package/dist/frameworks/templates/vue-template.d.ts.map +1 -0
  129. package/dist/frameworks/templates/vue-template.js +388 -0
  130. package/dist/frameworks/templates/vue-template.js.map +1 -0
  131. package/dist/frameworks/types.d.ts +57 -0
  132. package/dist/frameworks/types.d.ts.map +1 -0
  133. package/dist/frameworks/types.js +2 -0
  134. package/dist/frameworks/types.js.map +1 -0
  135. package/dist/index.d.ts +7 -0
  136. package/dist/index.d.ts.map +1 -0
  137. package/dist/index.js +7 -0
  138. package/dist/index.js.map +1 -0
  139. package/dist/lib/performance-tracker.d.ts +45 -0
  140. package/dist/lib/performance-tracker.d.ts.map +1 -0
  141. package/dist/lib/performance-tracker.js +165 -0
  142. package/dist/lib/performance-tracker.js.map +1 -0
  143. package/dist/lib/sandbox-cache.d.ts +24 -0
  144. package/dist/lib/sandbox-cache.d.ts.map +1 -0
  145. package/dist/lib/sandbox-cache.js +138 -0
  146. package/dist/lib/sandbox-cache.js.map +1 -0
  147. package/dist/locales/de.json +72 -0
  148. package/dist/locales/en.json +72 -0
  149. package/dist/locales/index.d.ts +148 -0
  150. package/dist/locales/index.d.ts.map +1 -0
  151. package/dist/locales/index.js +7 -0
  152. package/dist/locales/index.js.map +1 -0
  153. package/dist/performance/sandpack-bundle-cache.d.ts +19 -0
  154. package/dist/performance/sandpack-bundle-cache.d.ts.map +1 -0
  155. package/dist/performance/sandpack-bundle-cache.js +48 -0
  156. package/dist/performance/sandpack-bundle-cache.js.map +1 -0
  157. package/dist/sandbox-config.d.ts +4 -0
  158. package/dist/sandbox-config.d.ts.map +1 -0
  159. package/dist/sandbox-config.js +235 -0
  160. package/dist/sandbox-config.js.map +1 -0
  161. package/dist/storage/__tests__/indexeddb-adapter.test.d.ts +2 -0
  162. package/dist/storage/__tests__/indexeddb-adapter.test.d.ts.map +1 -0
  163. package/dist/storage/__tests__/indexeddb-adapter.test.js +192 -0
  164. package/dist/storage/__tests__/indexeddb-adapter.test.js.map +1 -0
  165. package/dist/storage/__tests__/project-manager.test.d.ts +2 -0
  166. package/dist/storage/__tests__/project-manager.test.d.ts.map +1 -0
  167. package/dist/storage/__tests__/project-manager.test.js +266 -0
  168. package/dist/storage/__tests__/project-manager.test.js.map +1 -0
  169. package/dist/storage/index.d.ts +5 -0
  170. package/dist/storage/index.d.ts.map +1 -0
  171. package/dist/storage/index.js +4 -0
  172. package/dist/storage/index.js.map +1 -0
  173. package/dist/storage/indexeddb-adapter.d.ts +18 -0
  174. package/dist/storage/indexeddb-adapter.d.ts.map +1 -0
  175. package/dist/storage/indexeddb-adapter.js +232 -0
  176. package/dist/storage/indexeddb-adapter.js.map +1 -0
  177. package/dist/storage/project-manager.d.ts +35 -0
  178. package/dist/storage/project-manager.d.ts.map +1 -0
  179. package/dist/storage/project-manager.js +213 -0
  180. package/dist/storage/project-manager.js.map +1 -0
  181. package/dist/storage/types.d.ts +59 -0
  182. package/dist/storage/types.d.ts.map +1 -0
  183. package/dist/storage/types.js +2 -0
  184. package/dist/storage/types.js.map +1 -0
  185. package/dist/storage/zip-handler.d.ts +5 -0
  186. package/dist/storage/zip-handler.d.ts.map +1 -0
  187. package/dist/storage/zip-handler.js +200 -0
  188. package/dist/storage/zip-handler.js.map +1 -0
  189. package/dist/types/sandbox-types.d.ts +54 -0
  190. package/dist/types/sandbox-types.d.ts.map +1 -0
  191. package/dist/types/sandbox-types.js +2 -0
  192. package/dist/types/sandbox-types.js.map +1 -0
  193. package/dist/utils/__tests__/converters/auto-detect.test.d.ts +2 -0
  194. package/dist/utils/__tests__/converters/auto-detect.test.d.ts.map +1 -0
  195. package/dist/utils/__tests__/converters/auto-detect.test.js +381 -0
  196. package/dist/utils/__tests__/converters/auto-detect.test.js.map +1 -0
  197. package/dist/utils/__tests__/converters/codepen-converter.test.d.ts +2 -0
  198. package/dist/utils/__tests__/converters/codepen-converter.test.d.ts.map +1 -0
  199. package/dist/utils/__tests__/converters/codepen-converter.test.js +408 -0
  200. package/dist/utils/__tests__/converters/codepen-converter.test.js.map +1 -0
  201. package/dist/utils/__tests__/converters/gist-converter.test.d.ts +2 -0
  202. package/dist/utils/__tests__/converters/gist-converter.test.d.ts.map +1 -0
  203. package/dist/utils/__tests__/converters/gist-converter.test.js +458 -0
  204. package/dist/utils/__tests__/converters/gist-converter.test.js.map +1 -0
  205. package/dist/utils/__tests__/converters/html-parser.test.d.ts +2 -0
  206. package/dist/utils/__tests__/converters/html-parser.test.d.ts.map +1 -0
  207. package/dist/utils/__tests__/converters/html-parser.test.js +285 -0
  208. package/dist/utils/__tests__/converters/html-parser.test.js.map +1 -0
  209. package/dist/utils/__tests__/converters/sanitization.test.d.ts +2 -0
  210. package/dist/utils/__tests__/converters/sanitization.test.d.ts.map +1 -0
  211. package/dist/utils/__tests__/converters/sanitization.test.js +210 -0
  212. package/dist/utils/__tests__/converters/sanitization.test.js.map +1 -0
  213. package/dist/utils/auto-resize-script.d.ts +4 -0
  214. package/dist/utils/auto-resize-script.d.ts.map +1 -0
  215. package/dist/utils/auto-resize-script.js +125 -0
  216. package/dist/utils/auto-resize-script.js.map +1 -0
  217. package/dist/widgets/banner/BannerWidget.d.ts +15 -0
  218. package/dist/widgets/banner/BannerWidget.d.ts.map +1 -0
  219. package/dist/widgets/banner/BannerWidget.js +33 -0
  220. package/dist/widgets/banner/BannerWidget.js.map +1 -0
  221. package/dist/widgets/form/FormWidget.d.ts +23 -0
  222. package/dist/widgets/form/FormWidget.d.ts.map +1 -0
  223. package/dist/widgets/form/FormWidget.js +42 -0
  224. package/dist/widgets/form/FormWidget.js.map +1 -0
  225. package/dist/widgets/index.d.ts +8 -0
  226. package/dist/widgets/index.d.ts.map +1 -0
  227. package/dist/widgets/index.js +28 -0
  228. package/dist/widgets/index.js.map +1 -0
  229. package/dist/widgets/types.d.ts +28 -0
  230. package/dist/widgets/types.d.ts.map +1 -0
  231. package/dist/widgets/types.js +2 -0
  232. package/dist/widgets/types.js.map +1 -0
  233. package/package.json +116 -0
@@ -0,0 +1,285 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { extractHTMLParts, extractExternalLibraries } from '../../../converters/shared/html-parser';
3
+ describe('extractHTMLParts', () => {
4
+ describe('Complete HTML Documents', () => {
5
+ it('should extract HTML, CSS, and JS from complete document', () => {
6
+ const combined = `
7
+ <!DOCTYPE html>
8
+ <html lang="en">
9
+ <head>
10
+ <meta charset="UTF-8">
11
+ <style>
12
+ .demo {
13
+ color: blue;
14
+ padding: 20px;
15
+ }
16
+ </style>
17
+ </head>
18
+ <body>
19
+ <div class="demo">Hello World</div>
20
+ <script>
21
+ console.log("Hello from CodePen!");
22
+ </script>
23
+ </body>
24
+ </html>
25
+ `;
26
+ const result = extractHTMLParts(combined);
27
+ expect(result.html).toContain('Hello World');
28
+ expect(result.html).toContain('class="demo"');
29
+ expect(result.css).toContain('.demo');
30
+ expect(result.css).toContain('color: blue');
31
+ expect(result.js).toContain('console.log');
32
+ });
33
+ it('should handle multiple style tags', () => {
34
+ const html = `
35
+ <html>
36
+ <head>
37
+ <style>.one { color: red; }</style>
38
+ <style>.two { color: blue; }</style>
39
+ </head>
40
+ <body><div>Test</div></body>
41
+ </html>
42
+ `;
43
+ const result = extractHTMLParts(html);
44
+ expect(result.css).toContain('.one');
45
+ expect(result.css).toContain('.two');
46
+ });
47
+ it('should handle multiple script tags', () => {
48
+ const html = `
49
+ <html>
50
+ <body>
51
+ <div>Test</div>
52
+ <script>console.log("one");</script>
53
+ <script>console.log("two");</script>
54
+ </body>
55
+ </html>
56
+ `;
57
+ const result = extractHTMLParts(html);
58
+ expect(result.js).toContain('console.log("one")');
59
+ expect(result.js).toContain('console.log("two")');
60
+ });
61
+ it('should exclude external scripts', () => {
62
+ const html = `
63
+ <html>
64
+ <body>
65
+ <script src="https://cdn.example.com/lib.js"></script>
66
+ <script>console.log("inline");</script>
67
+ </body>
68
+ </html>
69
+ `;
70
+ const result = extractHTMLParts(html);
71
+ expect(result.js).toContain('console.log("inline")');
72
+ expect(result.js).not.toContain('cdn.example.com');
73
+ });
74
+ it('should remove style and script tags from HTML', () => {
75
+ const html = `
76
+ <html>
77
+ <head><style>.test {}</style></head>
78
+ <body>
79
+ <div>Content</div>
80
+ <script>console.log("test");</script>
81
+ </body>
82
+ </html>
83
+ `;
84
+ const result = extractHTMLParts(html);
85
+ expect(result.html).toContain('Content');
86
+ expect(result.html).not.toContain('<style>');
87
+ expect(result.html).not.toContain('<script>');
88
+ });
89
+ });
90
+ describe('HTML Fragments', () => {
91
+ it('should handle HTML without head/body', () => {
92
+ const fragment = '<div class="demo">Hello</div>';
93
+ const result = extractHTMLParts(fragment);
94
+ expect(result.html).toContain('Hello');
95
+ expect(result.css).toBe('');
96
+ expect(result.js).toBe('');
97
+ });
98
+ it('should handle HTML with inline styles', () => {
99
+ const html = `
100
+ <style>.demo { color: red; }</style>
101
+ <div class="demo">Styled</div>
102
+ `;
103
+ const result = extractHTMLParts(html);
104
+ expect(result.html).toContain('Styled');
105
+ expect(result.css).toContain('.demo');
106
+ expect(result.html).not.toContain('<style>');
107
+ });
108
+ it('should handle HTML with inline scripts', () => {
109
+ const html = `
110
+ <div>Content</div>
111
+ <script>alert("test");</script>
112
+ `;
113
+ const result = extractHTMLParts(html);
114
+ expect(result.html).toContain('Content');
115
+ expect(result.js).toContain('alert');
116
+ expect(result.html).not.toContain('<script>');
117
+ });
118
+ });
119
+ describe('Edge Cases', () => {
120
+ it('should handle empty string', () => {
121
+ const result = extractHTMLParts('');
122
+ expect(result.css).toBe('');
123
+ expect(result.js).toBe('');
124
+ });
125
+ it('should handle whitespace only', () => {
126
+ const result = extractHTMLParts(' \n\t ');
127
+ expect(result.css).toBe('');
128
+ expect(result.js).toBe('');
129
+ });
130
+ it('should handle document without body', () => {
131
+ const html = `
132
+ <!DOCTYPE html>
133
+ <html>
134
+ <head>
135
+ <style>.test {}</style>
136
+ </head>
137
+ </html>
138
+ `;
139
+ const result = extractHTMLParts(html);
140
+ expect(result.css).toContain('.test');
141
+ });
142
+ it('should handle nested structures', () => {
143
+ const html = `
144
+ <html>
145
+ <body>
146
+ <div>
147
+ <div>
148
+ <style>.nested {}</style>
149
+ <span>Nested content</span>
150
+ <script>console.log("nested");</script>
151
+ </div>
152
+ </div>
153
+ </body>
154
+ </html>
155
+ `;
156
+ const result = extractHTMLParts(html);
157
+ expect(result.html).toContain('Nested content');
158
+ expect(result.css).toContain('.nested');
159
+ expect(result.js).toContain('console.log');
160
+ });
161
+ });
162
+ describe('Real-World Examples', () => {
163
+ it('should handle typical CodePen export', () => {
164
+ const codepen = `
165
+ <!DOCTYPE html>
166
+ <html lang="en">
167
+ <head>
168
+ <meta charset="UTF-8">
169
+ <title>My Pen</title>
170
+ <style>
171
+ body {
172
+ font-family: Arial, sans-serif;
173
+ padding: 20px;
174
+ }
175
+ .container {
176
+ max-width: 600px;
177
+ margin: 0 auto;
178
+ }
179
+ </style>
180
+ </head>
181
+ <body>
182
+ <div class="container">
183
+ <h1>Hello CodePen</h1>
184
+ <p>This is a demo</p>
185
+ </div>
186
+ <script>
187
+ document.querySelector('h1').addEventListener('click', function() {
188
+ alert('Clicked!');
189
+ });
190
+ </script>
191
+ </body>
192
+ </html>
193
+ `;
194
+ const result = extractHTMLParts(codepen);
195
+ expect(result.html).toContain('Hello CodePen');
196
+ expect(result.css).toContain('font-family');
197
+ expect(result.css).toContain('.container');
198
+ expect(result.js).toContain('addEventListener');
199
+ });
200
+ it('should handle v0.dev style export', () => {
201
+ const v0 = `
202
+ <style>
203
+ .card {
204
+ border: 1px solid #e5e7eb;
205
+ border-radius: 8px;
206
+ padding: 16px;
207
+ }
208
+ </style>
209
+ <div class="card">
210
+ <h2>Card Title</h2>
211
+ <p>Card content goes here.</p>
212
+ </div>
213
+ `;
214
+ const result = extractHTMLParts(v0);
215
+ expect(result.html).toContain('Card Title');
216
+ expect(result.css).toContain('.card');
217
+ });
218
+ });
219
+ });
220
+ describe('extractExternalLibraries', () => {
221
+ it('should extract script src URLs', () => {
222
+ const html = `
223
+ <script src="https://cdn.tailwindcss.com"></script>
224
+ <script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
225
+ <script>console.log("inline");</script>
226
+ `;
227
+ const libs = extractExternalLibraries(html);
228
+ expect(libs).toHaveLength(2);
229
+ expect(libs).toContain('https://cdn.tailwindcss.com');
230
+ expect(libs).toContain('https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js');
231
+ });
232
+ it('should extract stylesheet href URLs', () => {
233
+ const html = `
234
+ <link rel="stylesheet" href="https://cdn.example.com/style.css">
235
+ <link rel="icon" href="favicon.ico">
236
+ `;
237
+ const libs = extractExternalLibraries(html);
238
+ expect(libs).toHaveLength(1);
239
+ expect(libs).toContain('https://cdn.example.com/style.css');
240
+ });
241
+ it('should extract both scripts and stylesheets', () => {
242
+ const html = `
243
+ <link rel="stylesheet" href="https://cdn.example.com/style.css">
244
+ <script src="https://cdn.example.com/script.js"></script>
245
+ `;
246
+ const libs = extractExternalLibraries(html);
247
+ expect(libs).toHaveLength(2);
248
+ expect(libs).toContain('https://cdn.example.com/style.css');
249
+ expect(libs).toContain('https://cdn.example.com/script.js');
250
+ });
251
+ it('should ignore relative URLs', () => {
252
+ const html = `
253
+ <script src="/local/script.js"></script>
254
+ <script src="./relative.js"></script>
255
+ <link rel="stylesheet" href="../styles.css">
256
+ `;
257
+ const libs = extractExternalLibraries(html);
258
+ expect(libs).toHaveLength(0);
259
+ });
260
+ it('should handle empty document', () => {
261
+ const libs = extractExternalLibraries('');
262
+ expect(libs).toHaveLength(0);
263
+ });
264
+ it('should handle document without external resources', () => {
265
+ const html = `
266
+ <html>
267
+ <body>
268
+ <div>No external resources</div>
269
+ </body>
270
+ </html>
271
+ `;
272
+ const libs = extractExternalLibraries(html);
273
+ expect(libs).toHaveLength(0);
274
+ });
275
+ it('should handle HTTP and HTTPS URLs', () => {
276
+ const html = `
277
+ <script src="http://cdn.example.com/old.js"></script>
278
+ <script src="https://cdn.example.com/new.js"></script>
279
+ `;
280
+ const libs = extractExternalLibraries(html);
281
+ expect(libs).toHaveLength(2);
282
+ expect(libs[0]).toMatch(/^https?:\/\//);
283
+ });
284
+ });
285
+ //# sourceMappingURL=html-parser.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html-parser.test.js","sourceRoot":"","sources":["../../../../src/utils/__tests__/converters/html-parser.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sanitization.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitization.test.d.ts","sourceRoot":"","sources":["../../../../src/utils/__tests__/converters/sanitization.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,210 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { sanitizeHTML, sanitizeCSS, sanitizeJS } from '../../../converters/shared/sanitization';
3
+ describe('sanitizeHTML', () => {
4
+ describe('XSS Prevention', () => {
5
+ it('should remove script tags', () => {
6
+ const malicious = '<script>alert("xss")</script><div>Safe</div>';
7
+ const result = sanitizeHTML(malicious);
8
+ expect(result.clean).not.toContain('script');
9
+ expect(result.clean).not.toContain('alert');
10
+ expect(result.modified).toBe(true);
11
+ });
12
+ it('should remove event handlers', () => {
13
+ const malicious = '<div onclick="alert(\'xss\')">Click me</div>';
14
+ const result = sanitizeHTML(malicious);
15
+ expect(result.clean).not.toContain('onclick');
16
+ expect(result.modified).toBe(true);
17
+ });
18
+ it('should remove javascript: URIs', () => {
19
+ const malicious = '<a href="javascript:alert(\'xss\')">Link</a>';
20
+ const result = sanitizeHTML(malicious);
21
+ expect(result.clean).not.toContain('javascript:');
22
+ expect(result.modified).toBe(true);
23
+ });
24
+ it('should remove iframe with javascript src', () => {
25
+ const malicious = '<iframe src="javascript:alert(1)"></iframe>';
26
+ const result = sanitizeHTML(malicious);
27
+ expect(result.clean).not.toContain('iframe');
28
+ expect(result.modified).toBe(true);
29
+ });
30
+ it('should remove svg with onload handler', () => {
31
+ const malicious = '<svg/onload=alert(1)>';
32
+ const result = sanitizeHTML(malicious);
33
+ expect(result.clean).not.toContain('onload');
34
+ expect(result.modified).toBe(true);
35
+ });
36
+ it('should remove img with onerror handler', () => {
37
+ const malicious = '<img src=x onerror="alert(1)">';
38
+ const result = sanitizeHTML(malicious);
39
+ expect(result.clean).not.toContain('onerror');
40
+ expect(result.modified).toBe(true);
41
+ });
42
+ });
43
+ describe('Safe Content', () => {
44
+ it('should allow safe HTML', () => {
45
+ const safe = '<div class="demo"><h1>Hello</h1><p>World</p></div>';
46
+ const result = sanitizeHTML(safe);
47
+ expect(result.clean).toBe(safe);
48
+ expect(result.modified).toBe(false);
49
+ expect(result.removed).toHaveLength(0);
50
+ });
51
+ it('should allow safe styles', () => {
52
+ const safe = '<div style="color: red; padding: 10px;">Styled</div>';
53
+ const result = sanitizeHTML(safe);
54
+ expect(result.clean).toContain('style=');
55
+ expect(result.clean).toContain('color');
56
+ expect(result.modified).toBe(false);
57
+ });
58
+ it('should allow data attributes', () => {
59
+ const safe = '<div data-id="123" data-name="test">Data</div>';
60
+ const result = sanitizeHTML(safe);
61
+ expect(result.clean).toContain('data-id');
62
+ expect(result.clean).toContain('data-name');
63
+ expect(result.modified).toBe(false);
64
+ });
65
+ it('should allow ARIA attributes', () => {
66
+ const safe = '<button aria-label="Close" aria-hidden="false">×</button>';
67
+ const result = sanitizeHTML(safe);
68
+ expect(result.clean).toContain('aria-label');
69
+ expect(result.clean).toContain('aria-hidden');
70
+ expect(result.modified).toBe(false);
71
+ });
72
+ it('should allow safe SVG', () => {
73
+ const safe = '<svg viewBox="0 0 100 100"><circle cx="50" cy="50" r="40" fill="blue"/></svg>';
74
+ const result = sanitizeHTML(safe);
75
+ expect(result.clean).toContain('svg');
76
+ expect(result.clean).toContain('circle');
77
+ });
78
+ });
79
+ describe('Size Limits', () => {
80
+ it('should enforce default size limits', () => {
81
+ const huge = '<div>' + 'x'.repeat(2 * 1024 * 1024) + '</div>';
82
+ expect(() => sanitizeHTML(huge)).toThrow('exceeds maximum size');
83
+ });
84
+ it('should allow custom size limits', () => {
85
+ const small = '<div>' + 'x'.repeat(100) + '</div>';
86
+ expect(() => sanitizeHTML(small, { maxSize: 50 })).toThrow('exceeds maximum size');
87
+ });
88
+ it('should pass when under limit', () => {
89
+ const small = '<div>Hello</div>';
90
+ const result = sanitizeHTML(small, { maxSize: 100 });
91
+ expect(result.clean).toBe(small);
92
+ });
93
+ });
94
+ describe('Custom Whitelists', () => {
95
+ it('should allow custom tags', () => {
96
+ const html = '<div><custom-element>Test</custom-element></div>';
97
+ const result = sanitizeHTML(html, {
98
+ allowedTags: ['div', 'custom-element'],
99
+ });
100
+ expect(result.clean).toContain('custom-element');
101
+ });
102
+ it('should remove non-whitelisted tags', () => {
103
+ const html = '<div><span>Test</span></div>';
104
+ const result = sanitizeHTML(html, {
105
+ allowedTags: ['div'],
106
+ });
107
+ expect(result.clean).not.toContain('span');
108
+ expect(result.modified).toBe(true);
109
+ });
110
+ it('should allow custom attributes', () => {
111
+ const html = '<div custom-attr="value">Test</div>';
112
+ const result = sanitizeHTML(html, {
113
+ allowedAttributes: ['custom-attr'],
114
+ });
115
+ expect(result.clean).toContain('custom-attr');
116
+ });
117
+ });
118
+ describe('Edge Cases', () => {
119
+ it('should handle empty string', () => {
120
+ const result = sanitizeHTML('');
121
+ expect(result.clean).toBe('');
122
+ expect(result.modified).toBe(false);
123
+ });
124
+ it('should handle whitespace only', () => {
125
+ const result = sanitizeHTML(' \n\t ');
126
+ expect(result.clean.trim()).toBe('');
127
+ });
128
+ it('should handle plain text', () => {
129
+ const text = 'Hello, world!';
130
+ const result = sanitizeHTML(text);
131
+ expect(result.clean).toBe(text);
132
+ expect(result.modified).toBe(false);
133
+ });
134
+ it('should handle malformed HTML', () => {
135
+ const malformed = '<div><p>Unclosed paragraph<div>Nested wrong</div>';
136
+ const result = sanitizeHTML(malformed);
137
+ expect(result.clean).toBeTruthy();
138
+ });
139
+ });
140
+ describe('Complex XSS Vectors', () => {
141
+ it('should block all common XSS vectors', () => {
142
+ const xssVectors = [
143
+ '<script>alert("xss")</script>',
144
+ '<img src=x onerror="alert(1)">',
145
+ '<div onclick="alert(1)">Click</div>',
146
+ '<iframe src="javascript:alert(1)">',
147
+ '<svg/onload=alert(1)>',
148
+ '<body onload=alert(1)>',
149
+ '<input onfocus=alert(1) autofocus>',
150
+ '<select onfocus=alert(1) autofocus>',
151
+ '<textarea onfocus=alert(1) autofocus>',
152
+ '<marquee onstart=alert(1)>',
153
+ ];
154
+ xssVectors.forEach((vector) => {
155
+ const result = sanitizeHTML(vector);
156
+ expect(result.clean).not.toContain('alert');
157
+ expect(result.modified).toBe(true);
158
+ });
159
+ });
160
+ });
161
+ });
162
+ describe('sanitizeCSS', () => {
163
+ it('should enforce size limits', () => {
164
+ const huge = 'body { color: red; }' + ' '.repeat(600 * 1024);
165
+ expect(() => sanitizeCSS(huge)).toThrow('exceeds maximum size');
166
+ });
167
+ it('should pass through valid CSS', () => {
168
+ const css = '.demo { color: red; padding: 10px; }';
169
+ expect(sanitizeCSS(css)).toBe(css);
170
+ });
171
+ it('should allow empty CSS', () => {
172
+ expect(sanitizeCSS('')).toBe('');
173
+ });
174
+ it('should allow complex CSS', () => {
175
+ const css = `
176
+ @keyframes slide {
177
+ from { transform: translateX(0); }
178
+ to { transform: translateX(100px); }
179
+ }
180
+ .animated {
181
+ animation: slide 1s ease-in-out;
182
+ }
183
+ `;
184
+ expect(sanitizeCSS(css)).toBe(css);
185
+ });
186
+ });
187
+ describe('sanitizeJS', () => {
188
+ it('should enforce size limits', () => {
189
+ const huge = 'console.log("test");' + ' '.repeat(600 * 1024);
190
+ expect(() => sanitizeJS(huge)).toThrow('exceeds maximum size');
191
+ });
192
+ it('should pass through valid JavaScript', () => {
193
+ const js = 'console.log("Hello, world!");';
194
+ expect(sanitizeJS(js)).toBe(js);
195
+ });
196
+ it('should allow empty JavaScript', () => {
197
+ expect(sanitizeJS('')).toBe('');
198
+ });
199
+ it('should allow complex JavaScript', () => {
200
+ const js = `
201
+ function fibonacci(n) {
202
+ if (n <= 1) return n;
203
+ return fibonacci(n - 1) + fibonacci(n - 2);
204
+ }
205
+ console.log(fibonacci(10));
206
+ `;
207
+ expect(sanitizeJS(js)).toBe(js);
208
+ });
209
+ });
210
+ //# sourceMappingURL=sanitization.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitization.test.js","sourceRoot":"","sources":["../../../../src/utils/__tests__/converters/sanitization.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function generateAutoResizeScript(maxHeight: number, debounceMs?: number): string;
2
+ export declare const DEFAULT_DEBOUNCE_MS = 100;
3
+ export declare const DEFAULT_MAX_HEIGHT = 1200;
4
+ //# sourceMappingURL=auto-resize-script.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-resize-script.d.ts","sourceRoot":"","sources":["../../src/utils/auto-resize-script.ts"],"names":[],"mappings":"AAqBA,wBAAgB,wBAAwB,CACvC,SAAS,EAAE,MAAM,EACjB,UAAU,SAAM,GACd,MAAM,CAyHR;AAKD,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAKvC,eAAO,MAAM,kBAAkB,OAAO,CAAC"}
@@ -0,0 +1,125 @@
1
+ export function generateAutoResizeScript(maxHeight, debounceMs = 100) {
2
+ return `
3
+ (function() {
4
+ 'use strict';
5
+
6
+ let debounceTimer = null;
7
+ let lastHeight = 0;
8
+
9
+ /**
10
+ * Debounced function to send height update to parent
11
+ */
12
+ function sendHeight() {
13
+ // Clear existing timer
14
+ if (debounceTimer) {
15
+ clearTimeout(debounceTimer);
16
+ }
17
+
18
+ debounceTimer = setTimeout(() => {
19
+ try {
20
+ // Get full document height
21
+ const body = document.body;
22
+ const html = document.documentElement;
23
+
24
+ const height = Math.max(
25
+ body.scrollHeight,
26
+ body.offsetHeight,
27
+ html.clientHeight,
28
+ html.scrollHeight,
29
+ html.offsetHeight
30
+ );
31
+
32
+ // Only send if height changed
33
+ if (height !== lastHeight) {
34
+ lastHeight = height;
35
+
36
+ // Cap at maxHeight
37
+ const cappedHeight = Math.min(height, ${maxHeight});
38
+
39
+ // Send to parent window
40
+ // Note: target origin is '*' because srcdoc has null origin
41
+ parent.postMessage({
42
+ type: 'resize',
43
+ height: cappedHeight,
44
+ timestamp: Date.now()
45
+ }, '*');
46
+ }
47
+ } catch (error) {
48
+ // Send error to parent
49
+ parent.postMessage({
50
+ type: 'error',
51
+ message: 'Auto-resize failed: ' + error.message,
52
+ timestamp: Date.now()
53
+ }, '*');
54
+ }
55
+ }, ${debounceMs});
56
+ }
57
+
58
+ /**
59
+ * Initialize ResizeObserver
60
+ */
61
+ function init() {
62
+ try {
63
+ // Send ready message
64
+ parent.postMessage({
65
+ type: 'ready',
66
+ timestamp: Date.now()
67
+ }, '*');
68
+
69
+ // Initial height calculation
70
+ sendHeight();
71
+
72
+ // Watch for size changes with ResizeObserver
73
+ if (typeof ResizeObserver !== 'undefined') {
74
+ const observer = new ResizeObserver(() => {
75
+ sendHeight();
76
+ });
77
+
78
+ // Observe body element
79
+ observer.observe(document.body);
80
+
81
+ // Also observe documentElement for edge cases
82
+ observer.observe(document.documentElement);
83
+ } else {
84
+ // Fallback: poll for height changes
85
+ setInterval(sendHeight, 500);
86
+ }
87
+
88
+ // Also listen for load events
89
+ window.addEventListener('load', sendHeight);
90
+ window.addEventListener('resize', sendHeight);
91
+
92
+ // Listen for dynamic content changes
93
+ if (typeof MutationObserver !== 'undefined') {
94
+ const mutationObserver = new MutationObserver(() => {
95
+ sendHeight();
96
+ });
97
+
98
+ mutationObserver.observe(document.body, {
99
+ childList: true,
100
+ subtree: true,
101
+ attributes: true,
102
+ characterData: true
103
+ });
104
+ }
105
+ } catch (error) {
106
+ parent.postMessage({
107
+ type: 'error',
108
+ message: 'Auto-resize init failed: ' + error.message,
109
+ timestamp: Date.now()
110
+ }, '*');
111
+ }
112
+ }
113
+
114
+ // Initialize when DOM is ready
115
+ if (document.readyState === 'loading') {
116
+ document.addEventListener('DOMContentLoaded', init);
117
+ } else {
118
+ init();
119
+ }
120
+ })();
121
+ `;
122
+ }
123
+ export const DEFAULT_DEBOUNCE_MS = 100;
124
+ export const DEFAULT_MAX_HEIGHT = 1200;
125
+ //# sourceMappingURL=auto-resize-script.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-resize-script.js","sourceRoot":"","sources":["../../src/utils/auto-resize-script.ts"],"names":[],"mappings":"AAqBA,MAAM,UAAU,wBAAwB,CACvC,SAAiB,EACjB,UAAU,GAAG,GAAG;IAEhB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kDAmC0C,SAAS;;;;;;;;;;;;;;;;;;SAkBlD,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkElB,CAAC;AACF,CAAC;AAKD,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAKvC,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC"}