Compare commits

...

12 commits
v1.2.0 ... main

Author SHA1 Message Date
57aeac59e6 1.4.0 2022-06-30 18:37:49 +02:00
34925dc266 Feature: Support for fetching data from amazon urls added
Signed-off-by: Benny <benny@hierl.dev>
2022-06-30 18:37:26 +02:00
f07085c211 1.3.0 2022-06-30 17:20:15 +02:00
9880406d61 pre-push adhusted
Signed-off-by: Benny <benny@hierl.dev>
2022-06-30 17:19:44 +02:00
42f0a6f63c pre commit adjusted
Signed-off-by: Benny <benny@hierl.dev>
2022-06-30 17:19:19 +02:00
54f869c7cd Bought Button adjusted 2022-06-30 17:17:32 +02:00
b4cd04a11a small adjustments for package.json
Signed-off-by: Benny <benny@hierl.dev>
2022-05-14 11:11:40 +02:00
caaef85d60 1.2.1 2022-05-14 11:09:51 +02:00
Benny
2e7ea74271
small change on readme 2022-03-10 21:24:33 +01:00
Benny
86e6fd4580
Create LICENSE 2022-03-08 22:54:43 +01:00
Benny
a0c7f33647
Update README.md 2022-03-08 22:52:12 +01:00
Benny
ecbeb4cef0
Update README.md 2022-03-08 22:39:56 +01:00
13 changed files with 666 additions and 176 deletions

View file

@ -1,4 +1,7 @@
#!/bin/sh #!/bin/sh
. "$(dirname "$0")/_/husky.sh" . "$(dirname "$0")/_/husky.sh"
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
npm run lint npm run lint

View file

