feat: client app can now upload images for beer posts

Updated seed to incorporate cloudinary images, downgraded multer to recent LTS, update tsconfig to allow spread operator usage on FileList.
This commit is contained in:
Aaron William Po
2023-05-07 21:05:21 -04:00
parent b457508a9b
commit f21dc905fe
15 changed files with 305 additions and 392 deletions

View File

@@ -2,7 +2,7 @@
const nextConfig = {
reactStrictMode: true,
images: {
domains: ['picsum.photos'],
domains: ['picsum.photos', 'res.cloudinary.com'],
},
};

524
package-lock.json generated
View File

@@ -26,7 +26,7 @@
"jsonwebtoken": "^9.0.0",
"lodash": "^4.17.21",
"mapbox-gl": "^2.14.1",
"multer": "^2.0.0-rc.4",
"multer": "^1.4.5-lts.1",
"multer-storage-cloudinary": "^4.0.0",
"next": "^13.3.4",
"next-connect": "^1.0.0-next.3",
@@ -618,17 +618,6 @@
"npm": ">=6.0.0"
}
},
"node_modules/@fastify/busboy": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-1.2.1.tgz",
"integrity": "sha512-7PQA7EH43S0CxcOa9OeAnaeA0oQ+e/DHNPZwSQM9CQHW76jle5+OvLdibRp/Aafs9KXbLhxyjOTkRjWUbQEd3Q==",
"dependencies": {
"text-decoding": "^1.0.0"
},
"engines": {
"node": ">=14"
}
},
"node_modules/@hapi/b64": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@hapi/b64/-/b64-6.0.1.tgz",
@@ -1675,11 +1664,6 @@
"node": ">=10"
}
},
"node_modules/@tokenizer/token": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
"integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="
},
"node_modules/@tootallnate/once": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
@@ -2532,12 +2516,9 @@
}
},
"node_modules/append-field": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/append-field/-/append-field-2.0.0.tgz",
"integrity": "sha512-yUPXgerKgcuwakzrRyklfhX+Ma2aYYMjb+BO2RPUwq+tk928V/i5DFWcCUS3hQhj468N+Ktmwb0tfbEtmfC6WA==",
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz",
"integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw=="
},
"node_modules/aproba": {
"version": "2.0.0",
@@ -2828,17 +2809,6 @@
"resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz",
"integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA=="
},
"node_modules/base32-encode": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/base32-encode/-/base32-encode-2.0.0.tgz",
"integrity": "sha512-mlmkfc2WqdDtMl/id4qm3A7RjW6jxcbAoMjdRmsPiwQP0ufD4oXItYMnPgVHe80lnAIy+1xwzhHE1s4FoIceSw==",
"dependencies": {
"to-data-view": "^2.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
@@ -3007,6 +2977,11 @@
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
},
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
},
"node_modules/buffer-indexof-polyfill": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz",
@@ -3053,6 +3028,7 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
"optional": true,
"engines": {
"node": ">= 0.8"
}
@@ -3405,6 +3381,52 @@
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
},
"node_modules/concat-stream": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
"integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
"engines": [
"node >= 0.8"
],
"dependencies": {
"buffer-from": "^1.0.0",
"inherits": "^2.0.3",
"readable-stream": "^2.2.2",
"typedarray": "^0.0.6"
}
},
"node_modules/concat-stream/node_modules/isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
},
"node_modules/concat-stream/node_modules/readable-stream": {
"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"
}
},
"node_modules/concat-stream/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"node_modules/concat-stream/node_modules/string_decoder": {
"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"
}
},
"node_modules/condense-newlines": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/condense-newlines/-/condense-newlines-0.2.1.tgz",
@@ -4238,11 +4260,6 @@
"resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
"integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A=="
},
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
},
"node_modules/electron-to-chromium": {
"version": "1.4.380",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.380.tgz",
@@ -4254,14 +4271,6 @@
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
"dev": true
},
"node_modules/encode-utf8": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-2.0.0.tgz",
"integrity": "sha512-3EyMFxZj1/7oMotElDQUEQcP7N4TIe1aJ0m1uBDoyQ8I2LBHhBsXx8P3KsPbqNlGzG+NYxFwEauUwMPHZg3YDQ==",
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
"node_modules/end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
@@ -5264,22 +5273,6 @@
"node": "^10.12.0 || >=12.0.0"
}
},
"node_modules/file-type": {
"version": "16.5.4",
"resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz",
"integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==",
"dependencies": {
"readable-web-to-node-stream": "^3.0.0",
"strtok3": "^6.2.4",
"token-types": "^4.1.1"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sindresorhus/file-type?sponsor=1"
}
},
"node_modules/file-uri-to-path": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz",
@@ -5335,14 +5328,6 @@
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
"dev": true
},
"node_modules/fmix": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fmix/-/fmix-1.0.0.tgz",
"integrity": "sha512-PIaqOGvVH5P+R92Ywy5PumsNEHvondVQh42SGOmkA9A0ZTFbfguzZpjZ/Gy3WVRUqT9Ia8k5tWlJeiZQzRHA7g==",
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
"node_modules/for-each": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
@@ -5425,17 +5410,6 @@
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/fs-temp": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/fs-temp/-/fs-temp-2.0.1.tgz",
"integrity": "sha512-WYE7cUGOA0xRKsiYxNf/+WDuj0T20OtX85bVhsXpY+wJmjrRIUQftTI6JF9PVpo2RpGkh0l8lZsV8zszisYQ0Q==",
"dependencies": {
"random-path": "^1.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -5854,14 +5828,6 @@
"node": ">=8"
}
},
"node_modules/has-own-property": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-own-property/-/has-own-property-2.0.0.tgz",
"integrity": "sha512-oupojxEPq/nfAshi0hOFDjpmYO4JXtymFyPC9YSBmFqGamZ2zUgrCkYInt5tf7f1j6iumlzJBpfLNRxZIQCM0w==",
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
"node_modules/has-property-descriptors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
@@ -7839,21 +7805,20 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/multer": {
"version": "2.0.0-rc.4",
"resolved": "https://registry.npmjs.org/multer/-/multer-2.0.0-rc.4.tgz",
"integrity": "sha512-YkjV/rOzngEBxtZV8s6BcBcB/z2v/dfDcIpWagmMsKBq0QnQCu/NpCUDd2ElExfnxRXMVXKrFh94/UKe4NdxBQ==",
"version": "1.4.5-lts.1",
"resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz",
"integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==",
"dependencies": {
"@fastify/busboy": "^1.0.0",
"append-field": "^2.0.0",
"bytes": "^3.1.0",
"fs-temp": "^2.0.1",
"has-own-property": "^2.0.0",
"on-finished": "^2.3.0",
"stream-file-type": "^0.6.1",
"type-is": "^1.6.18"
"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"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
"node": ">= 6.0.0"
}
},
"node_modules/multer-storage-cloudinary": {
@@ -7864,16 +7829,15 @@
"cloudinary": "^1.21.0"
}
},
"node_modules/murmur-32": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/murmur-32/-/murmur-32-1.0.0.tgz",
"integrity": "sha512-l6QKUGWXzZWHash7lmZzycpIifOrnc3PeMaoFrMv90c+xqOyOSzJU0q2T/1d15MzAdEWTpCh1paC855APqt1Gw==",
"node_modules/multer/node_modules/mkdirp": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
"integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
"dependencies": {
"encode-utf8": "^2.0.0",
"fmix": "^1.0.0"
"minimist": "^1.2.6"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
"bin": {
"mkdirp": "bin/cmd.js"
}
},
"node_modules/murmurhash-js": {
@@ -8269,17 +8233,6 @@
"resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz",
"integrity": "sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w=="
},
"node_modules/on-finished": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
"dependencies": {
"ee-first": "1.1.1"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -8578,18 +8531,6 @@
"url": "https://ko-fi.com/killymxi"
}
},
"node_modules/peek-readable": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz",
"integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==",
"engines": {
"node": ">=8"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Borewit"
}
},
"node_modules/performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
@@ -9209,18 +9150,6 @@
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz",
"integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw=="
},
"node_modules/random-path": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/random-path/-/random-path-1.0.0.tgz",
"integrity": "sha512-I6FGG7uFR3tZqHP7TzcP3Ikt5IyVEG59u7KTjIIjizcdPY6MDjD9CbbKqE+znIv4mrDF6HMlBshoemk0oRRwsQ==",
"dependencies": {
"base32-encode": "^2.0.0",
"murmur-32": "^1.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
"node_modules/raw-body": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
@@ -9629,21 +9558,6 @@
"node": ">= 6"
}
},
"node_modules/readable-web-to-node-stream": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz",
"integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==",
"dependencies": {
"readable-stream": "^3.6.0"
},
"engines": {
"node": ">=8"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Borewit"
}
},
"node_modules/readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -10270,17 +10184,6 @@
"node": ">= 0.4"
}
},
"node_modules/stream-file-type": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/stream-file-type/-/stream-file-type-0.6.1.tgz",
"integrity": "sha512-//KIXMQan4ow4gD//dfPu15nhH/sFdt41PzAOpD9EBFUBy/MtFjocTPO8v1dTOJnyi47TlPo6Qj+67sSE1lJKA==",
"dependencies": {
"file-type": "^16.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
"node_modules/streamsearch": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
@@ -10428,22 +10331,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/strtok3": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz",
"integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==",
"dependencies": {
"@tokenizer/token": "^0.3.0",
"peek-readable": "^4.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Borewit"
}
},
"node_modules/style-to-js": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.3.tgz",
@@ -10663,11 +10550,6 @@
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
"node_modules/text-decoding": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/text-decoding/-/text-decoding-1.0.0.tgz",
"integrity": "sha512-/0TJD42KDnVwKmDK6jj3xP7E2MG7SHAOG4tyTgyUCRPdHwvkquYNLEQltmdMa3owq3TkddCVcTsoctJI8VQNKA=="
},
"node_modules/text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -10723,14 +10605,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/to-data-view": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-data-view/-/to-data-view-2.0.0.tgz",
"integrity": "sha512-RGEM5KqlPHr+WVTPmGNAXNeFEmsBnlkxXaIfEpUYV0AST2Z5W1EGq9L/MENFrMMmL2WQr1wjkmZy/M92eKhjYA==",
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
}
},
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -10751,22 +10625,6 @@
"node": ">=0.6"
}
},
"node_modules/token-types": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz",
"integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==",
"dependencies": {
"@tokenizer/token": "^0.3.0",
"ieee754": "^1.2.1"
},
"engines": {
"node": ">=10"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/Borewit"
}
},
"node_modules/tough-cookie": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
@@ -11126,6 +10984,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/typedarray": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
"integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="
},
"node_modules/typescript": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz",
@@ -11862,14 +11725,6 @@
"integrity": "sha512-XK6BTq1NDMo9Xqw/YkYyGjSsg44fbNwYRx7QK2CuoQgyy+f1rrTDHoExVM5PsyXCtfl2vs2vVJ0MN0yN6LppRw==",
"dev": true
},
"@fastify/busboy": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-1.2.1.tgz",
"integrity": "sha512-7PQA7EH43S0CxcOa9OeAnaeA0oQ+e/DHNPZwSQM9CQHW76jle5+OvLdibRp/Aafs9KXbLhxyjOTkRjWUbQEd3Q==",
"requires": {
"text-decoding": "^1.0.0"
}
},
"@hapi/b64": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/@hapi/b64/-/b64-6.0.1.tgz",
@@ -12628,11 +12483,6 @@
"defer-to-connect": "^2.0.0"
}
},
"@tokenizer/token": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
"integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="
},
"@tootallnate/once": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
@@ -13336,9 +13186,9 @@
}
},
"append-field": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/append-field/-/append-field-2.0.0.tgz",
"integrity": "sha512-yUPXgerKgcuwakzrRyklfhX+Ma2aYYMjb+BO2RPUwq+tk928V/i5DFWcCUS3hQhj468N+Ktmwb0tfbEtmfC6WA=="
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz",
"integrity": "sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw=="
},
"aproba": {
"version": "2.0.0",
@@ -13555,14 +13405,6 @@
"resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz",
"integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA=="
},
"base32-encode": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/base32-encode/-/base32-encode-2.0.0.tgz",
"integrity": "sha512-mlmkfc2WqdDtMl/id4qm3A7RjW6jxcbAoMjdRmsPiwQP0ufD4oXItYMnPgVHe80lnAIy+1xwzhHE1s4FoIceSw==",
"requires": {
"to-data-view": "^2.0.0"
}
},
"base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
@@ -13672,6 +13514,11 @@
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
},
"buffer-from": {
"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-indexof-polyfill": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz",
@@ -13702,7 +13549,8 @@
"bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="
"integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
"optional": true
},
"cacheable-lookup": {
"version": "5.0.4",
@@ -13948,6 +13796,51 @@
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
},
"concat-stream": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
"integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
"requires": {
"buffer-from": "^1.0.0",
"inherits": "^2.0.3",
"readable-stream": "^2.2.2",
"typedarray": "^0.0.6"
},
"dependencies": {
"isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
},
"readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"requires": {
"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"
}
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"requires": {
"safe-buffer": "~5.1.0"
}
}
}
},
"condense-newlines": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/condense-newlines/-/condense-newlines-0.2.1.tgz",
@@ -14554,11 +14447,6 @@
}
}
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
},
"electron-to-chromium": {
"version": "1.4.380",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.380.tgz",
@@ -14570,11 +14458,6 @@
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
"dev": true
},
"encode-utf8": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-2.0.0.tgz",
"integrity": "sha512-3EyMFxZj1/7oMotElDQUEQcP7N4TIe1aJ0m1uBDoyQ8I2LBHhBsXx8P3KsPbqNlGzG+NYxFwEauUwMPHZg3YDQ=="
},
"end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
@@ -15338,16 +15221,6 @@
"flat-cache": "^3.0.4"
}
},
"file-type": {
"version": "16.5.4",
"resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.4.tgz",
"integrity": "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==",
"requires": {
"readable-web-to-node-stream": "^3.0.0",
"strtok3": "^6.2.4",
"token-types": "^4.1.1"
}
},
"file-uri-to-path": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-2.0.0.tgz",
@@ -15388,11 +15261,6 @@
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
"dev": true
},
"fmix": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fmix/-/fmix-1.0.0.tgz",
"integrity": "sha512-PIaqOGvVH5P+R92Ywy5PumsNEHvondVQh42SGOmkA9A0ZTFbfguzZpjZ/Gy3WVRUqT9Ia8k5tWlJeiZQzRHA7g=="
},
"for-each": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
@@ -15455,14 +15323,6 @@
}
}
},
"fs-temp": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/fs-temp/-/fs-temp-2.0.1.tgz",
"integrity": "sha512-WYE7cUGOA0xRKsiYxNf/+WDuj0T20OtX85bVhsXpY+wJmjrRIUQftTI6JF9PVpo2RpGkh0l8lZsV8zszisYQ0Q==",
"requires": {
"random-path": "^1.0.0"
}
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -15778,11 +15638,6 @@
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
},
"has-own-property": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-own-property/-/has-own-property-2.0.0.tgz",
"integrity": "sha512-oupojxEPq/nfAshi0hOFDjpmYO4JXtymFyPC9YSBmFqGamZ2zUgrCkYInt5tf7f1j6iumlzJBpfLNRxZIQCM0w=="
},
"has-property-descriptors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
@@ -17132,18 +16987,27 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"multer": {
"version": "2.0.0-rc.4",
"resolved": "https://registry.npmjs.org/multer/-/multer-2.0.0-rc.4.tgz",
"integrity": "sha512-YkjV/rOzngEBxtZV8s6BcBcB/z2v/dfDcIpWagmMsKBq0QnQCu/NpCUDd2ElExfnxRXMVXKrFh94/UKe4NdxBQ==",
"version": "1.4.5-lts.1",
"resolved": "https://registry.npmjs.org/multer/-/multer-1.4.5-lts.1.tgz",
"integrity": "sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==",
"requires": {
"@fastify/busboy": "^1.0.0",
"append-field": "^2.0.0",
"bytes": "^3.1.0",
"fs-temp": "^2.0.1",
"has-own-property": "^2.0.0",
"on-finished": "^2.3.0",
"stream-file-type": "^0.6.1",
"type-is": "^1.6.18"
"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"
},
"dependencies": {
"mkdirp": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
"integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
"requires": {
"minimist": "^1.2.6"
}
}
}
},
"multer-storage-cloudinary": {
@@ -17152,15 +17016,6 @@
"integrity": "sha512-25lm9R6o5dWrHLqLvygNX+kBOxprzpmZdnVKH4+r68WcfCt8XV6xfQaMuAg+kUE5Xmr8mJNA4gE0AcBj9FJyWA==",
"requires": {}
},
"murmur-32": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/murmur-32/-/murmur-32-1.0.0.tgz",
"integrity": "sha512-l6QKUGWXzZWHash7lmZzycpIifOrnc3PeMaoFrMv90c+xqOyOSzJU0q2T/1d15MzAdEWTpCh1paC855APqt1Gw==",
"requires": {
"encode-utf8": "^2.0.0",
"fmix": "^1.0.0"
}
},
"murmurhash-js": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/murmurhash-js/-/murmurhash-js-1.0.0.tgz",
@@ -17417,14 +17272,6 @@
"resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz",
"integrity": "sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w=="
},
"on-finished": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
"requires": {
"ee-first": "1.1.1"
}
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -17635,11 +17482,6 @@
"resolved": "https://registry.npmjs.org/peberminta/-/peberminta-0.8.0.tgz",
"integrity": "sha512-YYEs+eauIjDH5nUEGi18EohWE0nV2QbGTqmxQcqgZ/0g+laPCQmuIqq7EBLVi9uim9zMgfJv0QBZEnQ3uHw/Tw=="
},
"peek-readable": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz",
"integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg=="
},
"performance-now": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
@@ -18008,15 +17850,6 @@
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz",
"integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw=="
},
"random-path": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/random-path/-/random-path-1.0.0.tgz",
"integrity": "sha512-I6FGG7uFR3tZqHP7TzcP3Ikt5IyVEG59u7KTjIIjizcdPY6MDjD9CbbKqE+znIv4mrDF6HMlBshoemk0oRRwsQ==",
"requires": {
"base32-encode": "^2.0.0",
"murmur-32": "^1.0.0"
}
},
"raw-body": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
@@ -18328,14 +18161,6 @@
"util-deprecate": "^1.0.1"
}
},
"readable-web-to-node-stream": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz",
"integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==",
"requires": {
"readable-stream": "^3.6.0"
}
},
"readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -18804,14 +18629,6 @@
"internal-slot": "^1.0.4"
}
},
"stream-file-type": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/stream-file-type/-/stream-file-type-0.6.1.tgz",
"integrity": "sha512-//KIXMQan4ow4gD//dfPu15nhH/sFdt41PzAOpD9EBFUBy/MtFjocTPO8v1dTOJnyi47TlPo6Qj+67sSE1lJKA==",
"requires": {
"file-type": "^16.0.0"
}
},
"streamsearch": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
@@ -18922,15 +18739,6 @@
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="
},
"strtok3": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz",
"integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==",
"requires": {
"@tokenizer/token": "^0.3.0",
"peek-readable": "^4.1.0"
}
},
"style-to-js": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.3.tgz",
@@ -19091,11 +18899,6 @@
}
}
},
"text-decoding": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/text-decoding/-/text-decoding-1.0.0.tgz",
"integrity": "sha512-/0TJD42KDnVwKmDK6jj3xP7E2MG7SHAOG4tyTgyUCRPdHwvkquYNLEQltmdMa3owq3TkddCVcTsoctJI8VQNKA=="
},
"text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
@@ -19142,11 +18945,6 @@
"integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==",
"dev": true
},
"to-data-view": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-data-view/-/to-data-view-2.0.0.tgz",
"integrity": "sha512-RGEM5KqlPHr+WVTPmGNAXNeFEmsBnlkxXaIfEpUYV0AST2Z5W1EGq9L/MENFrMMmL2WQr1wjkmZy/M92eKhjYA=="
},
"to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -19161,15 +18959,6 @@
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
"optional": true
},
"token-types": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.1.tgz",
"integrity": "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==",
"requires": {
"@tokenizer/token": "^0.3.0",
"ieee754": "^1.2.1"
}
},
"tough-cookie": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
@@ -19411,6 +19200,11 @@
"is-typed-array": "^1.1.9"
}
},
"typedarray": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
"integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA=="
},
"typescript": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz",

