test: added testing via a browser (puppeteer)

This commit is contained in:
Miel Truyen 2023-12-03 10:42:51 +01:00
parent 2adfbee74b
commit e96c2248ee
27 changed files with 1281 additions and 123 deletions

View File

@ -66,6 +66,7 @@
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-typescript": "^11.1.5",
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-url": "^8.0.2",
"@types/node": "^18.18.12",
"ava": "^5.3.1",
@ -81,7 +82,11 @@
"rollup-plugin-postcss": "^4.0.2",
"tslib": "^2.6.2",
"tsx": "^4.4.0",
"typescript": "^5.3.2"
"typescript": "^5.3.2",
"puppeteer": "^21.5.2",
"mime": "^4.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"types": "./types/index.d.ts",
"ava": {

618
pnpm-lock.yaml generated
View File

@ -31,6 +31,9 @@ devDependencies:
'@rollup/plugin-node-resolve':
specifier: ^15.2.3
version: 15.2.3(rollup@3.29.4)
'@rollup/plugin-terser':
specifier: ^0.4.4
version: 0.4.4(rollup@3.29.4)
'@rollup/plugin-typescript':
specifier: ^11.1.5
version: 11.1.5(rollup@3.29.4)(tslib@2.6.2)(typescript@5.3.2)
@ -55,12 +58,24 @@ devDependencies:
lint-staged:
specifier: ^13.3.0
version: 13.3.0
mime:
specifier: ^4.0.0
version: 4.0.0
nyc:
specifier: ^15.1.0
version: 15.1.0
postcss:
specifier: ^8.4.31
version: 8.4.31
puppeteer:
specifier: ^21.5.2
version: 21.5.2(typescript@5.3.2)
react:
specifier: ^18.2.0
version: 18.2.0
react-dom:
specifier: ^18.2.0
version: 18.2.0(react@18.2.0)
rollup:
specifier: ^3.29.4
version: 3.29.4
@ -649,6 +664,13 @@ packages:
engines: {node: '>=6.0.0'}
dev: true
/@jridgewell/source-map@0.3.5:
resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==}
dependencies:
'@jridgewell/gen-mapping': 0.3.3
'@jridgewell/trace-mapping': 0.3.20
dev: true
/@jridgewell/sourcemap-codec@1.4.15:
resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
@ -680,6 +702,22 @@ packages:
fastq: 1.15.0
dev: true
/@puppeteer/browsers@1.8.0:
resolution: {integrity: sha512-TkRHIV6k2D8OlUe8RtG+5jgOF/H98Myx0M6AOafC8DdNVOFiBSFa5cpRDtpm8LXOa9sVwe0+e6Q3FC56X/DZfg==}
engines: {node: '>=16.3.0'}
hasBin: true
dependencies:
debug: 4.3.4
extract-zip: 2.0.1
progress: 2.0.3
proxy-agent: 6.3.1
tar-fs: 3.0.4
unbzip2-stream: 1.4.3
yargs: 17.7.2
transitivePeerDependencies:
- supports-color
dev: true
/@rollup/plugin-babel@6.0.4(@babel/core@7.23.3)(rollup@3.29.4):
resolution: {integrity: sha512-YF7Y52kFdFT/xVSuVdjkV5ZdX/3YtmX0QulG+x0taQOtJdHYzVU61aSSkAgVJ7NOv6qPkIYiJSgSWWN/DM5sGw==}
engines: {node: '>=14.0.0'}
@ -717,6 +755,21 @@ packages:
rollup: 3.29.4
dev: true
/@rollup/plugin-terser@0.4.4(rollup@3.29.4):
resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==}
engines: {node: '>=14.0.0'}
peerDependencies:
rollup: ^2.0.0||^3.0.0||^4.0.0
peerDependenciesMeta:
rollup:
optional: true
dependencies:
rollup: 3.29.4
serialize-javascript: 6.0.1
smob: 1.4.1
terser: 5.24.0
dev: true
/@rollup/plugin-typescript@11.1.5(rollup@3.29.4)(tslib@2.6.2)(typescript@5.3.2):
resolution: {integrity: sha512-rnMHrGBB0IUEv69Q8/JGRD/n4/n6b3nfpufUu26axhUcboUzv/twfZU8fIBbTOphRAe0v8EyxzeDpKXqGHfyDA==}
engines: {node: '>=14.0.0'}
@ -766,6 +819,10 @@ packages:
picomatch: 2.3.1
rollup: 3.29.4
/@tootallnate/quickjs-emscripten@0.23.0:
resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==}
dev: true
/@trysound/sax@0.2.0:
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
engines: {node: '>=10.13.0'}
@ -803,6 +860,14 @@ packages:
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
dev: true
/@types/yauzl@2.10.3:
resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
requiresBuild: true
dependencies:
'@types/node': 18.18.12
dev: true
optional: true
/acorn-walk@8.3.0:
resolution: {integrity: sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==}
engines: {node: '>=0.4.0'}
@ -814,6 +879,15 @@ packages:
hasBin: true
dev: true
/agent-base@7.1.0:
resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==}
engines: {node: '>= 14'}
dependencies:
debug: 4.3.4
transitivePeerDependencies:
- supports-color
dev: true
/aggregate-error@3.1.0:
resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
engines: {node: '>=8'}
@ -891,6 +965,10 @@ packages:
sprintf-js: 1.0.3
dev: true
/argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
dev: true
/array-find-index@1.0.2:
resolution: {integrity: sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==}
engines: {node: '>=0.10.0'}
@ -916,6 +994,13 @@ packages:
engines: {node: '>=12'}
dev: true
/ast-types@0.13.4:
resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==}
engines: {node: '>=4'}
dependencies:
tslib: 2.6.2
dev: true
/ava@5.3.1:
resolution: {integrity: sha512-Scv9a4gMOXB6+ni4toLuhAm9KYWEjsgBglJl+kMGI5+IVDt120CCDZyB5HNU9DjmLI2t4I0GbnxGLmmRfGTJGg==}
engines: {node: '>=14.19 <15 || >=16.15 <17 || >=18'}
@ -973,10 +1058,23 @@ packages:
- supports-color
dev: true
/b4a@1.6.4:
resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==}
dev: true
/balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
dev: true
/base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
dev: true
/basic-ftp@5.0.3:
resolution: {integrity: sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g==}
engines: {node: '>=10.0.0'}
dev: true
/binary-extensions@2.2.0:
resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==}
engines: {node: '>=8'}
@ -1015,6 +1113,21 @@ packages:
update-browserslist-db: 1.0.13(browserslist@4.22.1)
dev: true
/buffer-crc32@0.2.13:
resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==}
dev: true
/buffer-from@1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
dev: true
/buffer@5.7.1:
resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
dependencies:
base64-js: 1.5.1
ieee754: 1.2.1
dev: true
/builtin-modules@3.3.0:
resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==}
engines: {node: '>=6'}
@ -1030,6 +1143,11 @@ packages:
write-file-atomic: 3.0.3
dev: true
/callsites@3.1.0:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'}
dev: true
/callsites@4.1.0:
resolution: {integrity: sha512-aBMbD1Xxay75ViYezwT40aQONfr+pSXTHwNKvIXhXD6+LY3F1dLIcceoC5OZKBVHbXcysz1hL9D2w0JJIMXpUw==}
engines: {node: '>=12.20'}
@ -1112,6 +1230,16 @@ packages:
fsevents: 2.3.3
dev: true
/chromium-bidi@0.4.33(devtools-protocol@0.0.1203626):
resolution: {integrity: sha512-IxoFM5WGQOIAd95qrSXzJUv4eXIrh+RvU3rwwqIiwYuvfE7U/Llj4fejbsJnjJMUYCuGtVQsY2gv7oGl4aTNSQ==}
peerDependencies:
devtools-protocol: '*'
dependencies:
devtools-protocol: 0.0.1203626
mitt: 3.0.1
urlpattern-polyfill: 9.0.0
dev: true
/chunkd@2.0.1:
resolution: {integrity: sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==}
dev: true
@ -1215,6 +1343,10 @@ packages:
engines: {node: '>=16'}
dev: true
/commander@2.20.3:
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
dev: true
/commander@7.2.0:
resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
engines: {node: '>= 10'}
@ -1265,6 +1397,30 @@ packages:
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
dev: true
/cosmiconfig@8.3.6(typescript@5.3.2):
resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==}
engines: {node: '>=14'}
peerDependencies:
typescript: '>=4.9.5'
peerDependenciesMeta:
typescript:
optional: true
dependencies:
import-fresh: 3.3.0
js-yaml: 4.1.0
parse-json: 5.2.0
path-type: 4.0.0
typescript: 5.3.2
dev: true
/cross-fetch@4.0.0:
resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==}
dependencies:
node-fetch: 2.7.0
transitivePeerDependencies:
- encoding
dev: true
/cross-spawn@7.0.3:
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
engines: {node: '>= 8'}
@ -1385,6 +1541,11 @@ packages:
array-find-index: 1.0.2
dev: true
/data-uri-to-buffer@6.0.1:
resolution: {integrity: sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==}
engines: {node: '>= 14'}
dev: true
/date-time@3.1.0:
resolution: {integrity: sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==}
engines: {node: '>=6'}
@ -1434,6 +1595,15 @@ packages:
strip-bom: 4.0.0
dev: true
/degenerator@5.0.1:
resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==}
engines: {node: '>= 14'}
dependencies:
ast-types: 0.13.4
escodegen: 2.1.0
esprima: 4.0.1
dev: true
/del-cli@5.1.0:
resolution: {integrity: sha512-xwMeh2acluWeccsfzE7VLsG3yTr7nWikbfw+xhMnpRrF15pGSkw+3/vJZWlGoE4I86UiLRNHicmKt4tkIX9Jtg==}
engines: {node: '>=14.16'}
@ -1471,6 +1641,10 @@ packages:
slash: 4.0.0
dev: true
/devtools-protocol@0.0.1203626:
resolution: {integrity: sha512-nEzHZteIUZfGCZtTiS1fRpC8UZmsfD1SiyPvaUNvS13dvKf666OAm8YTi0+Ca3n1nLEyu49Cy4+dPWpaHFJk9g==}
dev: true
/dir-glob@3.0.1:
resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
engines: {node: '>=8'}
@ -1526,6 +1700,12 @@ packages:
resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
dev: true
/end-of-stream@1.4.4:
resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==}
dependencies:
once: 1.4.0
dev: true
/entities@2.2.0:
resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==}
dev: true
@ -1595,12 +1775,29 @@ packages:
engines: {node: '>=12'}
dev: true
/escodegen@2.1.0:
resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==}
engines: {node: '>=6.0'}
hasBin: true
dependencies:
esprima: 4.0.1
estraverse: 5.3.0
esutils: 2.0.3
optionalDependencies:
source-map: 0.6.1
dev: true
/esprima@4.0.1:
resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
engines: {node: '>=4'}
hasBin: true
dev: true
/estraverse@5.3.0:
resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==}
engines: {node: '>=4.0'}
dev: true
/estree-walker@0.6.1:
resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==}
dev: true
@ -1636,10 +1833,28 @@ packages:
strip-final-newline: 3.0.0
dev: true
/extract-zip@2.0.1:
resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==}
engines: {node: '>= 10.17.0'}
hasBin: true
dependencies:
debug: 4.3.4
get-stream: 5.2.0
yauzl: 2.10.0
optionalDependencies:
'@types/yauzl': 2.10.3
transitivePeerDependencies:
- supports-color
dev: true
/fast-diff@1.3.0:
resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==}
dev: true
/fast-fifo@1.3.2:
resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==}
dev: true
/fast-glob@3.3.2:
resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
engines: {node: '>=8.6.0'}
@ -1657,6 +1872,12 @@ packages:
reusify: 1.0.4
dev: true
/fd-slicer@1.1.0:
resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==}
dependencies:
pend: 1.2.0
dev: true
/figures@5.0.0:
resolution: {integrity: sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==}
engines: {node: '>=14'}
@ -1717,6 +1938,15 @@ packages:
resolution: {integrity: sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==}
dev: true
/fs-extra@8.1.0:
resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==}
engines: {node: '>=6 <7 || >=8'}
dependencies:
graceful-fs: 4.2.11
jsonfile: 4.0.0
universalify: 0.1.2
dev: true
/fs.realpath@1.0.0:
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
dev: true
@ -1753,6 +1983,13 @@ packages:
engines: {node: '>=8.0.0'}
dev: true
/get-stream@5.2.0:
resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==}
engines: {node: '>=8'}
dependencies:
pump: 3.0.0
dev: true
/get-stream@6.0.1:
resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==}
engines: {node: '>=10'}
@ -1764,6 +2001,18 @@ packages:
resolve-pkg-maps: 1.0.0
dev: true
/get-uri@6.0.2:
resolution: {integrity: sha512-5KLucCJobh8vBY1K07EFV4+cPZH3mrV9YeAruUseCQKHB58SGjjT2l9/eA9LD082IiuMjSlFJEcdJ27TXvbZNw==}
engines: {node: '>= 14'}
dependencies:
basic-ftp: 5.0.3
data-uri-to-buffer: 6.0.1
debug: 4.3.4
fs-extra: 8.1.0
transitivePeerDependencies:
- supports-color
dev: true
/glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
@ -1870,6 +2119,26 @@ packages:
resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==}
dev: true
/http-proxy-agent@7.0.0:
resolution: {integrity: sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==}
engines: {node: '>= 14'}
dependencies:
agent-base: 7.1.0
debug: 4.3.4
transitivePeerDependencies:
- supports-color
dev: true
/https-proxy-agent@7.0.2:
resolution: {integrity: sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==}
engines: {node: '>= 14'}
dependencies:
agent-base: 7.1.0
debug: 4.3.4
transitivePeerDependencies:
- supports-color
dev: true
/human-signals@4.3.1:
resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==}
engines: {node: '>=14.18.0'}
@ -1888,6 +2157,10 @@ packages:
postcss: 8.4.31
dev: true
/ieee754@1.2.1:
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
dev: true
/ignore-by-default@2.1.0:
resolution: {integrity: sha512-yiWd4GVmJp0Q6ghmM2B/V3oZGRmjrKLXvHR3TE1nfoXsmoggllfZUQe74EN0fJdPFZu2NIvNdrMMLm3OsV7Ohw==}
engines: {node: '>=10 <11 || >=12 <13 || >=14'}
@ -1905,6 +2178,14 @@ packages:
import-from: 3.0.0
dev: true
/import-fresh@3.3.0:
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
engines: {node: '>=6'}
dependencies:
parent-module: 1.0.1
resolve-from: 4.0.0
dev: true
/import-from@3.0.0:
resolution: {integrity: sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ==}
engines: {node: '>=8'}
@ -1938,6 +2219,14 @@ packages:
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
dev: true
/ip@1.1.8:
resolution: {integrity: sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==}
dev: true
/ip@2.0.0:
resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==}
dev: true
/irregular-plurals@3.5.0:
resolution: {integrity: sha512-1ANGLZ+Nkv1ptFb2pa8oG8Lem4krflKuX/gINiHJHjJUKaJHk/SXk5x6K3J+39/p0h1RQ2saROclJJ+QLvETCQ==}
engines: {node: '>=8'}
@ -2145,6 +2434,13 @@ packages:
esprima: 4.0.1
dev: true
/js-yaml@4.1.0:
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
hasBin: true
dependencies:
argparse: 2.0.1
dev: true
/jsesc@2.5.2:
resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==}
engines: {node: '>=4'}
@ -2161,6 +2457,12 @@ packages:
hasBin: true
dev: true
/jsonfile@4.0.0:
resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==}
optionalDependencies:
graceful-fs: 4.2.11
dev: true
/kind-of@6.0.3:
resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
engines: {node: '>=0.10.0'}
@ -2292,6 +2594,13 @@ packages:
wrap-ansi: 8.1.0
dev: true
/loose-envify@1.4.0:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
dependencies:
js-tokens: 4.0.0
dev: true
/lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
dependencies:
@ -2305,6 +2614,11 @@ packages:
yallist: 4.0.0
dev: true
/lru-cache@7.18.3:
resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==}
engines: {node: '>=12'}
dev: true
/magic-string@0.30.5:
resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==}
engines: {node: '>=12'}
@ -2410,6 +2724,12 @@ packages:
hasBin: true
dev: true
/mime@4.0.0:
resolution: {integrity: sha512-pzhgdeqU5pJ9t5WK9m4RT4GgGWqYJylxUf62Yb9datXRwdcw5MjiD1BYI5evF8AgTXN9gtKX3CFLvCUL5fAhEA==}
engines: {node: '>=16'}
hasBin: true
dev: true
/mimic-fn@2.1.0:
resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==}
engines: {node: '>=6'}
@ -2444,6 +2764,14 @@ packages:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
dev: true
/mitt@3.0.1:
resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==}
dev: true
/mkdirp-classic@0.5.3:
resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
dev: true
/ms@2.1.2:
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
dev: true
@ -2462,6 +2790,23 @@ packages:
resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==}
dev: true
/netmask@2.0.2:
resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==}
engines: {node: '>= 0.4.0'}
dev: true
/node-fetch@2.7.0:
resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
engines: {node: 4.x || >=6.0.0}
peerDependencies:
encoding: ^0.1.0
peerDependenciesMeta:
encoding:
optional: true
dependencies:
whatwg-url: 5.0.0
dev: true
/node-preload@0.2.1:
resolution: {integrity: sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==}
engines: {node: '>=8'}
@ -2669,6 +3014,31 @@ packages:
engines: {node: '>=6'}
dev: true
/pac-proxy-agent@7.0.1:
resolution: {integrity: sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==}
engines: {node: '>= 14'}
dependencies:
'@tootallnate/quickjs-emscripten': 0.23.0
agent-base: 7.1.0
debug: 4.3.4
get-uri: 6.0.2
http-proxy-agent: 7.0.0
https-proxy-agent: 7.0.2
pac-resolver: 7.0.0
socks-proxy-agent: 8.0.2
transitivePeerDependencies:
- supports-color
dev: true
/pac-resolver@7.0.0:
resolution: {integrity: sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==}
engines: {node: '>= 14'}
dependencies:
degenerator: 5.0.1
ip: 1.1.8
netmask: 2.0.2
dev: true
/package-hash@4.0.0:
resolution: {integrity: sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==}
engines: {node: '>=8'}
@ -2679,6 +3049,13 @@ packages:
release-zalgo: 1.0.0
dev: true
/parent-module@1.0.1:
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
engines: {node: '>=6'}
dependencies:
callsites: 3.1.0
dev: true
/parse-json@5.2.0:
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
engines: {node: '>=8'}
@ -2734,6 +3111,10 @@ packages:
engines: {node: '>=8'}
dev: true
/pend@1.2.0:
resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==}
dev: true
/picocolors@1.0.0:
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
dev: true
@ -3166,20 +3547,112 @@ packages:
fromentries: 1.3.2
dev: true
/progress@2.0.3:
resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==}
engines: {node: '>=0.4.0'}
dev: true
/promise.series@0.2.0:
resolution: {integrity: sha512-VWQJyU2bcDTgZw8kpfBpB/ejZASlCrzwz5f2hjb/zlujOEB4oeiAhHygAWq8ubsX2GVkD4kCU5V2dwOTaCY5EQ==}
engines: {node: '>=0.12'}
dev: true
/proxy-agent@6.3.1:
resolution: {integrity: sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==}
engines: {node: '>= 14'}
dependencies:
agent-base: 7.1.0
debug: 4.3.4
http-proxy-agent: 7.0.0
https-proxy-agent: 7.0.2
lru-cache: 7.18.3
pac-proxy-agent: 7.0.1
proxy-from-env: 1.1.0
socks-proxy-agent: 8.0.2
transitivePeerDependencies:
- supports-color
dev: true
/proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
dev: true
/pump@3.0.0:
resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==}
dependencies:
end-of-stream: 1.4.4
once: 1.4.0
dev: true
/puppeteer-core@21.5.2:
resolution: {integrity: sha512-v4T0cWnujSKs+iEfmb8ccd7u4/x8oblEyKqplqKnJ582Kw8PewYAWvkH4qUWhitN3O2q9RF7dzkvjyK5HbzjLA==}
engines: {node: '>=16.13.2'}
dependencies:
'@puppeteer/browsers': 1.8.0
chromium-bidi: 0.4.33(devtools-protocol@0.0.1203626)
cross-fetch: 4.0.0
debug: 4.3.4
devtools-protocol: 0.0.1203626
ws: 8.14.2
transitivePeerDependencies:
- bufferutil
- encoding
- supports-color
- utf-8-validate
dev: true
/puppeteer@21.5.2(typescript@5.3.2):
resolution: {integrity: sha512-BaAGJOq8Fl6/cck6obmwaNLksuY0Bg/lIahCLhJPGXBFUD2mCffypa4A592MaWnDcye7eaHmSK9yot0pxctY8A==}
engines: {node: '>=16.13.2'}
requiresBuild: true
dependencies:
'@puppeteer/browsers': 1.8.0
cosmiconfig: 8.3.6(typescript@5.3.2)
puppeteer-core: 21.5.2
transitivePeerDependencies:
- bufferutil
- encoding
- supports-color
- typescript
- utf-8-validate
dev: true
/queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
dev: true
/queue-tick@1.0.1:
resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==}
dev: true
/quick-lru@5.1.1:
resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
engines: {node: '>=10'}
dev: true
/randombytes@2.1.0:
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
dependencies:
safe-buffer: 5.2.1
dev: true
/react-dom@18.2.0(react@18.2.0):
resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==}
peerDependencies:
react: ^18.2.0
dependencies:
loose-envify: 1.4.0
react: 18.2.0
scheduler: 0.23.0
dev: true
/react@18.2.0:
resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
engines: {node: '>=0.10.0'}
dependencies:
loose-envify: 1.4.0
dev: true
/read-pkg-up@8.0.0:
resolution: {integrity: sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==}
engines: {node: '>=12'}
@ -3237,6 +3710,11 @@ packages:
resolve-from: 5.0.0
dev: true
/resolve-from@4.0.0:
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
engines: {node: '>=4'}
dev: true
/resolve-from@5.0.0:
resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
engines: {node: '>=8'}
@ -3339,10 +3817,20 @@ packages:
queue-microtask: 1.2.3
dev: true
/safe-buffer@5.2.1:
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
dev: true
/safe-identifier@0.4.2:
resolution: {integrity: sha512-6pNbSMW6OhAi9j+N8V+U715yBQsaWJ7eyEUaOrawX+isg5ZxhUlV1NipNtgaKHmFGiABwt+ZF04Ii+3Xjkg+8w==}
dev: true
/scheduler@0.23.0:
resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==}
dependencies:
loose-envify: 1.4.0
dev: true
/semver@6.3.1:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
@ -3363,6 +3851,12 @@ packages:
type-fest: 0.13.1
dev: true
/serialize-javascript@6.0.1:
resolution: {integrity: sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==}
dependencies:
randombytes: 2.1.0
dev: true
/set-blocking@2.0.0:
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
dev: true
@ -3406,11 +3900,46 @@ packages:
is-fullwidth-code-point: 4.0.0
dev: true
/smart-buffer@4.2.0:
resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==}
engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
dev: true
/smob@1.4.1:
resolution: {integrity: sha512-9LK+E7Hv5R9u4g4C3p+jjLstaLe11MDsL21UpYaCNmapvMkYhqCV4A/f/3gyH8QjMyh6l68q9xC85vihY9ahMQ==}
dev: true
/socks-proxy-agent@8.0.2:
resolution: {integrity: sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==}
engines: {node: '>= 14'}
dependencies:
agent-base: 7.1.0
debug: 4.3.4
socks: 2.7.1
transitivePeerDependencies:
- supports-color
dev: true
/socks@2.7.1:
resolution: {integrity: sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==}
engines: {node: '>= 10.13.0', npm: '>= 3.0.0'}
dependencies:
ip: 2.0.0
smart-buffer: 4.2.0
dev: true
/source-map-js@1.0.2:
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
engines: {node: '>=0.10.0'}
dev: true
/source-map-support@0.5.21:
resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
dependencies:
buffer-from: 1.1.2
source-map: 0.6.1
dev: true
/source-map@0.6.1:
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
engines: {node: '>=0.10.0'}
@ -3466,6 +3995,13 @@ packages:
escape-string-regexp: 2.0.0
dev: true
/streamx@2.15.5:
resolution: {integrity: sha512-9thPGMkKC2GctCzyCUjME3yR03x2xNo0GPKGkRw2UMYN+gqWa9uqpyNWhmsNCutU5zHmkUum0LsCRQTXUgUCAg==}
dependencies:
fast-fifo: 1.3.2
queue-tick: 1.0.1
dev: true
/string-argv@0.3.2:
resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==}
engines: {node: '>=0.6.19'}
@ -3582,11 +4118,38 @@ packages:
stable: 0.1.8
dev: true
/tar-fs@3.0.4:
resolution: {integrity: sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==}
dependencies:
mkdirp-classic: 0.5.3
pump: 3.0.0
tar-stream: 3.1.6
dev: true
/tar-stream@3.1.6:
resolution: {integrity: sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==}
dependencies:
b4a: 1.6.4
fast-fifo: 1.3.2
streamx: 2.15.5
dev: true
/temp-dir@3.0.0:
resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==}
engines: {node: '>=14.16'}
dev: true
/terser@5.24.0:
resolution: {integrity: sha512-ZpGR4Hy3+wBEzVEnHvstMvqpD/nABNelQn/z2r0fjVWGQsN3bpOLzQlqDxmb4CDZnXq5lpjnQ+mHQLAOpfM5iw==}
engines: {node: '>=10'}
hasBin: true
dependencies:
'@jridgewell/source-map': 0.3.5
acorn: 8.11.2
commander: 2.20.3
source-map-support: 0.5.21
dev: true
/test-exclude@6.0.0:
resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==}
engines: {node: '>=8'}
@ -3596,6 +4159,10 @@ packages:
minimatch: 3.1.2
dev: true
/through@2.3.8:
resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
dev: true
/time-zone@1.0.0:
resolution: {integrity: sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==}
engines: {node: '>=4'}
@ -3613,6 +4180,10 @@ packages:
is-number: 7.0.0
dev: true
/tr46@0.0.3:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
dev: true
/trim-newlines@4.1.1:
resolution: {integrity: sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ==}
engines: {node: '>=12'}
@ -3668,10 +4239,22 @@ packages:
dev: true
optional: true
/unbzip2-stream@1.4.3:
resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==}
dependencies:
buffer: 5.7.1
through: 2.3.8
dev: true
/undici-types@5.26.5:
resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
dev: true
/universalify@0.1.2:
resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
engines: {node: '>= 4.0.0'}
dev: true
/update-browserslist-db@1.0.13(browserslist@4.22.1):
resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==}
hasBin: true
@ -3683,6 +4266,10 @@ packages:
picocolors: 1.0.0
dev: true
/urlpattern-polyfill@9.0.0:
resolution: {integrity: sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==}
dev: true
/util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
dev: true
@ -3699,11 +4286,22 @@ packages:
spdx-expression-parse: 3.0.1
dev: true
/webidl-conversions@3.0.1:
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
dev: true
/well-known-symbols@2.0.0:
resolution: {integrity: sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==}
engines: {node: '>=6'}
dev: true
/whatwg-url@5.0.0:
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
dependencies:
tr46: 0.0.3
webidl-conversions: 3.0.1
dev: true
/which-module@2.0.1:
resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==}
dev: true
@ -3781,6 +4379,19 @@ packages:
optional: true
dev: true
/ws@8.14.2:
resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==}
engines: {node: '>=10.0.0'}
peerDependencies:
bufferutil: ^4.0.1
utf-8-validate: '>=5.0.2'
peerDependenciesMeta:
bufferutil:
optional: true
utf-8-validate:
optional: true
dev: true
/y18n@4.0.3:
resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
dev: true
@ -3856,6 +4467,13 @@ packages:
yargs-parser: 21.1.1
dev: true
/yauzl@2.10.0:
resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==}
dependencies:
buffer-crc32: 0.2.13
fd-slicer: 1.1.0
dev: true
/yocto-queue@0.1.0:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}