@ -1,4 +1,7 @@
#!/bin/sh #!/bin/sh
. "$(dirname "$0")/_/husky.sh" . "$(dirname "$0")/_/husky.sh"
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
npm run test:unit:ci npm run test:unit:ci

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Benny
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -1,16 +1,27 @@
# Wishlist App <p align="center">
<img src="https://raw.githubusercontent.com/ThisIsBenny/wishlist-app/main/public/logo-256.png" height="200">
</p>
<h1 align="center">
Wishlist App
</h1>
<p align="center">
<img src="https://img.shields.io/github/package-json/v/thisisbenny/wishlist-app" />
<img src="https://img.shields.io/github/workflow/status/thisisbenny/wishlist-app/CI" />
<a href="https://hub.docker.com/r/thisisbenny/wishlist-app"><img src="https://img.shields.io/docker/pulls/thisisbenny/wishlist-app" /></a>
<img src="https://img.shields.io/github/license/thisisbenny/wishlist-app" />
</p>
<p align="center">
A simple webapp to manage your wishlist.
<p>
<h3 align="center">
<a href="https://codesandbox.io/s/wishlist-app-ycygh3"><i>Demo</i></a>
</h3>
<br>
<br>
The wishlist app is a simple webapp for publishing wishlists. It allows to share wishlists for different people or occasions with friends and family. If something from the wishlist was bought, it can be removed from the list to prevent duplicate purchases. The wishlist app is a simple webapp for publishing wishlists. It allows to share wishlists for different people or occasions with friends and family. If something from the wishlist was bought, it can be removed from the list to prevent duplicate purchases.
## Demo
[![Open in CodeSandbox](https://img.shields.io/badge/Open%20in-CodeSandbox-blue?style=flat-square&logo=codesandbox)](https://codesandbox.io/s/wishlist-app-ycygh3)
## Screenshots
![Overview Image](.github/assets/overview.jpg)
![Detail Image](.github/assets/details.jpg)
## Features ## Features
- Support of multiple wishlists - Support of multiple wishlists
@ -18,6 +29,11 @@ The wishlist app is a simple webapp for publishing wishlists. It allows to share
- Grab title, description and image-url from url via open graph meta tags - Grab title, description and image-url from url via open graph meta tags
- i18n support - i18n support
## Screenshots
![Overview Image](.github/assets/overview.jpg)
![Detail Image](.github/assets/details.jpg)
## Install ## Install
### Docker Setup ### Docker Setup
@ -50,8 +66,6 @@ Now you can select the bookmark on a product page. This will redirect you to the
![Demo Bookmark adding](.github/assets/demo-bookmark.gif) ![Demo Bookmark adding](.github/assets/demo-bookmark.gif)
Once the wish list is ready, it can be shared with friends and family. They have the option to remove purchased items from the wish list so that they are not bought a second time. Once the wish list is ready, it can be shared with friends and family. They have the option to remove purchased items from the wish list so that they are not bought a second time.
Wishlists that have been set as non-public can only be opened with a deep link. They do not appear on the start page (unless the API key is set). Wishlists that have been set as non-public can only be opened with a deep link. They do not appear on the start page (unless the API key is set).

640
package-lock.json generated
View file

@ -1,16 +1,17 @@
{ {
"name": "wishlist", "name": "wishlist",
"version": "1.2.0", "version": "1.4.0",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"version": "1.2.0", "version": "1.4.0",
"dependencies": { "dependencies": {
"@prisma/client": "^3.9.2", "@prisma/client": "^3.9.2",
"@tailwindcss/line-clamp": "^0.3.1", "@tailwindcss/line-clamp": "^0.3.1",
"@vueuse/core": "^7.6.1", "@vueuse/core": "^7.6.1",
"axios": "^0.25.0", "axios": "^0.25.0",
"cheerio": "^1.0.0-rc.12",
"fastify": "^3.27.1", "fastify": "^3.27.1",
"fastify-compress": "^4.0.1", "fastify-compress": "^4.0.1",
"fastify-cors": "^6.0.2", "fastify-cors": "^6.0.2",
@ -1530,7 +1531,7 @@
"node_modules/boolbase": { "node_modules/boolbase": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
}, },
"node_modules/boxen": { "node_modules/boxen": {
"version": "5.1.2", "version": "5.1.2",
@ -1785,17 +1786,17 @@
} }
}, },
"node_modules/cheerio": { "node_modules/cheerio": {
"version": "1.0.0-rc.10", "version": "1.0.0-rc.12",
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz",
"integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==", "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==",
"dependencies": { "dependencies": {
"cheerio-select": "^1.5.0", "cheerio-select": "^2.1.0",
"dom-serializer": "^1.3.2", "dom-serializer": "^2.0.0",
"domhandler": "^4.2.0", "domhandler": "^5.0.3",
"htmlparser2": "^6.1.0", "domutils": "^3.0.1",
"parse5": "^6.0.1", "htmlparser2": "^8.0.1",
"parse5-htmlparser2-tree-adapter": "^6.0.1", "parse5": "^7.0.0",
"tslib": "^2.2.0" "parse5-htmlparser2-tree-adapter": "^7.0.0"
}, },
"engines": { "engines": {
"node": ">= 6" "node": ">= 6"
@ -1805,20 +1806,134 @@
} }
}, },
"node_modules/cheerio-select": { "node_modules/cheerio-select": {
"version": "1.5.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.5.0.tgz", "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
"integrity": "sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==", "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
"dependencies": { "dependencies": {
"css-select": "^4.1.3", "boolbase": "^1.0.0",
"css-what": "^5.0.1", "css-select": "^5.1.0",
"domelementtype": "^2.2.0", "css-what": "^6.1.0",
"domhandler": "^4.2.0", "domelementtype": "^2.3.0",
"domutils": "^2.7.0" "domhandler": "^5.0.3",
"domutils": "^3.0.1"
}, },
"funding": { "funding": {
"url": "https://github.com/sponsors/fb55" "url": "https://github.com/sponsors/fb55"
} }
}, },
"node_modules/cheerio-select/node_modules/dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
},
"funding": {
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
"node_modules/cheerio-select/node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dependencies": {
"domelementtype": "^2.3.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/cheerio-select/node_modules/domutils": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
"integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
"dependencies": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.1"
},
"funding": {
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/cheerio-select/node_modules/entities": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.3.0.tgz",
"integrity": "sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg==",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/cheerio/node_modules/dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
},
"funding": {
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
"node_modules/cheerio/node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dependencies": {
"domelementtype": "^2.3.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/cheerio/node_modules/domutils": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
"integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
"dependencies": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.1"
},
"funding": {
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/cheerio/node_modules/entities": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.3.0.tgz",
"integrity": "sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg==",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/cheerio/node_modules/parse5": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.0.0.tgz",
"integrity": "sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==",
"dependencies": {
"entities": "^4.3.0"
},
"funding": {
"url": "https://github.com/inikulin/parse5?sponsor=1"
}
},
"node_modules/chokidar": { "node_modules/chokidar": {
"version": "3.5.3", "version": "3.5.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
@ -2065,24 +2180,75 @@
} }
}, },
"node_modules/css-select": { "node_modules/css-select": {
"version": "4.2.1", "version": "5.1.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-4.2.1.tgz", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
"integrity": "sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==", "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
"dependencies": { "dependencies": {
"boolbase": "^1.0.0", "boolbase": "^1.0.0",
"css-what": "^5.1.0", "css-what": "^6.1.0",
"domhandler": "^4.3.0", "domhandler": "^5.0.2",
"domutils": "^2.8.0", "domutils": "^3.0.1",
"nth-check": "^2.0.1" "nth-check": "^2.0.1"
}, },
"funding": { "funding": {
"url": "https://github.com/sponsors/fb55" "url": "https://github.com/sponsors/fb55"
} }
}, },
"node_modules/css-select/node_modules/dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
},
"funding": {
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
"node_modules/css-select/node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dependencies": {
"domelementtype": "^2.3.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/css-select/node_modules/domutils": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
"integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
"dependencies": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.1"
},
"funding": {
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/css-select/node_modules/entities": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.3.0.tgz",
"integrity": "sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg==",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/css-what": { "node_modules/css-what": {
"version": "5.1.0", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
"integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==", "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
"engines": { "engines": {
"node": ">= 6" "node": ">= 6"
}, },
@ -2352,6 +2518,7 @@
"version": "1.3.2", "version": "1.3.2",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
"integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==",
"dev": true,
"dependencies": { "dependencies": {
"domelementtype": "^2.0.1", "domelementtype": "^2.0.1",
"domhandler": "^4.2.0", "domhandler": "^4.2.0",
@ -2362,9 +2529,9 @@
} }
}, },
"node_modules/domelementtype": { "node_modules/domelementtype": {
"version": "2.2.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
"integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
"funding": [ "funding": [
{ {
"type": "github", "type": "github",
@ -2388,6 +2555,7 @@
"version": "4.3.0", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz",
"integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==", "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==",
"dev": true,
"dependencies": { "dependencies": {
"domelementtype": "^2.2.0" "domelementtype": "^2.2.0"
}, },
@ -2402,6 +2570,7 @@
"version": "2.8.0", "version": "2.8.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
"integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
"dev": true,
"dependencies": { "dependencies": {
"dom-serializer": "^1.0.1", "dom-serializer": "^1.0.1",
"domelementtype": "^2.2.0", "domelementtype": "^2.2.0",
@ -2530,6 +2699,7 @@
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
"integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
"dev": true,
"funding": { "funding": {
"url": "https://github.com/fb55/entities?sponsor=1" "url": "https://github.com/fb55/entities?sponsor=1"
} }
@ -3904,9 +4074,9 @@
"dev": true "dev": true
}, },
"node_modules/htmlparser2": { "node_modules/htmlparser2": {
"version": "6.1.0", "version": "8.0.1",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz",
"integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==",
"funding": [ "funding": [
"https://github.com/fb55/htmlparser2?sponsor=1", "https://github.com/fb55/htmlparser2?sponsor=1",
{ {
@ -3915,10 +4085,61 @@
} }
], ],
"dependencies": { "dependencies": {
"domelementtype": "^2.0.1", "domelementtype": "^2.3.0",
"domhandler": "^4.0.0", "domhandler": "^5.0.2",
"domutils": "^2.5.2", "domutils": "^3.0.1",
"entities": "^2.0.0" "entities": "^4.3.0"
}
},
"node_modules/htmlparser2/node_modules/dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
},
"funding": {
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
"node_modules/htmlparser2/node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dependencies": {
"domelementtype": "^2.3.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/htmlparser2/node_modules/domutils": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
"integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
"dependencies": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.1"
},
"funding": {
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/htmlparser2/node_modules/entities": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.3.0.tgz",
"integrity": "sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg==",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
} }
}, },
"node_modules/http-cache-semantics": { "node_modules/http-cache-semantics": {
@ -4922,9 +5143,9 @@
} }
}, },
"node_modules/nth-check": { "node_modules/nth-check": {
"version": "2.0.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
"integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
"dependencies": { "dependencies": {
"boolbase": "^1.0.0" "boolbase": "^1.0.0"
}, },
@ -5257,14 +5478,55 @@
"node_modules/parse5": { "node_modules/parse5": {
"version": "6.0.1", "version": "6.0.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
"integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
"dev": true
}, },
"node_modules/parse5-htmlparser2-tree-adapter": { "node_modules/parse5-htmlparser2-tree-adapter": {
"version": "6.0.1", "version": "7.0.0",
"resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz",
"integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==",
"dependencies": { "dependencies": {
"parse5": "^6.0.1" "domhandler": "^5.0.2",
"parse5": "^7.0.0"
},
"funding": {
"url": "https://github.com/inikulin/parse5?sponsor=1"
}
},
"node_modules/parse5-htmlparser2-tree-adapter/node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dependencies": {
"domelementtype": "^2.3.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/parse5-htmlparser2-tree-adapter/node_modules/entities": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.3.0.tgz",
"integrity": "sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg==",
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.0.0.tgz",
"integrity": "sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==",
"dependencies": {
"entities": "^4.3.0"
},
"funding": {
"url": "https://github.com/inikulin/parse5?sponsor=1"
} }
}, },
"node_modules/path-exists": { "node_modules/path-exists": {
@ -6686,11 +6948,6 @@
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
"devOptional": true "devOptional": true
}, },
"node_modules/tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"node_modules/tsutils": { "node_modules/tsutils": {
"version": "3.21.0", "version": "3.21.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
@ -8754,7 +9011,7 @@
"boolbase": { "boolbase": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
}, },
"boxen": { "boxen": {
"version": "5.1.2", "version": "5.1.2",
@ -8945,29 +9202,108 @@
"dev": true "dev": true
}, },
"cheerio": { "cheerio": {
"version": "1.0.0-rc.10", "version": "1.0.0-rc.12",
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz",
"integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==", "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==",
"requires": { "requires": {
"cheerio-select": "^1.5.0", "cheerio-select": "^2.1.0",
"dom-serializer": "^1.3.2", "dom-serializer": "^2.0.0",
"domhandler": "^4.2.0", "domhandler": "^5.0.3",
"htmlparser2": "^6.1.0", "domutils": "^3.0.1",
"parse5": "^6.0.1", "htmlparser2": "^8.0.1",
"parse5-htmlparser2-tree-adapter": "^6.0.1", "parse5": "^7.0.0",
"tslib": "^2.2.0" "parse5-htmlparser2-tree-adapter": "^7.0.0"
},
"dependencies": {
"dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"requires": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
}
},
"domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"requires": {
"domelementtype": "^2.3.0"
}
},
"domutils": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
"integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
"requires": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.1"
}
},
"entities": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.3.0.tgz",
"integrity": "sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg=="
},
"parse5": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.0.0.tgz",
"integrity": "sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==",
"requires": {
"entities": "^4.3.0"
}
}
} }
}, },
"cheerio-select": { "cheerio-select": {
"version": "1.5.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.5.0.tgz", "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
"integrity": "sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==", "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
"requires": { "requires": {
"css-select": "^4.1.3", "boolbase": "^1.0.0",
"css-what": "^5.0.1", "css-select": "^5.1.0",
"domelementtype": "^2.2.0", "css-what": "^6.1.0",
"domhandler": "^4.2.0", "domelementtype": "^2.3.0",
"domutils": "^2.7.0" "domhandler": "^5.0.3",
"domutils": "^3.0.1"
},
"dependencies": {
"dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"requires": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
}
},
"domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"requires": {
"domelementtype": "^2.3.0"
}
},
"domutils": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
"integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
"requires": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.1"
}
},
"entities": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.3.0.tgz",
"integrity": "sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg=="
}
} }
}, },
"chokidar": { "chokidar": {
@ -9170,21 +9506,56 @@
"dev": true "dev": true
}, },
"css-select": { "css-select": {
"version": "4.2.1", "version": "5.1.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-4.2.1.tgz", "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
"integrity": "sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ==", "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
"requires": { "requires": {
"boolbase": "^1.0.0", "boolbase": "^1.0.0",
"css-what": "^5.1.0", "css-what": "^6.1.0",
"domhandler": "^4.3.0", "domhandler": "^5.0.2",
"domutils": "^2.8.0", "domutils": "^3.0.1",
"nth-check": "^2.0.1" "nth-check": "^2.0.1"
},
"dependencies": {
"dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"requires": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
}
},
"domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"requires": {
"domelementtype": "^2.3.0"
}
},
"domutils": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
"integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
"requires": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.1"
}
},
"entities": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.3.0.tgz",
"integrity": "sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg=="
}
} }
}, },
"css-what": { "css-what": {
"version": "5.1.0", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-5.1.0.tgz", "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
"integrity": "sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==" "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw=="
}, },
"cssesc": { "cssesc": {
"version": "3.0.0", "version": "3.0.0",
@ -9377,6 +9748,7 @@
"version": "1.3.2", "version": "1.3.2",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
"integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==",
"dev": true,
"requires": { "requires": {
"domelementtype": "^2.0.1", "domelementtype": "^2.0.1",
"domhandler": "^4.2.0", "domhandler": "^4.2.0",
@ -9384,9 +9756,9 @@
} }
}, },
"domelementtype": { "domelementtype": {
"version": "2.2.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
"integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==" "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw=="
}, },
"domexception": { "domexception": {
"version": "4.0.0", "version": "4.0.0",
@ -9401,6 +9773,7 @@
"version": "4.3.0", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz",
"integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==", "integrity": "sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g==",
"dev": true,
"requires": { "requires": {
"domelementtype": "^2.2.0" "domelementtype": "^2.2.0"
} }
@ -9409,6 +9782,7 @@
"version": "2.8.0", "version": "2.8.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
"integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
"dev": true,
"requires": { "requires": {
"dom-serializer": "^1.0.1", "dom-serializer": "^1.0.1",
"domelementtype": "^2.2.0", "domelementtype": "^2.2.0",
@ -9523,7 +9897,8 @@
"entities": { "entities": {
"version": "2.2.0", "version": "2.2.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
"integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
"dev": true
}, },
"error-ex": { "error-ex": {
"version": "1.3.2", "version": "1.3.2",
@ -10460,14 +10835,49 @@
"dev": true "dev": true
}, },
"htmlparser2": { "htmlparser2": {
"version": "6.1.0", "version": "8.0.1",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz",
"integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==",
"requires": { "requires": {
"domelementtype": "^2.0.1", "domelementtype": "^2.3.0",
"domhandler": "^4.0.0", "domhandler": "^5.0.2",
"domutils": "^2.5.2", "domutils": "^3.0.1",
"entities": "^2.0.0" "entities": "^4.3.0"
},
"dependencies": {
"dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"requires": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
}
},
"domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"requires": {
"domelementtype": "^2.3.0"
}
},
"domutils": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
"integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
"requires": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.1"
}
},
"entities": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.3.0.tgz",
"integrity": "sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg=="
}
} }
}, },
"http-cache-semantics": { "http-cache-semantics": {
@ -11221,9 +11631,9 @@
"integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A=="
}, },
"nth-check": { "nth-check": {
"version": "2.0.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
"integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
"requires": { "requires": {
"boolbase": "^1.0.0" "boolbase": "^1.0.0"
} }
@ -11481,14 +11891,39 @@
"parse5": { "parse5": {
"version": "6.0.1", "version": "6.0.1",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
"integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
"dev": true
}, },
"parse5-htmlparser2-tree-adapter": { "parse5-htmlparser2-tree-adapter": {
"version": "6.0.1", "version": "7.0.0",
"resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz",
"integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==",
"requires": { "requires": {
"parse5": "^6.0.1" "domhandler": "^5.0.2",
"parse5": "^7.0.0"
},
"dependencies": {
"domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"requires": {
"domelementtype": "^2.3.0"
}
},
"entities": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.3.0.tgz",
"integrity": "sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg=="
},
"parse5": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-7.0.0.tgz",
"integrity": "sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g==",
"requires": {
"entities": "^4.3.0"
}
}
} }
}, },
"path-exists": { "path-exists": {
@ -12575,11 +13010,6 @@
} }
} }
}, },
"tslib": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
"integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw=="
},
"tsutils": { "tsutils": {
"version": "3.21.0", "version": "3.21.0",
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",

View file

@ -1,5 +1,5 @@
{ {
"version": "1.2.0", "version": "1.4.0",
"scripts": { "scripts": {
"dev": "concurrently --kill-others \"npm run dev:frontend\" \"npm run dev:backend\"", "dev": "concurrently --kill-others \"npm run dev:frontend\" \"npm run dev:backend\"",
"demo": "npm run build && prisma migrate deploy && prisma migrate reset -f && node dist/api/server.js", "demo": "npm run build && prisma migrate deploy && prisma migrate reset -f && node dist/api/server.js",
@ -14,7 +14,9 @@
"coverage": "vitest run --environment jsdom --coverage", "coverage": "vitest run --environment jsdom --coverage",
"typecheck": "vue-tsc --noEmit", "typecheck": "vue-tsc --noEmit",
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
"prepare": "husky install" "prepare": "husky install",
"preversion": "git pull --ff-only",
"postversion": "git push --follow-tags"
}, },
"prisma": { "prisma": {
"seed": "ts-node prisma/seed.ts" "seed": "ts-node prisma/seed.ts"
@ -24,6 +26,7 @@
"@tailwindcss/line-clamp": "^0.3.1", "@tailwindcss/line-clamp": "^0.3.1",
"@vueuse/core": "^7.6.1", "@vueuse/core": "^7.6.1",
"axios": "^0.25.0", "axios": "^0.25.0",
"cheerio": "^1.0.0-rc.12",
"fastify": "^3.27.1", "fastify": "^3.27.1",
"fastify-compress": "^4.0.1", "fastify-compress": "^4.0.1",
"fastify-cors": "^6.0.2", "fastify-cors": "^6.0.2",

View file

@ -0,0 +1,63 @@
import { FastifyRequest, FastifyReply, RouteOptions } from 'fastify'
import ogs, { OpenGraphImage } from 'open-graph-scraper'
import axios from 'axios'
import cheerio from 'cheerio'
interface fetchMetaDataRequest extends FastifyRequest {
query: {
url: string
}
}
export const fetchMetaData = <RouteOptions>{
method: 'GET',
url: '/fetch-meta-data-from-url',
schema: {
querystring: {
type: 'object',
required: ['url'],
properties: {
url: { type: 'string', format: 'uri' },
},
},
response: {
200: {
type: 'object',
properties: {
title: { type: 'string' },
description: { type: 'string' },
imageSrc: { type: 'string' },
},
},
},
},
handler: async (request: fetchMetaDataRequest, reply: FastifyReply) => {
const url = request.query.url
const response = {
title: '',
description: '',
imageSrc: '',
}
if (url.includes('amazon.de')) {
const { data } = await axios.get(url)
const $ = cheerio.load(data)
response.title = $('#productTitle').text().trim() || ''
response.description = response.title
response.imageSrc = ($('#landingImage').attr('src') || '').trim()
} else {
const { result } = await ogs({
url: request.query.url,
})
request.log.debug(result)
if (result.success) {
response.imageSrc =
result.ogImage && (result.ogImage as OpenGraphImage).url
? (result.ogImage as OpenGraphImage).url
: ''
response.title = result.ogTitle || ''
response.description = result.ogDescription || ''
}
}
reply.send(response)
},
}

View file

@ -1,6 +1,6 @@
import { FastifyInstance } from 'fastify' import { FastifyInstance } from 'fastify'
import { fetchOpenGraph } from './opengraph' import { fetchMetaData } from './fetchmetadata'
export default async (app: FastifyInstance) => { export default async (app: FastifyInstance) => {
await app.route(fetchOpenGraph) await app.route(fetchMetaData)
} }

View file

@ -1,49 +0,0 @@
import { FastifyRequest, FastifyReply, RouteOptions } from 'fastify'
import ogs, { OpenGraphImage } from 'open-graph-scraper'
interface fetchOpenGraphRequest extends FastifyRequest {
query: {
url: string
}
}
export const fetchOpenGraph = <RouteOptions>{
method: 'GET',
url: '/fetch-open-graph',
schema: {
querystring: {
type: 'object',
required: ['url'],
properties: {
url: { type: 'string', format: 'uri' },
},
},
response: {
200: {
type: 'object',
properties: {
title: { type: 'string' },
description: { type: 'string' },
imageSrc: { type: 'string' },
},
},
},
},
handler: async (request: fetchOpenGraphRequest, reply: FastifyReply) => {
const { result } = await ogs({
url: request.query.url,
})
request.log.debug(result)
if (result.success) {
const image =
result.ogImage && (result.ogImage as OpenGraphImage).url
? (result.ogImage as OpenGraphImage).url
: ''
reply.send({
title: result.ogTitle || '',
description: result.ogDescription || '',
imageSrc: image,
})
}
},
}

View file

@ -44,9 +44,11 @@ const openUrl = (): void => {
{{ item.description }} {{ item.description }}
</p> </p>
</div> </div>
<div class="flex flex-row items-baseline space-x-2"> <div
class="mt-4 flex w-full flex-row flex-wrap-reverse items-baseline sm:mt-2"
>
<ButtonBase <ButtonBase
class="mt-4 text-xs sm:mt-2" class="mr-4 mt-4 text-xs sm:mt-0"
:icon="IconCart" :icon="IconCart"
@click="$emit('bought')" @click="$emit('bought')"
data-test="bought-button" data-test="bought-button"
@ -58,7 +60,7 @@ const openUrl = (): void => {
target="_blank" target="_blank"
rel="noopener" rel="noopener"
data-test="link" data-test="link"
class="mt-1 flex w-fit flex-row items-center text-sm text-stone-500 dark:text-white/60" class="flex w-fit flex-row items-center text-sm text-stone-500 dark:text-white/60"
> >
<IconLink class="mr-1 h-4 w-4 fill-stone-500 dark:fill-white/60" /> <IconLink class="mr-1 h-4 w-4 fill-stone-500 dark:fill-white/60" />
<span>{{ <span>{{

View file

@ -130,7 +130,7 @@
"text": "Produktseite öffnen" "text": "Produktseite öffnen"
}, },
"bought-button": { "bought-button": {
"text": "Gekauft" "text": "Als gekauft markieren"
} }
}, },
"form-wishlist": { "form-wishlist": {

View file

@ -130,7 +130,7 @@
"text": "Open product page" "text": "Open product page"
}, },
"bought-button": { "bought-button": {
"text": "Bought" "text": "Mark as purchased"
} }
}, },
"form-wishlist": { "form-wishlist": {

View file

@ -36,7 +36,7 @@ fetch()
if (route.query.url) { if (route.query.url) {
prefillData.value.url = route.query.url as string prefillData.value.url = route.query.url as string
const { data: opData, isFinished: opDataLoaded } = useFetch( const { data: opData, isFinished: opDataLoaded } = useFetch(
`/utils/fetch-open-graph?url=${route.query.url}` `/utils/fetch-meta-data-from-url?url=${route.query.url}`
).json() ).json()
syncRef(opDataLoaded, isFinished) syncRef(opDataLoaded, isFinished)