diff --git a/client/src/componets/AddBlogs.js b/client/src/componets/AddBlogs.js index f2eb4a97..005e9e11 100644 --- a/client/src/componets/AddBlogs.js +++ b/client/src/componets/AddBlogs.js @@ -10,32 +10,45 @@ const labelStyles = { mb: 1, mt: 2, fontSize: "24px", fontWeight: "bold" }; const AddBlogs = () => { const classes = useStyles(); const navigate = useNavigate(); - const [inputs, setInputs] = useState({ - title: "", - description: "", - imageURL: "", - }); - const handleChange = (e) => { - setInputs((prevState) => ({ - ...prevState, - [e.target.name]: e.target.value, - })); - }; + + // added useState variables removed input and handlechange method + const [title,setTitle] = useState(""); + const [desc,setDesc] = useState(""); + const [image,setImage] = useState(""); + // const [inputs, setInputs] = useState({ + // title: "", + // description: "", + // imageURL: "", + // }); + // const handleChange = (e) => { + // setInputs((prevState) => ({ + // ...prevState, + // [e.target.name]: e.target.value, + // })); + // }; const sendRequest = async () => { + const formdata = new FormData(); + // console.log(title,desc,image) + formdata.append('title',title); + formdata.append('desc',desc); + formdata.append('image',image); + formdata.append('user',localStorage.getItem('userId')); + // removed object data { + // title: inputs.title, + // desc: inputs.description, + // img: inputs.imageURL, + // user: localStorage.getItem("userId"), + // } + // from axios added formdata const res = await axios - .post(`${config.BASE_URL}/api/blogs/add`, { - title: inputs.title, - desc: inputs.description, - img: inputs.imageURL, - user: localStorage.getItem("userId"), - }) + .post(`${config.BASE_URL}/api/blogs/add`,formdata ) .catch((err) => console.log(err)); const data = await res.data; return data; }; const handleSubmit = (e) => { e.preventDefault(); - console.log(inputs); + // console.log(inputs); sendRequest() .then((data) => console.log(data)) .then(() => navigate("/blogs")); @@ -68,8 +81,9 @@ const AddBlogs = () => { setTitle(e.target.value)} + // value={inputs.title} margin="auto" variant="outlined" /> @@ -78,21 +92,23 @@ const AddBlogs = () => { setDesc(e.target.value)} minRows={10} margin="auto" variant="outlined" - value={inputs.description} + // value={inputs.description} /> ImageURL setImage(e.target.files[0])} + // value={inputs.imageURL} margin="auto" variant="outlined" /> diff --git a/client/src/componets/Blog.js b/client/src/componets/Blog.js index ae161a10..d6d22282 100644 --- a/client/src/componets/Blog.js +++ b/client/src/componets/Blog.js @@ -70,7 +70,7 @@ const Blogs = ({ title, desc, img, user, isUser, id }) => { } title={title} /> - +
diff --git a/client/src/componets/Blogs.js b/client/src/componets/Blogs.js index 959d98cb..e59eb7dd 100644 --- a/client/src/componets/Blogs.js +++ b/client/src/componets/Blogs.js @@ -25,7 +25,7 @@ const Blogs = () => { isUser={localStorage.getItem("userId") === blog.user._id} title={blog.title} desc={blog.desc} - img={blog.img} + img={`${config.BASE_URL}/${blog?.imgUrl}`} user={blog.user.name} date={new Date(blog.date).toLocaleDateString()} /> diff --git a/server/controller/blog-controller.js b/server/controller/blog-controller.js index 0085b2e5..64911459 100644 --- a/server/controller/blog-controller.js +++ b/server/controller/blog-controller.js @@ -2,7 +2,7 @@ const mongoose = require("mongoose"); const { findByIdAndRemove } = require("../model/Blog"); const Blog = require("../model/Blog"); const User = require("../model/User"); - +// const path = require('path') const getAllBlogs = async(req,res,next) =>{ let blogs; try{ @@ -53,7 +53,11 @@ const getAllBlogs = async(req,res,next) =>{ const addBlog = async(req,res,next) =>{ - const { title , desc , img , user } = req.body; + // const { title , desc , img , user } = req.body; + const title = req.body.title; + const desc = req.body.desc; + const imgUrl = req.file.path; + const user = req.body.user; const currentDate = new Date(); @@ -69,7 +73,7 @@ const addBlog = async(req,res,next) =>{ const blog = new Blog({ - title ,desc , img , user, date: currentDate + title ,desc , imgUrl , user, date: currentDate }); try { diff --git a/server/model/Blog.js b/server/model/Blog.js index 5661287f..fc25dad3 100644 --- a/server/model/Blog.js +++ b/server/model/Blog.js @@ -11,7 +11,8 @@ const blogSchema = new Schema({ type: String, required: true, }, - img : { + //img-->imgUrl + imgUrl : { type: String, required: true, }, diff --git a/server/package.json b/server/package.json index 5bc27252..890f3798 100644 --- a/server/package.json +++ b/server/package.json @@ -1,73 +1,78 @@ -{ - - - "name": "blogapp", - - - "version": "1.0.0", - - - "description": "", - - - "main": "server.js", - - - "scripts": { - - - - - "start": "nodemon server.js", - - - - - "test": "echo \"Error: no test specified\" && exit 1" - - - }, - - - "author": "khushi patel", - - - "license": "ISC", - - - "devDependencies": { - - - - - "nodemon": "^2.0.16" - - - }, - - - "dependencies": { - - - - - "bcryptjs": "^2.4.3", - - - - - "cors": "^2.8.5", - - - - - "express": "^4.18.1", - - - - - "mongoose": "^6.3.4" - - - } -} +{ + + + "name": "blogapp", + + + "version": "1.0.0", + + + "description": "", + + + "main": "server.js", + + + "scripts": { + + + + + "start": "nodemon server.js", + + + + + "test": "echo \"Error: no test specified\" && exit 1" + + + }, + + + "author": "khushi patel", + + + "license": "ISC", + + + "devDependencies": { + + + + + "nodemon": "^2.0.16" + + + }, + + + "dependencies": { + + + + + "bcryptjs": "^2.4.3", + + + + + "cors": "^2.8.5", + + + + + "express": "^4.18.1", + + + + + "mongoose": "^6.3.4", + + + + + "multer": "^1.4.5-lts.2" + + + } +} diff --git a/server/routes/blog-routes.js b/server/routes/blog-routes.js index 549697a6..a7cac6c9 100644 --- a/server/routes/blog-routes.js +++ b/server/routes/blog-routes.js @@ -3,9 +3,25 @@ const blogRouter = express.Router(); const { getAllBlogs , addBlog , updateBlog ,getById , deleteBlog , getByUserId} = require("../controller/blog-controller"); +const multer = require('multer') + +// defined disk storage for multer + +const storage = multer.diskStorage({ + destination: function (req, file, cb) { + cb(null, "uploads"); + }, + filename: function (req, file, cb) { + cb(null, file.originalname); + }, + }); + +// used multer for storing images + +let upload = multer({storage:storage}) blogRouter.get("/",getAllBlogs); -blogRouter.post('/add', addBlog); +blogRouter.post('/add',upload.single("image"), addBlog); blogRouter.put("/update/:id", updateBlog); blogRouter.get("/:id", getById); blogRouter.delete("/:id",deleteBlog); diff --git a/server/server.js b/server/server.js index a1e17658..12d59b9d 100644 --- a/server/server.js +++ b/server/server.js @@ -5,9 +5,14 @@ require("./config/db"); const cors = require("cors"); const app = express(); +const path = require('path') + app.use(cors()); +// defined path for serving the upload folder +app.use('/uploads',express.static(path.join(__dirname,'uploads'))); + app.set("view engine", "ejs"); app.use(express.json()); diff --git a/server/uploads/kalen-emsley-Bkci_8qcdvQ-unsplash.jpg b/server/uploads/kalen-emsley-Bkci_8qcdvQ-unsplash.jpg new file mode 100644 index 00000000..512f92d4 Binary files /dev/null and b/server/uploads/kalen-emsley-Bkci_8qcdvQ-unsplash.jpg differ diff --git a/server/uploads/man-meditating-front-majestic-mountain-peak_1282444-242951.jpg b/server/uploads/man-meditating-front-majestic-mountain-peak_1282444-242951.jpg new file mode 100644 index 00000000..408cab34 Binary files /dev/null and b/server/uploads/man-meditating-front-majestic-mountain-peak_1282444-242951.jpg differ diff --git a/server/yarn.lock b/server/yarn.lock index 430e9ed5..a000e666 100644 --- a/server/yarn.lock +++ b/server/yarn.lock @@ -918,6 +918,11 @@ anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" +append-field@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz" + integrity sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw== + array-flatten@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" @@ -988,6 +993,11 @@ bson@^4.7.2: dependencies: buffer "^5.6.0" +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + buffer@^5.6.0: version "5.7.1" resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" @@ -996,6 +1006,13 @@ buffer@^5.6.0: base64-js "^1.3.1" ieee754 "^1.1.13" +busboy@^1.0.0: + version "1.6.0" + resolved "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz" + integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== + dependencies: + streamsearch "^1.1.0" + bytes@3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" @@ -1032,6 +1049,16 @@ concat-map@0.0.1: resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== +concat-stream@^1.5.2: + version "1.6.2" + resolved "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + content-disposition@0.5.4: version "0.5.4" resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" @@ -1054,6 +1081,11 @@ cookie@0.5.0: resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + cors@^2.8.5: version "2.8.5" resolved "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz" @@ -1208,11 +1240,6 @@ fresh@0.5.2: resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== -fsevents@~2.3.2: - version "2.3.3" - resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" - integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== - function-bind@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" @@ -1300,7 +1327,7 @@ ignore-by-default@^1.0.1: resolved "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz" integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== -inherits@2.0.4: +inherits@^2.0.3, inherits@~2.0.3, inherits@2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -1342,6 +1369,11 @@ is-number@^7.0.0: resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + jsbn@1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz" @@ -1396,6 +1428,18 @@ minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" +minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +mkdirp@^0.5.4: + version "0.5.6" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + mongodb-connection-string-url@^2.6.0: version "2.6.0" resolved "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz" @@ -1461,6 +1505,19 @@ ms@2.1.3: resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +multer@^1.4.5-lts.2: + version "1.4.5-lts.2" + resolved "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.2.tgz" + integrity sha512-VzGiVigcG9zUAoCNU+xShztrlr1auZOlurXynNvO9GiWD1/mTBbUljOKY+qMeazBqXgRnjzeEgJI/wyjJUHg9A== + dependencies: + append-field "^1.0.0" + busboy "^1.0.0" + concat-stream "^1.5.2" + mkdirp "^0.5.4" + object-assign "^4.1.1" + type-is "^1.6.4" + xtend "^4.0.0" + negotiator@0.6.3: version "0.6.3" resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" @@ -1494,7 +1551,7 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -object-assign@^4: +object-assign@^4, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== @@ -1526,6 +1583,11 @@ picomatch@^2.0.4, picomatch@^2.2.1: resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz" @@ -1566,6 +1628,19 @@ raw-body@2.5.2: iconv-lite "0.4.24" unpipe "1.0.0" +readable-stream@^2.2.2: + version "2.3.8" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + readdirp@~3.6.0: version "3.6.0" resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" @@ -1573,6 +1648,16 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" +safe-buffer@~5.1.0: + version "5.1.2" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + safe-buffer@5.2.1: version "5.2.1" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" @@ -1691,6 +1776,18 @@ statuses@2.0.1: resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== +streamsearch@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz" + integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + strnum@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz" @@ -1739,7 +1836,7 @@ tslib@^2.3.1, tslib@^2.5.0: resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== -type-is@~1.6.18: +type-is@^1.6.4, type-is@~1.6.18: version "1.6.18" resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== @@ -1747,6 +1844,11 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz" + integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== + undefsafe@^2.0.5: version "2.0.5" resolved "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz" @@ -1762,6 +1864,11 @@ unpipe@~1.0.0, unpipe@1.0.0: resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + utils-merge@1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" @@ -1789,3 +1896,8 @@ whatwg-url@^11.0.0: dependencies: tr46 "^3.0.0" webidl-conversions "^7.0.0" + +xtend@^4.0.0: + version "4.0.2" + resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==