View File

@ -82,7 +82,7 @@ export default function html(opts: RollupHtmlOptions = {}): Plugin {
let addedEntries = new Map<string, string>();
let entryNames = new Map<string,string>();
const pluginName = 'html2';
const pluginName = 'html2'; // TODO: Need a better name
/**
* Short summary:
* Intercepts the loading of the html files and parses it with parse5.
@ -103,7 +103,7 @@ export default function html(opts: RollupHtmlOptions = {}): Plugin {
* - we might need to know which output is being used to properly extract the html back from the result? (in case of not being included in a JS file)
*/
return {
name: pluginName,// TODO: Need a better name, original plugin was just named `html` and might still make sense to use in conjunction with this one
name: pluginName,
// Track html entrypoints
buildStart(options){

View File

@ -2,7 +2,7 @@ import {join, dirname} from "node:path";
import test from "ava";
import { rollup } from "rollup";
import {debugPrintOutput, getCode} from "../util/test.js";
import {debugPrintOutput, getCode} from "../util/index.ts";
import html from "../../src/index.ts";
@ -25,7 +25,7 @@ test.serial('simple', async (t) => {
}),
]
});
const code = await getCode(bundle, output, true);
const code = await getCode(bundle, output);
debugPrintOutput('simple',code);
t.snapshot(code);
});
@ -38,7 +38,7 @@ test.serial('inline-script', async (t) => {
}),
]
});
const code = await getCode(bundle, output, true);
const code = await getCode(bundle, output);
debugPrintOutput('inline-script',code);
t.snapshot(code);
});

