fix local storage upload of photo/avatar

This commit is contained in:
Amruth Pillai
2022-08-29 20:44:07 +02:00
parent 17019e446b
commit 049de38da2
8 changed files with 106 additions and 88 deletions
+1 -13
View File
@@ -2,23 +2,11 @@
"ignorePatterns": ["/app"],
"parser": "@typescript-eslint/parser",
"extends": ["plugin:@typescript-eslint/recommended"],
"plugins": ["@typescript-eslint/eslint-plugin", "simple-import-sort", "unused-imports"],
"plugins": ["@typescript-eslint/eslint-plugin", "simple-import-sort"],
"rules": {
// ESLint
"no-unused-vars": "off",
// Unused Imports
"unused-imports/no-unused-imports": "error",
"unused-imports/no-unused-vars": [
"warn",
{
"vars": "all",
"args": "none",
"varsIgnorePattern": "^_",
"argsIgnorePattern": "^_"
}
],
// Simple Import Sort
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error",
+13
View File
@@ -1,5 +1,6 @@
{
"extends": ["../.eslintrc.json", "next/core-web-vitals", "plugin:tailwindcss/recommended"],
"plugins": ["unused-imports"],
"ignorePatterns": [".next", "__ENV.js"],
"settings": {
"next": {
@@ -14,6 +15,18 @@
// React Hooks
"react-hooks/exhaustive-deps": "off",
// Unused Imports
"unused-imports/no-unused-imports": "error",
"unused-imports/no-unused-vars": [
"warn",
{
"vars": "all",
"args": "none",
"varsIgnorePattern": "^_",
"argsIgnorePattern": "^_"
}
],
// Tailwind CSS
"tailwindcss/no-custom-classname": ["warn", { "whitelist": ["preview-mode", "printer-mode", "markdown"] }]
}
+5 -4
View File
@@ -16,10 +16,10 @@
"@hello-pangea/dnd": "^16.0.0",
"@hookform/resolvers": "2.9.7",
"@monaco-editor/react": "^4.4.5",
"@mui/icons-material": "^5.10.2",
"@mui/lab": "^5.0.0-alpha.96",
"@mui/material": "^5.10.2",
"@mui/system": "^5.10.2",
"@mui/icons-material": "^5.10.3",
"@mui/lab": "^5.0.0-alpha.97",
"@mui/material": "^5.10.3",
"@mui/system": "^5.10.3",
"@mui/x-date-pickers": "5.0.0-beta.7",
"@next/env": "^12.2.5",
"@react-oauth/google": "^0.2.6",
@@ -60,6 +60,7 @@
"devDependencies": {
"@babel/core": "^7.18.13",
"@reactive-resume/schema": "workspace:*",
"eslint-plugin-unused-imports": "^2.0.0",
"@tailwindcss/typography": "^0.5.4",
"@types/downloadjs": "^1.4.3",
"@types/lodash": "^4.14.184",
-1
View File
@@ -25,7 +25,6 @@
"eslint": "^8.23.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-simple-import-sort": "^7.0.0",
"eslint-plugin-unused-imports": "^2.0.0",
"prettier": "^2.7.1",
"standard-version": "^9.5.0",
"typescript": "^4.8.2"
+64 -51
View File
@@ -14,7 +14,6 @@ importers:
eslint: ^8.23.0
eslint-plugin-import: ^2.26.0
eslint-plugin-simple-import-sort: ^7.0.0
eslint-plugin-unused-imports: ^2.0.0
prettier: ^2.7.1
standard-version: ^9.5.0
turbo: ^1.4.3
@@ -28,7 +27,6 @@ importers:
eslint: 8.23.0
eslint-plugin-import: 2.26.0_kavhtzjob4obuugpatbfgsyfbm
eslint-plugin-simple-import-sort: 7.0.0_eslint@8.23.0
eslint-plugin-unused-imports: 2.0.0_h2obgme53psvsi5hnxwhauwpoe
prettier: 2.7.1
standard-version: 9.5.0
typescript: 4.8.2
@@ -44,10 +42,10 @@ importers:
'@hello-pangea/dnd': ^16.0.0
'@hookform/resolvers': 2.9.7
'@monaco-editor/react': ^4.4.5
'@mui/icons-material': ^5.10.2
'@mui/lab': ^5.0.0-alpha.96
'@mui/material': ^5.10.2
'@mui/system': ^5.10.2
'@mui/icons-material': ^5.10.3
'@mui/lab': ^5.0.0-alpha.97
'@mui/material': ^5.10.3
'@mui/system': ^5.10.3
'@mui/x-date-pickers': 5.0.0-beta.7
'@next/env': ^12.2.5
'@react-oauth/google': ^0.2.6
@@ -71,6 +69,7 @@ importers:
downloadjs: ^1.4.7
eslint-config-next: ^12.2.5
eslint-plugin-tailwindcss: ^3.6.0
eslint-plugin-unused-imports: ^2.0.0
joi: ^17.6.0
lodash: ^4.17.21
md5-hex: ^4.0.0
@@ -113,11 +112,11 @@ importers:
'@hello-pangea/dnd': 16.0.0_itztagxbudv7qpjmcixvw7qcxu
'@hookform/resolvers': 2.9.7_react-hook-form@7.34.2
'@monaco-editor/react': 4.4.5_7payg3yaajmz2lehtpasnhysrm
'@mui/icons-material': 5.10.2_pe34yoxfle46vwr2x5qecrpmaa
'@mui/lab': 5.0.0-alpha.96_atslascsvst3lirrukwo3ttf6m
'@mui/material': 5.10.2_fysfq4yi5czcauwysabbmi7r4e
'@mui/system': 5.10.2_5fhvyv2ndpor6xyeflovbajcce
'@mui/x-date-pickers': 5.0.0-beta.7_duotufuww3r4hl77c53hrwrcfi
'@mui/icons-material': 5.10.3_hvqhvczo6nhngogkfpykwmdnpu
'@mui/lab': 5.0.0-alpha.97_tm7nujx47fip2dp7jovg3hu2pq
'@mui/material': 5.10.3_fysfq4yi5czcauwysabbmi7r4e
'@mui/system': 5.10.3_5fhvyv2ndpor6xyeflovbajcce
'@mui/x-date-pickers': 5.0.0-beta.7_jswxb7wixuecrvgxery4aquwdu
'@next/env': 12.2.5
'@react-oauth/google': 0.2.6_biqbaboplfbrettd7655fr4n2y
'@reduxjs/toolkit': 1.8.5_kkwg4cbsojnjnupd3btipussee
@@ -170,6 +169,7 @@ importers:
csstype: 3.1.0
eslint-config-next: 12.2.5_yqf6kl63nyoq5megxukfnom5rm
eslint-plugin-tailwindcss: 3.6.0
eslint-plugin-unused-imports: 2.0.0_eslint@8.23.0
next-sitemap: 3.1.21_gzpnnaylvtfluxe3m63vhk6hhm
postcss: 8.4.16
sass: 1.54.5
@@ -1829,8 +1829,8 @@ packages:
react-dom: 18.2.0_react@18.2.0
dev: false
/@mui/base/5.0.0-alpha.94_5zfva2lldyu7jrbrwroiixp6xm:
resolution: {integrity: sha512-IJXmgTF07H1Iv5zjDV7zJZGUmb9cN8ERzd2dgA1akh6NWZgwyIGyQx+Au9+QSDoM5vN3FqZvU/0YCU6inUwgeQ==}
/@mui/base/5.0.0-alpha.95_5zfva2lldyu7jrbrwroiixp6xm:
resolution: {integrity: sha512-fcxnDeO7rBwzP0buVdI5fn0aA7NQ/AeUV5RzIIH0kOXVVT21HB4JFf41Qhwd0PIq63PXxmc6Fs2mdlzMYuPo9g==}
engines: {node: '>=12.0.0'}
peerDependencies:
'@types/react': ^17.0.0 || ^18.0.0
@@ -1842,8 +1842,8 @@ packages:
dependencies:
'@babel/runtime': 7.18.9
'@emotion/is-prop-valid': 1.2.0
'@mui/types': 7.1.5_@types+react@17.0.2
'@mui/utils': 5.9.3_react@18.2.0
'@mui/types': 7.2.0_@types+react@17.0.2
'@mui/utils': 5.10.3_react@18.2.0
'@popperjs/core': 2.11.6
'@types/react': 17.0.2
clsx: 1.2.1
@@ -1853,12 +1853,12 @@ packages:
react-is: 18.2.0
dev: false
/@mui/core-downloads-tracker/5.10.2:
resolution: {integrity: sha512-1guoGvL3QZ7VjA3y9zye9Rpm+jz18rVZIo3AauTGyW5ntDMxr/cR0M18nuc/NH2KqpMt+coh4NwPEO1uPuKM5w==}
/@mui/core-downloads-tracker/5.10.3:
resolution: {integrity: sha512-mX2S0d1oboKBbWQqWIgRmyALAEzh37yiknpD3mKx8bcoMKbp1VtqzIt0aeHP16Uhsd0eValDFILxLNHWi0oddQ==}
dev: false
/@mui/icons-material/5.10.2_pe34yoxfle46vwr2x5qecrpmaa:
resolution: {integrity: sha512-p7ku+43JeKRz0ONGzPZbRXZRbE7vCKP1Cr8l/Yj9sUIGVQ6CM/m37u6udacJZkDXD+G2FoxJPixrVvvjx6f64w==}
/@mui/icons-material/5.10.3_hvqhvczo6nhngogkfpykwmdnpu:
resolution: {integrity: sha512-o0kbUlsWCBtCE0wP33cGKbyryCh7kpm2EECYMPDmWrLhbA+HUODXIdhiTFS26szp2xXo9HY1lEx0ufeJ+tddYw==}
engines: {node: '>=12.0.0'}
peerDependencies:
'@mui/material': ^5.0.0
@@ -1869,13 +1869,13 @@ packages:
optional: true
dependencies:
'@babel/runtime': 7.18.9
'@mui/material': 5.10.2_fysfq4yi5czcauwysabbmi7r4e
'@mui/material': 5.10.3_fysfq4yi5czcauwysabbmi7r4e
'@types/react': 17.0.2
react: 18.2.0
dev: false
/@mui/lab/5.0.0-alpha.96_atslascsvst3lirrukwo3ttf6m:
resolution: {integrity: sha512-hA3nef9cV50eIljPA/otQ6CrDeI276UGRJmVw6YZzSBtUeGuE9FY411VOZeST4I4OM88RD3lwiRbN5aTX5Nn3g==}
/@mui/lab/5.0.0-alpha.97_tm7nujx47fip2dp7jovg3hu2pq:
resolution: {integrity: sha512-0qIyXcNJg2PftzUjO5nsa9D2LEiyfA+Zg7EpJMZNtkjCTGjJmqw4cp2nJIFlZDzoFb8DsjhlFl3BWAAZqRRgTw==}
engines: {node: '>=12.0.0'}
peerDependencies:
'@emotion/react': ^11.5.0
@@ -1895,10 +1895,10 @@ packages:
'@babel/runtime': 7.18.9
'@emotion/react': 11.10.0_bp52lckidoqgagdowtbm7s2nrm
'@emotion/styled': 11.10.0_ne4npfofad547qwr5bje3fwhji
'@mui/base': 5.0.0-alpha.94_5zfva2lldyu7jrbrwroiixp6xm
'@mui/material': 5.10.2_fysfq4yi5czcauwysabbmi7r4e
'@mui/system': 5.10.2_5fhvyv2ndpor6xyeflovbajcce
'@mui/utils': 5.9.3_react@18.2.0
'@mui/base': 5.0.0-alpha.95_5zfva2lldyu7jrbrwroiixp6xm
'@mui/material': 5.10.3_fysfq4yi5czcauwysabbmi7r4e
'@mui/system': 5.10.3_5fhvyv2ndpor6xyeflovbajcce
'@mui/utils': 5.10.3_react@18.2.0
'@types/react': 17.0.2
clsx: 1.2.1
prop-types: 15.8.1
@@ -1907,8 +1907,8 @@ packages:
react-is: 18.2.0
dev: false
/@mui/material/5.10.2_fysfq4yi5czcauwysabbmi7r4e:
resolution: {integrity: sha512-ay43fuQLXROXkxFd6tqbj394Hu8BlbmpCdEDFtAisijulla2ZLfQa24pjhdX+56HrHReB3cZsf/sRq+DSfIgiA==}
/@mui/material/5.10.3_fysfq4yi5czcauwysabbmi7r4e:
resolution: {integrity: sha512-g0lzHcqWHYeOEAxTzcwpM1I7b+wyiRTeXkEdRsspnOpZtb0H/1xg386tMFRGbxBJ4zfVGT+TWublofw7pyQkqw==}
engines: {node: '>=12.0.0'}
peerDependencies:
'@emotion/react': ^11.5.0
@@ -1927,11 +1927,11 @@ packages:
'@babel/runtime': 7.18.9
'@emotion/react': 11.10.0_bp52lckidoqgagdowtbm7s2nrm
'@emotion/styled': 11.10.0_ne4npfofad547qwr5bje3fwhji
'@mui/base': 5.0.0-alpha.94_5zfva2lldyu7jrbrwroiixp6xm
'@mui/core-downloads-tracker': 5.10.2
'@mui/system': 5.10.2_5fhvyv2ndpor6xyeflovbajcce
'@mui/types': 7.1.5_@types+react@17.0.2
'@mui/utils': 5.9.3_react@18.2.0
'@mui/base': 5.0.0-alpha.95_5zfva2lldyu7jrbrwroiixp6xm
'@mui/core-downloads-tracker': 5.10.3
'@mui/system': 5.10.3_5fhvyv2ndpor6xyeflovbajcce
'@mui/types': 7.2.0_@types+react@17.0.2
'@mui/utils': 5.10.3_react@18.2.0
'@types/react': 17.0.2
'@types/react-transition-group': 4.4.5
clsx: 1.2.1
@@ -1943,8 +1943,8 @@ packages:
react-transition-group: 4.4.5_biqbaboplfbrettd7655fr4n2y
dev: false
/@mui/private-theming/5.9.3_akgelr6b34ghs4njbbtjaykm7q:
resolution: {integrity: sha512-Ys3WO39WqoGciGX9k5AIi/k2zJhlydv4FzlEEwtw9OqdMaV0ydK/TdZekKzjP9sTI/JcdAP3H5DWtUaPLQJjWg==}
/@mui/private-theming/5.10.3_akgelr6b34ghs4njbbtjaykm7q:
resolution: {integrity: sha512-LCYIKlkGz2BTSng2BFzzwSJBRZbChIUri2x2Nh8ryk2B1Ho7zpvE7ex6y39LlStG2Frf92NFC/V4YQbmMAjD5A==}
engines: {node: '>=12.0.0'}
peerDependencies:
'@types/react': ^17.0.0 || ^18.0.0
@@ -1954,14 +1954,14 @@ packages:
optional: true
dependencies:
'@babel/runtime': 7.18.9
'@mui/utils': 5.9.3_react@18.2.0
'@mui/utils': 5.10.3_react@18.2.0
'@types/react': 17.0.2
prop-types: 15.8.1
react: 18.2.0
dev: false
/@mui/styled-engine/5.10.2_rq3l25qc4qpq3j4w6o4x7hatzy:
resolution: {integrity: sha512-YqnptNQ2E0cWwOTmLCEvrddiiR/neUfn2AD/4TDUXZu8B2n7NfDb9d3bAUfWZV+KmulQdAedoaZDqyXBFGLdbQ==}
/@mui/styled-engine/5.10.3_rq3l25qc4qpq3j4w6o4x7hatzy:
resolution: {integrity: sha512-9Uz7eB8xXoiDvpJ9qBxZ/2xGO8xKfA2T23dw4AsQ69SQtGatrOLAapzP2lNr0tfB9xvKucclPFhRO5aLhDFOVQ==}
engines: {node: '>=12.0.0'}
peerDependencies:
'@emotion/react': ^11.4.1
@@ -1982,8 +1982,8 @@ packages:
react: 18.2.0
dev: false
/@mui/system/5.10.2_5fhvyv2ndpor6xyeflovbajcce:
resolution: {integrity: sha512-YudwJhLcEoQiwCAmzeMr9P3ISiVGNsxBIIPzFxaGwJ8+mMrx3qoPVOV2sfm0ZuNiQuABshEw4KqHa5ftNC+pOQ==}
/@mui/system/5.10.3_5fhvyv2ndpor6xyeflovbajcce:
resolution: {integrity: sha512-uLW/CIz3zk1jr5zH0ahOUqJIrpWP02Mv4emfrplh7Mh5JCb/oumhYaC/ALJJEjzUHKg9wwiyuM0pCwK/kSf1jQ==}
engines: {node: '>=12.0.0'}
peerDependencies:
'@emotion/react': ^11.5.0
@@ -2001,10 +2001,10 @@ packages:
'@babel/runtime': 7.18.9
'@emotion/react': 11.10.0_bp52lckidoqgagdowtbm7s2nrm
'@emotion/styled': 11.10.0_ne4npfofad547qwr5bje3fwhji
'@mui/private-theming': 5.9.3_akgelr6b34ghs4njbbtjaykm7q
'@mui/styled-engine': 5.10.2_rq3l25qc4qpq3j4w6o4x7hatzy
'@mui/types': 7.1.5_@types+react@17.0.2
'@mui/utils': 5.9.3_react@18.2.0
'@mui/private-theming': 5.10.3_akgelr6b34ghs4njbbtjaykm7q
'@mui/styled-engine': 5.10.3_rq3l25qc4qpq3j4w6o4x7hatzy
'@mui/types': 7.2.0_@types+react@17.0.2
'@mui/utils': 5.10.3_react@18.2.0
'@types/react': 17.0.2
clsx: 1.2.1
csstype: 3.1.0
@@ -2012,8 +2012,8 @@ packages:
react: 18.2.0
dev: false
/@mui/types/7.1.5_@types+react@17.0.2:
resolution: {integrity: sha512-HnRXrxgHJYJcT8ZDdDCQIlqk0s0skOKD7eWs9mJgBUu70hyW4iA6Kiv3yspJR474RFH8hysKR65VVSzUSzkuwA==}
/@mui/types/7.2.0_@types+react@17.0.2:
resolution: {integrity: sha512-lGXtFKe5lp3UxTBGqKI1l7G8sE2xBik8qCfrLHD5olwP/YU0/ReWoWT7Lp1//ri32dK39oPMrJN8TgbkCSbsNA==}
peerDependencies:
'@types/react': '*'
peerDependenciesMeta:
@@ -2023,6 +2023,20 @@ packages:
'@types/react': 17.0.2
dev: false
/@mui/utils/5.10.3_react@18.2.0:
resolution: {integrity: sha512-4jXMDPfx6bpMVuheLaOpKTjpzw39ogAZLeaLj5+RJec3E37/hAZMYjURfblLfTWMMoGoqkY03mNsZaEwNobBow==}
engines: {node: '>=12.0.0'}
peerDependencies:
react: ^17.0.0 || ^18.0.0
dependencies:
'@babel/runtime': 7.18.9
'@types/prop-types': 15.7.5
'@types/react-is': 17.0.3
prop-types: 15.8.1
react: 18.2.0
react-is: 18.2.0
dev: false
/@mui/utils/5.9.3_react@18.2.0:
resolution: {integrity: sha512-l0N5bcrenE9hnwZ/jPecpIRqsDFHkPXoFUcmkgysaJwVZzJ3yQkGXB47eqmXX5yyGrSc6HksbbqXEaUya+siew==}
engines: {node: '>=12.0.0'}
@@ -2037,7 +2051,7 @@ packages:
react-is: 18.2.0
dev: false
/@mui/x-date-pickers/5.0.0-beta.7_duotufuww3r4hl77c53hrwrcfi:
/@mui/x-date-pickers/5.0.0-beta.7_jswxb7wixuecrvgxery4aquwdu:
resolution: {integrity: sha512-3GugfJ17OQ13TOjyIvz/DsbtG3VF1cU+iKNxY+bscKx03LVJPTRZMXrMCVJnVz5L3mjhwWfcku7+nOY6aC0GVA==}
engines: {node: '>=12.0.0'}
peerDependencies:
@@ -2073,8 +2087,8 @@ packages:
'@date-io/moment': 2.15.0
'@emotion/react': 11.10.0_bp52lckidoqgagdowtbm7s2nrm
'@emotion/styled': 11.10.0_ne4npfofad547qwr5bje3fwhji
'@mui/material': 5.10.2_fysfq4yi5czcauwysabbmi7r4e
'@mui/system': 5.10.2_5fhvyv2ndpor6xyeflovbajcce
'@mui/material': 5.10.3_fysfq4yi5czcauwysabbmi7r4e
'@mui/system': 5.10.3_5fhvyv2ndpor6xyeflovbajcce
'@mui/utils': 5.9.3_react@18.2.0
'@types/react-transition-group': 4.4.5
clsx: 1.2.1
@@ -4765,7 +4779,7 @@ packages:
- ts-node
dev: true
/eslint-plugin-unused-imports/2.0.0_h2obgme53psvsi5hnxwhauwpoe:
/eslint-plugin-unused-imports/2.0.0_eslint@8.23.0:
resolution: {integrity: sha512-3APeS/tQlTrFa167ThtP0Zm0vctjr4M44HMpeg1P4bK6wItarumq0Ma82xorMKdFsWpphQBlRPzw/pxiVELX1A==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
@@ -4775,7 +4789,6 @@ packages:
'@typescript-eslint/eslint-plugin':
optional: true
dependencies:
'@typescript-eslint/eslint-plugin': 5.35.1_pfwtupu3r4wxmgbx6hj7gwmyuu
eslint: 8.23.0
eslint-rule-composer: 0.3.0
dev: true
+1
View File
@@ -6,4 +6,5 @@ export default registerAs('app', () => ({
secretKey: process.env.SECRET_KEY,
port: parseInt(process.env.PORT, 10) || 3100,
url: process.env.PUBLIC_URL || 'http://localhost:3000',
serverUrl: process.env.PUBLIC_SERVER_URL || 'http://localhost:3100',
}));
+1
View File
@@ -18,6 +18,7 @@ const validationSchema = Joi.object({
// URLs
PUBLIC_URL: Joi.string().default('http://localhost:3000'),
PUBLIC_SERVER_URL: Joi.string().default('http://localhost:3100'),
// Database
POSTGRES_HOST: Joi.string().required(),
+21 -19
View File
@@ -3,7 +3,7 @@ import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { InjectRepository } from '@nestjs/typeorm';
import { Resume as ResumeSchema } from '@reactive-resume/schema';
import fs from 'fs';
import fs from 'fs/promises';
import { isEmpty, pick, sample, set } from 'lodash';
import { nanoid } from 'nanoid';
import { extname } from 'path';
@@ -254,17 +254,19 @@ export class ResumeService {
updatedResume = set(resume, 'basics.photo.url', publicUrl);
} else {
const path = `${__dirname}/../assets/uploads/${userId}/${id}/`;
fs.mkdir(path, { recursive: true }, (err) => {
if (err) {
console.log(err);
}
fs.writeFile(path + filename, file.buffer, (err) => {
if (err) {
console.log(err);
}
});
});
updatedResume = set(resume, 'basics.photo.url', `/api/assets/uploads/${userId}/${id}/` + filename);
const serverUrl = this.configService.get<string>('app.serverUrl');
try {
await fs.mkdir(path, { recursive: true });
await fs.writeFile(path + filename, file.buffer);
updatedResume = set(resume, 'basics.photo.url', `${serverUrl}/assets/uploads/${userId}/${id}/` + filename);
} catch (error) {
throw new HttpException(
'Something went wrong. Please try again later, or raise an issue on GitHub if the problem persists.',
HttpStatus.INTERNAL_SERVER_ERROR
);
}
}
return this.resumeRepository.save<Resume>(updatedResume);
@@ -285,13 +287,13 @@ export class ResumeService {
})
);
} else {
const filePath = __dirname + '/../' + resume.basics.photo.url.replace('/api/', '');
if (fs.existsSync(filePath)) {
fs.unlink(filePath, (err) => {
if (err) {
console.log(err);
}
});
const serverUrl = this.configService.get<string>('app.serverUrl');
const filePath = __dirname + '/..' + resume.basics.photo.url.replace(serverUrl, '');
const isValidFile = (await fs.stat(filePath)).isFile();
if (isValidFile) {
await fs.unlink(filePath);
}
}