View File

@@ -29,7 +29,7 @@
"jsonwebtoken": "^9.0.0",
"lodash": "^4.17.21",
"mapbox-gl": "^2.14.1",
"multer": "^2.0.0-rc.4",
"multer": "^1.4.5-lts.1",
"multer-storage-cloudinary": "^4.0.0",
"next": "^13.3.4",
"next-connect": "^1.0.0-next.3",

View File

@@ -39,6 +39,7 @@ const CommentCardDropdown: FC<CommentCardDropdownProps> = ({
<button
type="button"
onClick={() => {
// eslint-disable-next-line no-alert
alert('This feature is not yet implemented.');
}}
>

View File

@@ -1,12 +1,14 @@
import sendCreateBeerPostRequest from '@/requests/sendCreateBeerPostRequest';
import CreateBeerPostValidationSchema from '@/services/BeerPost/schema/CreateBeerPostValidationSchema';
import { zodResolver } from '@hookform/resolvers/zod';
import { BeerType } from '@prisma/client';
import router from 'next/router';
import { FunctionComponent, useState } from 'react';
import { useForm, SubmitHandler } from 'react-hook-form';
import { useForm, SubmitHandler, FieldError } from 'react-hook-form';
import { z } from 'zod';
import BreweryPostQueryResult from '@/services/BreweryPost/types/BreweryPostQueryResult';
import CreateBeerPostValidationSchema from '@/services/BeerPost/schema/CreateBeerPostValidationSchema';
import sendCreateBeerPostRequest from '@/requests/sendCreateBeerPostRequest';
import UploadImageValidationSchema from '@/services/types/ImageSchema/UploadImageValidationSchema';
import sendUploadBeerImagesRequest from '@/requests/sendUploadBeerImageRequest';
import ErrorAlert from './ui/alerts/ErrorAlert';
import Button from './ui/forms/Button';
import FormError from './ui/forms/FormError';
@@ -17,32 +19,52 @@ import FormSelect from './ui/forms/FormSelect';
import FormTextArea from './ui/forms/FormTextArea';
import FormTextInput from './ui/forms/FormTextInput';
type CreateBeerPostSchema = z.infer<typeof CreateBeerPostValidationSchema>;
interface BeerFormProps {
breweries: z.infer<typeof BreweryPostQueryResult>[];
types: BeerType[];
}
const CreateBeerPostWithImagesValidationSchema = CreateBeerPostValidationSchema.merge(
UploadImageValidationSchema,
);
const CreateBeerPostForm: FunctionComponent<BeerFormProps> = ({
breweries = [],
types = [],
}) => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm<CreateBeerPostSchema>({
resolver: zodResolver(CreateBeerPostValidationSchema),
const { register, handleSubmit, formState } = useForm<
z.infer<typeof CreateBeerPostWithImagesValidationSchema>
>({
resolver: zodResolver(CreateBeerPostWithImagesValidationSchema),
});
const { errors, isSubmitting } = formState;
const [error, setError] = useState('');
const [isSubmitting, setIsSubmitting] = useState(false);
const onSubmit: SubmitHandler<CreateBeerPostSchema> = async (data) => {
const onSubmit: SubmitHandler<
z.infer<typeof CreateBeerPostWithImagesValidationSchema>
> = async (data) => {
if (!(data.images instanceof FileList)) {
return;
}
const { breweryId, typeId, name, abv, ibu, description } = data;
try {
setIsSubmitting(true);
const response = await sendCreateBeerPostRequest(data);
const response = await sendCreateBeerPostRequest({
breweryId,
typeId,
name,
abv,
ibu,
description,
});
await sendUploadBeerImagesRequest({
beerPost: response,
images: data.images,
});
router.push(`/beers/${response.id}`);
} catch (e) {
if (!(e instanceof Error)) {
@@ -160,6 +182,19 @@ const CreateBeerPostForm: FunctionComponent<BeerFormProps> = ({
/>
</FormSegment>
<FormInfo>
<FormLabel htmlFor="images">Images</FormLabel>
<FormError>{(errors.images as FieldError | undefined)?.message}</FormError>
</FormInfo>
<FormSegment>
<input
type="file"
{...register('images')}
multiple
className="file-input-bordered file-input w-full"
/>
</FormSegment>
<div className="mt-6">
<Button type="submit" isSubmitting={isSubmitting}>
{isSubmitting ? 'Submitting...' : 'Submit'}

View File

@@ -59,7 +59,11 @@ const EditBeerPostForm: FC<EditBeerPostFormProps> = ({ previousValues }) => {
router.push('/beers');
}
} catch (e) {
console.error(e);
if (!(e instanceof Error)) {
setError('Something went wrong');
return;
}
setError(e.message);
}
};
return (

View File

@@ -29,7 +29,9 @@ const fileFilter: multer.Options['fileFilter'] = (req, file, cb) => {
};
const uploadMiddleware = expressWrapper(
multer({ storage, fileFilter, limits: { files: 3 } }).array('images'),
multer({ storage, fileFilter, limits: { files: 5, fileSize: 15 * 1024 * 1024 } }).array(
'images',
),
);
const BeerPostImageValidationSchema = z.object({

View File

@@ -46,9 +46,9 @@ const registerUser = async (req: RegisterUserRequest, res: NextApiResponse) => {
await sendConfirmationEmail(user);
res.status(200).json({
res.status(201).json({
success: true,
statusCode: 200,
statusCode: 201,
message: 'User registered successfully.',
payload: user,
});

View File

@@ -17,7 +17,7 @@ const ProtectedPage: NextPage = () => {
const isDesktop = useMediaQuery('(min-width: 768px)');
return (
<div className="flex h-full flex-col items-center justify-center space-y-3 text-center">
<div className="flex h-full flex-col items-center justify-center space-y-3 bg-primary text-center">
{isLoading && <Spinner size={isDesktop ? 'xl' : 'md'} />}
{user && !isLoading && (
<>
@@ -27,9 +27,7 @@ const ProtectedPage: NextPage = () => {
{isEvening && 'evening'}
{`, ${user?.firstName}!`}
</h1>
<h2 className="text-xl font-bold lg:text-4xl">
Welcome to the Biergarten App!
</h2>
<h2 className="text-xl font-bold lg:text-4xl">Welcome to the Biergarten App!</h2>
</>
)}
</div>

View File

@@ -2,6 +2,7 @@
import { faker } from '@faker-js/faker';
import { BeerPost, User } from '@prisma/client';
import DBClient from '../../DBClient';
import imageUrls from '../util/imageUrls';
interface CreateNewBeerImagesArgs {
numberOfImages: number;
@@ -31,9 +32,10 @@ const createNewBeerImages = async ({
const user = users[Math.floor(Math.random() * users.length)];
const caption = faker.lorem.sentence();
const alt = faker.lorem.sentence();
const path = imageUrls[Math.floor(Math.random() * imageUrls.length)];
beerImageData.push({
path: 'https://picsum.photos/5000/5000',
path,
alt,
caption,
beerPostId: beerPost.id,

View File

@@ -2,6 +2,7 @@
import { faker } from '@faker-js/faker';
import { BreweryPost, User } from '@prisma/client';
import DBClient from '../../DBClient';
import imageUrls from '../util/imageUrls';
interface CreateBreweryImagesArgs {
numberOfImages: number;
@@ -32,9 +33,10 @@ const createNewBreweryImages = async ({
for (let i = 0; i < numberOfImages; i++) {
const breweryPost = breweryPosts[Math.floor(Math.random() * breweryPosts.length)];
const user = users[Math.floor(Math.random() * users.length)];
const path = imageUrls[Math.floor(Math.random() * imageUrls.length)];
breweryImageData.push({
path: 'https://picsum.photos/5000/5000',
path,
alt: 'Placeholder brewery image.',
caption: 'Placeholder brewery image caption.',
breweryPostId: breweryPost.id,

View File

@@ -0,0 +1,9 @@
const imageUrls = [
'https://res.cloudinary.com/dxie9b7na/image/upload/v1683482214/cld-sample.jpg',
'https://res.cloudinary.com/dxie9b7na/image/upload/v1683482214/cld-sample-2.jpg',
'https://res.cloudinary.com/dxie9b7na/image/upload/v1683482214/cld-sample-3.jpg',
'https://res.cloudinary.com/dxie9b7na/image/upload/v1683482214/cld-sample-4.jpg',
'https://res.cloudinary.com/dxie9b7na/image/upload/v1683482214/cld-sample-5.jpg',
] as const;
export default imageUrls;

View File

@@ -0,0 +1,34 @@
import beerPostQueryResult from '@/services/BeerPost/schema/BeerPostQueryResult';
import { z } from 'zod';
interface SendUploadBeerImagesRequestArgs {
beerPost: z.infer<typeof beerPostQueryResult>;
images: FileList;
}
const sendUploadBeerImagesRequest = async ({
beerPost,
images,
}: SendUploadBeerImagesRequestArgs) => {
const formData = new FormData();
[...images].forEach((file) => {
formData.append('images', file);
});
formData.append('caption', `Image of ${beerPost.name}`);
formData.append('alt', beerPost.name);
const uploadResponse = await fetch(`/api/beers/${beerPost.id}/images`, {
method: 'POST',
body: formData,
});
if (!uploadResponse.ok) {
throw new Error('Failed to upload images');
}
return uploadResponse.json();
};
export default sendUploadBeerImagesRequest;

View File

@@ -0,0 +1,31 @@
import { z } from 'zod';
const UploadImageValidationSchema = z.object({
images: z
.instanceof(typeof FileList !== 'undefined' ? FileList : Object)
.refine((fileList) => fileList instanceof FileList, {
message: 'You must submit this form in a web browser.',
})
.refine((fileList) => (fileList as FileList).length > 0, {
message: 'You must upload at least one file.',
})
.refine((fileList) => (fileList as FileList).length < 5, {
message: 'You can only upload up to 5 files at a time.',
})
.refine(
(fileList) =>
[...(fileList as FileList)]
.map((file) => file.type)
.every((fileType) => fileType.startsWith('image/')),
{ message: 'You must upload only images.' },
)
.refine(
(fileList) =>
[...(fileList as FileList)]
.map((file) => file.size)
.every((fileSize) => fileSize < 15 * 1024 * 1024),
{ message: 'You must upload images smaller than 15MB.' },
),
});
export default UploadImageValidationSchema;

View File

@@ -15,6 +15,7 @@
"jsx": "preserve",
"incremental": true,
"baseUrl": ".",
"downlevelIteration": true,
"paths": {
"@/*": ["./src/*"]
}