View File

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<title>HTML5 Logo</title>
<path d="M108.4 0h23v22.8h21.2V0h23v69h-23V46h-21v23h-23.2M206 23h-20.3V0h63.7v23H229v46h-23M259.5 0h24.1l14.8 24.3L313.2 0h24.1v69h-23V34.8l-16.1 24.8l-16.1-24.8v34.2h-22.6M348.7 0h23v46.2h32.6V69h-55.6"/>
<path fill="#e44d26" d="M107.6 471l-33-370.4h362.8l-33 370.2L255.7 512"/>
<path fill="#f16529" d="M256 480.5V131H404.3L376 447"/>
<path fill="#ebebeb" d="M142 176.3h114v45.4h-64.2l4.2 46.5h60v45.3H154.4M156.4 336.3H202l3.2 36.3 50.8 13.6v47.4l-93.2-26"/>
<path fill="#fff" d="M369.6 176.3H255.8v45.4h109.6M361.3 268.2H255.8v45.4h56l-5.3 59-50.7 13.6v47.2l93-25.8"/>
</svg>

After

Width:  |  Height:  |  Size: 693 B

View File

@ -0,0 +1 @@
export const batman = 'bum badum badum baaaaa dum!';

View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
Test bundle!
</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="./assets/logo-sq.svg">
{{{ head }}}
</head>
<body>
<div id="root">Here the app should load!</div>
<script src="./index.js" type="module"></script>
</body>
</html>

View File

@ -0,0 +1,27 @@
// Dynamically loads libraries and bootstraps the application
(async ()=>{
// Add a loader here if any
const root = document.getElementById('root')
if(root) root.innerHTML= `<div style="align-self: center">My app has loaded!!</div>`;
try {
// Load app
const [
appModule,
] = await Promise.all([
import("./batman.js"),
]);
console.log("Bootstrapped, ready to go!");
// Wait for DOM to be ready
if(document.readyState === 'loading') {
await new Promise((resolve)=>document.addEventListener('DOMContentLoaded', resolve));
}
// Start the app!
root.innerHTML = `<div style="align-self: center"><b>${appModule.batman}</b></div>`;
}catch(err){
console.error(err);
}
})()

View File

@ -0,0 +1,73 @@
# Snapshot report for `test/evaluated-web-bundle/test.js`
The actual snapshot is saved in `test.js.snap`.
Generated by [AVA](https://avajs.dev).
## web-bundle
> Snapshot 1
{
console: [
'[log] Bootstrapped, ready to go!',
],
errors: [],
html: `<html lang="en"><head>
<meta charset="UTF-8">
<title>
Test bundle!␊
</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20512%20512%22%3E%20%20%20%20%3Ctitle%3EHTML5%20Logo%3C%2Ftitle%3E%20%20%20%20%3Cpath%20d%3D%22M108.4%200h23v22.8h21.2V0h23v69h-23V46h-21v23h-23.2M206%2023h-20.3V0h63.7v23H229v46h-23M259.5%200h24.1l14.8%2024.3L313.2%200h24.1v69h-23V34.8l-16.1%2024.8l-16.1-24.8v34.2h-22.6M348.7%200h23v46.2h32.6V69h-55.6%22%2F%3E%20%20%20%20%3Cpath%20fill%3D%22%23e44d26%22%20d%3D%22M107.6%20471l-33-370.4h362.8l-33%20370.2L255.7%20512%22%2F%3E%20%20%20%20%3Cpath%20fill%3D%22%23f16529%22%20d%3D%22M256%20480.5V131H404.3L376%20447%22%2F%3E%20%20%20%20%3Cpath%20fill%3D%22%23ebebeb%22%20d%3D%22M142%20176.3h114v45.4h-64.2l4.2%2046.5h60v45.3H154.4M156.4%20336.3H202l3.2%2036.3%2050.8%2013.6v47.4l-93.2-26%22%2F%3E%20%20%20%20%3Cpath%20fill%3D%22%23fff%22%20d%3D%22M369.6%20176.3H255.8v45.4h109.6M361.3%20268.2H255.8v45.4h56l-5.3%2059-50.7%2013.6v47.2l93-25.8%22%2F%3E%3C%2Fsvg%3E">
<title>I'm cool!</title>
</head>
<body>
<div id="root"><div style="align-self: center"><b>bum badum badum baaaaa dum!</b></div></div>
<script src="index.js" type="module"></script>
</body></html>`,
requestsFailed: [],
responses: [
'200 http://localhost/index.html',
'200 http://localhost/index.js',
'200 http://localhost/batman.js',
],
}
## copied-assets
> Snapshot 1
{
console: [
'[log] Bootstrapped, ready to go!',
],
errors: [],
html: `<html lang="en"><head>
<meta charset="UTF-8">
<title>
Test bundle!␊
</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20512%20512%22%3E%20%20%20%20%3Ctitle%3EHTML5%20Logo%3C%2Ftitle%3E%20%20%20%20%3Cpath%20d%3D%22M108.4%200h23v22.8h21.2V0h23v69h-23V46h-21v23h-23.2M206%2023h-20.3V0h63.7v23H229v46h-23M259.5%200h24.1l14.8%2024.3L313.2%200h24.1v69h-23V34.8l-16.1%2024.8l-16.1-24.8v34.2h-22.6M348.7%200h23v46.2h32.6V69h-55.6%22%2F%3E%20%20%20%20%3Cpath%20fill%3D%22%23e44d26%22%20d%3D%22M107.6%20471l-33-370.4h362.8l-33%20370.2L255.7%20512%22%2F%3E%20%20%20%20%3Cpath%20fill%3D%22%23f16529%22%20d%3D%22M256%20480.5V131H404.3L376%20447%22%2F%3E%20%20%20%20%3Cpath%20fill%3D%22%23ebebeb%22%20d%3D%22M142%20176.3h114v45.4h-64.2l4.2%2046.5h60v45.3H154.4M156.4%20336.3H202l3.2%2036.3%2050.8%2013.6v47.4l-93.2-26%22%2F%3E%20%20%20%20%3Cpath%20fill%3D%22%23fff%22%20d%3D%22M369.6%20176.3H255.8v45.4h109.6M361.3%20268.2H255.8v45.4h56l-5.3%2059-50.7%2013.6v47.2l93-25.8%22%2F%3E%3C%2Fsvg%3E">
<title>I'm cool!</title>
</head>
<body>
<div id="root"><div style="align-self: center"><b>bum badum badum baaaaa dum!</b></div></div>
<script src="index.js" type="module"></script>
</body></html>`,
requestsFailed: [],
responses: [
'200 http://localhost/index.html',
'200 http://localhost/index.js',
'200 http://localhost/batman.js',
],
}

Binary file not shown.

View File

@ -0,0 +1,58 @@
import {join, dirname} from "node:path";
import test from "ava";
import { rollup } from "rollup";
import urlPlugin from "@rollup/plugin-url";
import html from "../../src/index.ts";
import serveTest from "../util/test-server.ts";
/**
* @type {OutputOptions}
*/
const output= {
dir: 'output', // Output all files
format: 'es', // iifi and cjs should be added to tests
sourcemap: true,// Test if #sourcemapUrl is not accidentally included in the html-output
chunkFileNames: '[name].js',
entryFileNames: '[name].[extname]',
assetFileNames: '[name].[extname]',
};
import {fileURLToPath} from "node:url";
import handlebars from "handlebars";
const __dirname = dirname(fileURLToPath(import.meta.url));
process.chdir(join(__dirname, 'fixtures'));
const defaultAssetInclude = [
'**/*.(png|jpg|jpeg|gif|ico|svg)',// images, svg
'**/*.(woff|woff2|eot|ttf|otf)',// fonts
'**/*.(webm|mp4)',// video
];
test.serial('web-bundle', async (t) => {
const bundle = await rollup({
input: 'index.hbs',
treeshake: 'smallest',
plugins: [
html({
transform(src) {
return handlebars.compile(src)({
head: `<title>I'm cool!</title>`
});
}
}),
urlPlugin({
include: defaultAssetInclude,
}),
serveTest({
path: 'index.html',
t,
})
],
});
await bundle.generate(output);
});

View File

@ -37,7 +37,7 @@ Generated by [AVA](https://avajs.dev).
sources: [
'../icon.svg',
'../index.html',
'../index.js',
'../index.ts',
],
sourcesContent: [
'export default "data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%2032%2032%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%20%3Cpath%20style%3D%22fill%3Anone%3Bstroke%3A%2300ff0d%3Bstroke-width%3A5%3Bstroke-linecap%3Asquare%3Bstroke-linejoin%3Amiter%3Bstroke-dasharray%3Anone%3Bstroke-opacity%3A1%22%20d%3D%22M4.1%2014.72%2016%2026.31%2028.38%205.09%22%2F%3E%3C%2Fsvg%3E"',
@ -66,6 +66,6 @@ Generated by [AVA](https://avajs.dev).
code: undefined,
fileName: 'index-f75fa1e5.js.map',
map: undefined,
source: '{"version":3,"file":"index-f75fa1e5.js","sources":["../icon.svg","../index.html","../index.js"],"sourcesContent":["export default \\"data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%2032%2032%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%20%3Cpath%20style%3D%22fill%3Anone%3Bstroke%3A%2300ff0d%3Bstroke-width%3A5%3Bstroke-linecap%3Asquare%3Bstroke-linejoin%3Amiter%3Bstroke-dasharray%3Anone%3Bstroke-opacity%3A1%22%20d%3D%22M4.1%2014.72%2016%2026.31%2028.38%205.09%22%2F%3E%3C%2Fsvg%3E\\"","<html>\\n <head>\\n <link rel=\\"icon\\" href=\\"./icon.svg\\">\\n<!-- <link rel=\\"stylesheet\\" href=\\"./joker.css\\">-->\\n </head>\\n <body>\\n <!--<script src=\\"./batman.js\\" type=\\"module\\"></script>-->\\n </body>\\n</html>\\n","import html from \\"./index.html\\"\\n\\nexport function render(){\\n return html;\\n}\\n"],"names":[],"mappings":"AAAA,aAAe;;ACAf,MAAA,IAAA,GAAA,CAAA;AACA,+BAA+B,EAAwD,MAAA,CAAA;AACvF;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,CAAA;;ACNN,SAAS,MAAM,EAAE;AACxB,IAAI,OAAO,IAAI,CAAC;AAChB;;;;"}',
source: '{"version":3,"file":"index-f75fa1e5.js","sources":["../icon.svg","../index.html","../index.ts"],"sourcesContent":["export default \\"data:image/svg+xml,%3Csvg%20viewBox%3D%220%200%2032%2032%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%20%20%3Cpath%20style%3D%22fill%3Anone%3Bstroke%3A%2300ff0d%3Bstroke-width%3A5%3Bstroke-linecap%3Asquare%3Bstroke-linejoin%3Amiter%3Bstroke-dasharray%3Anone%3Bstroke-opacity%3A1%22%20d%3D%22M4.1%2014.72%2016%2026.31%2028.38%205.09%22%2F%3E%3C%2Fsvg%3E\\"","<html>\\n <head>\\n <link rel=\\"icon\\" href=\\"./icon.svg\\">\\n<!-- <link rel=\\"stylesheet\\" href=\\"./joker.css\\">-->\\n </head>\\n <body>\\n <!--<script src=\\"./batman.js\\" type=\\"module\\"></script>-->\\n </body>\\n</html>\\n","import html from \\"./index.html\\"\\n\\nexport function render(){\\n return html;\\n}\\n"],"names":[],"mappings":"AAAA,aAAe;;ACAf,MAAA,IAAA,GAAA,CAAA;AACA,+BAA+B,EAAwD,MAAA,CAAA;AACvF;AACA;AACA;AACA;AACA;AACA;AACA,cAAa,CAAA;;ACNN,SAAS,MAAM,EAAE;AACxB,IAAI,OAAO,IAAI,CAAC;AAChB;;;;"}',
},
]

View File

@ -3,7 +3,7 @@ import {join, dirname} from "node:path";
import test from "ava";
import { rollup } from "rollup";
import {debugPrintOutput, getCode} from "../util/test.js";
import {debugPrintOutput, getCode} from "../util/index.ts";
import html from "../../src/index.ts";
import handlebars from "handlebars";
@ -38,7 +38,7 @@ test.serial('js-import', async (t) => {
}),
]
});
const code = await getCode(bundle, output, true);
const code = await getCode(bundle, output);
debugPrintOutput('js-import',code);
t.snapshot(code);
});

View File

@ -3,7 +3,7 @@ import {join, dirname} from "node:path";
import test from "ava";
import {rollup} from "rollup";
import liveReload from "rollup-plugin-livereload";
import {debugPrintOutput, getCode} from "../util/test.js";
import {debugPrintOutput, getCode} from "../util/index.ts";
import html from "../../src/index.ts";
@ -29,7 +29,7 @@ test.serial('live-reload', async (t) => {
})
]
});
const code = await getCode(bundle, output, true);
const code = await getCode(bundle, output);
await bundle.close();// Make sure live-reload closes itself
debugPrintOutput('live-reload',code);
t.snapshot(code);

View File

@ -2,7 +2,7 @@ import {resolve, join, dirname} from "node:path";
import test from "ava";
import { rollup } from "rollup";
import {debugPrintOutput, getCode} from "../util/test.js";
import {debugPrintOutput, getCode} from "../util/index.ts";
import html from "../../src/index.ts";
@ -28,7 +28,7 @@ test.serial('multi-entry', async (t) => {
}),
]
});
const code = await getCode(bundle, output, true);
const code = await getCode(bundle, output);
debugPrintOutput('multi-entry',code);
t.snapshot(code);
});

View File

@ -2,7 +2,7 @@ import {resolve, join, dirname} from "node:path";
import * as path from "node:path";
import test from "ava";
import { rollup } from "rollup";
import {debugPrintOutput, getCode} from "../util/test.js";
import {debugPrintOutput, getCode} from "../util/index.ts";
import html from "../../src/index.ts";
@ -32,7 +32,7 @@ test.serial('rewrite-url', async (t) => {
}),
]
});
const code = await getCode(bundle, output, true);
const code = await getCode(bundle, output);
debugPrintOutput('rewrite-url',code);
t.snapshot(code);
});

View File

@ -3,7 +3,7 @@ import {join, dirname} from "node:path";
import test from "ava";
import { rollup } from "rollup";
import {debugPrintOutput, getCode} from "../util/test.js";
import {debugPrintOutput, getCode} from "../util/index.ts";
import html from "../../src/index.ts";
import handlebars from "handlebars";
@ -30,7 +30,7 @@ test.serial('handlebars', async (t) => {
})
]
});
const code = await getCode(bundle, output, true);
const code = await getCode(bundle, output);
debugPrintOutput('handlebars',code);
t.snapshot(code);
});

View File

@ -4,7 +4,7 @@ import test from "ava";
import { rollup } from "rollup";
import urlPlugin from "@rollup/plugin-url";
import {debugPrintOutput, getCode} from "../util/test.js";
import {debugPrintOutput, getCode} from "../util/index.ts";
import html from "../../src/index.ts";
@ -37,7 +37,7 @@ test.serial('copied-assets', async (t) => {
}),
],
});
const code = await getCode(bundle, output, true);
const code = await getCode(bundle, output);
debugPrintOutput('copied-assets',code);
t.snapshot(code);
});
@ -55,7 +55,7 @@ test.serial('inlined-assets', async (t) => {
}),
]
});
const code = await getCode(bundle, output, true);
const code = await getCode(bundle, output);
debugPrintOutput('inlined-assets',code);
t.snapshot(code);
});

26
test/util/code-output.ts Normal file
View File

@ -0,0 +1,26 @@
import type {RollupBuild, OutputOptions, OutputAsset, OutputChunk, SourceMap} from "rollup";
export interface TestOutput{
code: string,
fileName: string,
source: any,
map: any
}
export const getCode = async (bundle: RollupBuild, outputOptions: OutputOptions): Promise<TestOutput[]> => {
const { output } = await bundle.generate(outputOptions || { format: 'cjs', exports: 'auto' });
return output.sort((a,b)=> {
if(a.fileName === b.fileName && (<OutputAsset>a).source !== (<OutputAsset>b).source){ return (<OutputAsset>a).source<(<OutputAsset>b).source?-1:1}
return a.fileName < b.fileName ? -1 : (a.fileName > b.fileName? 1 : 0);
}).map(chunk=> {
const { code, map } = (<OutputChunk>chunk);
const { fileName, source } = (<OutputAsset>chunk);
return {
code,
fileName,
source,
map
};
});
};

6
test/util/index.ts Normal file
View File

@ -0,0 +1,6 @@
export * from "./code-output.ts";
export * from "./print-code-output.ts";
export * from "./test-server.ts";
export * from './misc.js';

View File

@ -1,59 +1,5 @@
import path from "node:path";
import process from "node:process";
import chalk from "chalk";
/**
* @param {import('rollup').RollupBuild} bundle
* @param {import('rollup').OutputOptions} [outputOptions]
*/
export const getCode = async (bundle, outputOptions, allFiles = false) => {
const { output } = await bundle.generate(outputOptions || { format: 'cjs', exports: 'auto' });
if (allFiles) {
return output.sort((a,b)=> {
if(a.fileName === b.fileName && a.source !== b.source){ return a.source<b.source?-1:1}
return a.fileName < b.fileName ? -1 : (a.fileName > b.fileName? 1 : 0);
}).map(({ code, fileName, source, map }) => {
return {
code,
fileName,
source,
map
};
});
}
const [{ code }] = output;
return code;
};
export const debugPrintOutput = async (header, files) => {
const out = [];
const headFn = chalk.bgCyan;
const headPadding = header.split('').map(x=>'#').join('');
out.push(...[
headFn(`##${headPadding}##`),
headFn(`# ${header} #`),
headFn(`##${headPadding}##`),
]);
const fileHeadFn = chalk.blue;
const fileContentFn = chalk.blackBright;
out.push(...(files.map(file=>{
return [
fileHeadFn(`${file.fileName}:`),
fileContentFn(`${file.code??file.source}`),
'',
]
}).flat()));
out.push(...[
headFn(`##${headPadding}##`),
]);
process.env.DEBUG? console.log(out.join('\n')) : null;
};
/**
* @param {import('rollup').RollupBuild} bundle

View File

@ -0,0 +1,32 @@
import process from "node:process";
import chalk from "chalk";
import {TestOutput} from "./code-output.ts";
export const debugPrintOutput = async (header: string, files: TestOutput[]) => {
const out = [];
const headFn = chalk.bgCyan;
const headPadding = header.split('').map(x=>'#').join('');
out.push(...[
headFn(`##${headPadding}##`),
headFn(`# ${header} #`),
headFn(`##${headPadding}##`),
]);
const fileHeadFn = chalk.blue;
const fileContentFn = chalk.blackBright;
out.push(...(files.map(file=>{
return [
fileHeadFn(`${file.fileName}:`),
fileContentFn(`${file.code??file.source}`),
'',
]
}).flat()));
out.push(...[
headFn(`##${headPadding}##`),
]);
process.env.DEBUG? console.log(out.join('\n')) : null;
};

384
test/util/test-server.ts Normal file
View File

@ -0,0 +1,384 @@
/**
* Puppeteer + from-memory devServer rollup plugin to open the result in a webpage en output the result
* (after an optional series of commands to the puppeteer Page)
*/
import puppeteer, {Page} from "puppeteer";
import http from 'http';
import {resolve, posix} from "node:path";
import {URL} from "node:url";
import { readFile } from 'fs'
import { createServer as createHttpsServer } from 'https'
import { createServer} from 'http'
import { Mime } from 'mime/lite'
import standardTypes from 'mime/types/standard.js'
import otherTypes from 'mime/types/other.js'
import type {NormalizedOutputOptions, OutputAsset, OutputBundle, OutputChunk, Plugin} from 'rollup'
import type {
IncomingHttpHeaders, OutgoingHttpHeaders,
IncomingMessage, ServerResponse,
Server
} from 'http'
import type { ServerOptions } from 'https'
type TypeMap = {
[key: string]: string[];
};
type ErrorCodeException = Error & {code: string};
export interface RollupServeOptions {
/**
* Change the path to be opened when the test is started
* Remember to start with a slash, e.g. `'/different/page'`
*/
path?: string
cb?: PageTestCallback
t?: any
/**
* Set to `true` to return index.html (200) instead of error page (404)
* or path to fallback page
*/
historyApiFallback?: boolean | string
/**
* Change the host of the server (default: `'localhost'`)
*/
host?: string
/**
* Change the port that the server will listen on (default: `10001`)
*/
port?: number | string
/**
* By default server will be served over HTTP (https: `false`). It can optionally be served over HTTPS.
*/
https?: ServerOptions | false
/**
* Set custom response headers
*/
headers?:
| IncomingHttpHeaders
| OutgoingHttpHeaders
| {
// i.e. Parameters<OutgoingMessage["setHeader"]>
[name: string]: number | string | ReadonlyArray<string>
}
/**
* Set custom mime types, usage https://github.com/broofa/mime#mimedefinetypemap-force--false
*/
mimeTypes?: TypeMap
/**
* Execute function after server has begun listening
*/
onListening?: (server: Server) => void
}
/**
* Serve your rolled up bundle like webpack-dev-server
* @param {import('..').RollupServeOptions} options
*/
export default function serveTest (options: RollupServeOptions ): Plugin {
const mime = new Mime(standardTypes, otherTypes)
const testOptions = {
port: 0,
headers: {},
historyApiFallback: true,
onListening: function noop (){},
...options||{},
https: options.https??false,
mimeTypes: options.mimeTypes? mime.define(options.mimeTypes, true): false
}
let server : Server;
let bundle : OutputBundle = {};
const requestListener = (request: IncomingMessage, response: ServerResponse) => {
// Remove querystring
const unsafePath = decodeURI(request.url!.split('?')[0])
// Don't allow path traversal
const urlPath = posix.normalize(unsafePath)
for(const [key, value] of Object.entries((<OutgoingHttpHeaders>testOptions.headers))){
response.setHeader(key, value!);
}
function urlToFilePath(url:string){
return url[0]==='/'?url.slice(1):url;
}
let filePath = urlToFilePath(urlPath); // Todo check if we need to strip '/'
let file: OutputChunk|OutputAsset;
if(!bundle[filePath] && testOptions.historyApiFallback) {
const fallbackPath = typeof testOptions.historyApiFallback === 'string'
? testOptions.historyApiFallback
: '/index.html';
if(bundle[urlToFilePath(fallbackPath)]){
filePath = urlToFilePath(fallbackPath);
}
}
file = bundle[filePath];
if(!file){
return notFound(response, filePath);
}else{
const content = (<OutputChunk>file).code || (<OutputAsset>file).source; // Todo might need to read a source file;
return found(response, mime.getType(filePath!), content);
}
//
// if(bundle[urlPath]){
// const fallbackPath = typeof testOptions.historyApiFallback === 'string' ? testOptions.historyApiFallback : '/index.html'
// }
//
// readFileFromContentBase(contentBase, urlPath, function (error, content, filePath) {
// if (!error) {
// return found(response, mime.getType(filePath!), content)
// }
// if ((<ErrorCodeException>error).code !== 'ENOENT') {
// response.writeHead(500)
// response.end('500 Internal Server Error' +
// '\n\n' + filePath +
// '\n\n' + Object.values(error).join('\n') +
// '\n\n(rollup-plugin-serve)', 'utf-8')
// return
// }
// if (testOptions.historyApiFallback) {
// const fallbackPath = typeof testOptions.historyApiFallback === 'string' ? testOptions.historyApiFallback : '/index.html'
// readFileFromContentBase(contentBase, fallbackPath, function (error, content, filePath) {
// if (error) {
// notFound(response, filePath)
// } else {
// found(response, mime.getType(filePath), content)
// }
// })
// } else {
// notFound(response, filePath)
// }
// })
}
function closeServerOnTermination () {
const terminationSignals = ['SIGINT', 'SIGTERM', 'SIGQUIT', 'SIGHUP']
terminationSignals.forEach(signal => {
process.on(signal, () => {
if (server) {
server.close()
process.exit()
}
})
})
}
// release previous server instance if rollup is reloading configuration in watch mode
// @ts-ignore
if (server) {
server.close()
} else {
closeServerOnTermination()
}
// If HTTPS options are available, create an HTTPS server
server = testOptions.https
? createHttpsServer(testOptions.https, requestListener)
: createServer(requestListener)
server.listen(
typeof(testOptions.port)==='string'? Number.parseInt(testOptions.port):testOptions.port,
testOptions.host,
undefined,
() => testOptions.onListening?.(server)
)
testOptions.port = (<any>server.address())?.port ?? testOptions.port;
// Assemble url for error and info messages
const url = (testOptions.https ? 'https' : 'http') + '://' + (testOptions.host || 'localhost') + ':' + testOptions.port
// Handle common server errors
server.on('error', e => {
if ((<ErrorCodeException>e).code === 'EADDRINUSE') {
console.error(url + ' is in use, either stop the other server or use a different port.')
process.exit()
} else {
throw e
}
})
let first = true
return {
name: 'serve',
generateBundle: {
order: 'post',
async handler(options, output){
bundle = output;
if (first) {
first = false
const testOutput = await runTest({
page: testOptions.path!,
cb: testOptions.cb,
}, url)
testOptions.t?.snapshot?.(testOutput);
}
}
},
closeBundle (){
// Done with the bundle
}
}
}
function notFound (response: ServerResponse, filePath: string) {
response.writeHead(404)
response.end(
'404 Not Found' + '\n\n' + filePath,
'utf-8'
)
}
function found (response: ServerResponse, mimeType: string|null, content: any) {
response.writeHead(200, { 'Content-Type': mimeType || 'text/plain' })
response.end(content, 'utf-8')
}
function green (text: string) {
return '\u001b[1m\u001b[32m' + text + '\u001b[39m\u001b[22m'
}
export type PageTestCallback = (page: Page)=>Promise<void>;
export interface TestFilterOptions{
html?: boolean
console?: ('log'|'error'|'warn')[] | true
errors?: boolean, // again don't know possible values
responses?: boolean, // interesting to see what other values were requested
requestsFailed?: boolean, // will probably also be replicated into console errors, but helpful to have if imports werent found
}
export interface TestOptions {
page: string
cb: PageTestCallback
filterOutput: TestFilterOptions
replaceHost: boolean
replaceHostWith?: string
}
const defaultOptions: Partial<TestOptions> = {
page: 'index.html',
cb: async (page: Page)=>{
await page.waitForNetworkIdle({});
},
replaceHost: true,
replaceHostWith: `http://localhost`,
filterOutput:{
html: true,
console: ['log','error','warn'],// TODO: or warning? need to check what possible values are
errors: true, // again don't know possible values
responses: true, // interesting to see what other values were requested
requestsFailed: true, // will probably also be replicated into console errors, but helpful to have if imports werent found
}
}
export interface TestOutput{
html?: string,
console?: string[],
errors?: string[],
responses?: string[],
requestsFailed?: string[],
}
export async function runTest(opts: Partial<TestOptions>, hostUrl: string){
const options : TestOptions = (<TestOptions>{
...defaultOptions,
...opts,
filterOutput: {
...defaultOptions.filterOutput,
...(opts?.filterOutput),
},
});
const {
page: path,
cb,
replaceHost,
replaceHostWith,
filterOutput
} = options;
const browser = await puppeteer.launch({
headless: 'new',
});
const page = await browser.newPage();
let output : TestOutput = {
console: [],
errors: [],
responses: [],
requestsFailed: []
};
try{
// Track requests, errors and console
page.on('console', message => {
let [type, text] = [message.type(), message.text()];
if(replaceHost){
text = text.replaceAll(hostUrl, replaceHostWith!);
}
if((<any>filterOutput.console)?.includes?.(<any>type) ?? (filterOutput.console === true)){// TODO: add callback option
output.console?.push(`[${type}] ${text}`);
}
}).on('pageerror', ({ message }) => {
let text = message;
if(replaceHost){
text = text.replaceAll(hostUrl, replaceHostWith!);
}
if(filterOutput.errors === true) {// TODO add callback option
output.errors?.push(text)
}
}).on('response', response => {
let [status, url] = [response.status(), response.url()]
if(replaceHost){
url = url.replaceAll(hostUrl, replaceHostWith!);
}
if(filterOutput.responses === true) {// TODO add callback option
output.responses?.push(`${status} ${url}`)
}
}).on('requestfailed', request => {
let [failure, url] = [request.failure()?.errorText, request.url()];
if(replaceHost){
failure = failure?.replaceAll(hostUrl, replaceHostWith!);
url = url.replaceAll(hostUrl, replaceHostWith!);
}
if(filterOutput.requestsFailed === true) {// TODO add callback option
output.requestsFailed?.push(`${failure} ${url}`)
}
});
const url = new URL(`${hostUrl}/${path??''}`);
await page.goto(url.href);
if(!cb) {
await page.waitForNetworkIdle({});
}else{
await cb(page);
}
const htmlHandle = await page.$('html');
const html = await page.evaluate(html => html?.outerHTML??html?.innerHTML, htmlHandle);
// Add the final html
output.html = html;
}finally{
await page.close();
await browser.close();
}
return output;
}

45
test/util/test.d.ts vendored
View File

@ -1,45 +0,0 @@
/* eslint-disable import/no-extraneous-dependencies */
import type { RollupBuild, OutputOptions, OutputChunk, OutputAsset } from 'rollup';
import type { Assertions } from 'ava';
interface GetCode {
(bundle: RollupBuild, outputOptions?: OutputOptions | null, allFiles?: false): Promise<string>;
(bundle: RollupBuild, outputOptions: OutputOptions | null | undefined, allFiles: true): Promise<
Array<{
code: OutputChunk['code'] | undefined;
fileName: OutputChunk['fileName'] | OutputAsset['fileName'];
source: OutputAsset['source'] | undefined;
}>
>;
}
export const getCode: GetCode;
export function getFiles(
bundle: RollupBuild,
outputOptions?: OutputOptions
): Promise<
{
fileName: string;
content: any;
}[]
>;
export function evaluateBundle(bundle: RollupBuild): Promise<Pick<NodeModule, 'exports'>>;
export function getImports(bundle: RollupBuild): Promise<string[]>;
export function getResolvedModules(bundle: RollupBuild): Promise<Record<string, string>>;
export function onwarn(warning: string | any): void;
export function testBundle(
t: Assertions,
bundle: RollupBuild,
options: { inject: Record<string, any>; options: Record<string, any> }
): Promise<{
code: string;
error?: any;
result?: any;
module: Pick<NodeModule, 'exports'>;
}>;

View File

@ -2,7 +2,7 @@ import {join, dirname} from "node:path";
import test from "ava";
import * as rollup from "rollup";
import {debugPrintOutput, getCode} from "../util/test.js";
import {debugPrintOutput, getCode} from "../util/index.ts";
import {resolve} from "node:path";
import {writeFile} from "node:fs/promises";
@ -49,7 +49,7 @@ test.serial('watch', async (t) => {
// Just wait on the watch mode to pick up on the changes
},
async (bundle)=>{
const code = await getCode(bundle, output, true);
const code = await getCode(bundle, output);
debugPrintOutput('watch',code);
// Reset the source file

View File

@ -13,7 +13,8 @@
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "NodeNext",
"allowJs": true
"allowJs": true,
"allowImportingTsExtensions": true
},
"exclude": ["dist", "node_modules", "test/types"],
"include": ["src/**/*", "types/**/*"],