diff --git a/.gitignore b/.gitignore index 88b6f0d..ecdfb42 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ # production /build +/data # misc .DS_Store @@ -25,6 +26,7 @@ yarn-debug.log* yarn-error.log* # local env files +.env .env.local .env.development.local .env.test.local diff --git a/package.json b/package.json index 80864b1..f9916f5 100644 --- a/package.json +++ b/package.json @@ -5,18 +5,27 @@ "private": true, "license": "MIT", "scripts": { + "prisma": "yarn prisma:push && yarn prisma:seed", + "initialdata": "ts-node scripts/initialdata.ts", + "predev": "yarn prisma && yarn initialdata", "dev": "next dev", + "prebuild": "yarn prisma && yarn initialdata", "build": "next build", "start": "next start", "lint": "next lint --fix", "prepare": "husky install", "clean": "rm -rf node_modules .next data public", - "type-check": "tsc" + "type-check": "tsc", + "prisma:push": "prisma db push", + "prisma:seed": "prisma db seed" }, "dependencies": { + "@prisma/client": "^3.6.0", "@stitches/react": "^1.2.6", + "axios": "^0.24.0", "lodash": "^4.17.21", "next": "12.0.7", + "next-connect": "^0.11.0", "react": "17.0.2", "react-dom": "17.0.2", "react-icons": "^4.3.1" @@ -25,7 +34,7 @@ "@commitlint/cli": "15.0.0", "@commitlint/config-conventional": "15.0.0", "@types/lodash": "^4.14.178", - "@types/node": "16.11.12", + "@types/node": "^16.11.12", "@types/react": "17.0.37", "eslint": "8.4.1", "eslint-config-next": "12.0.7", @@ -36,6 +45,11 @@ "lint-staged": "12.1.2", "prettier": "2.5.0", "pretty-quick": "3.1.2", - "typescript": "4.5.3" + "prisma": "^3.6.0", + "ts-node": "^10.4.0", + "typescript": "^4.5.3" + }, + "prisma": { + "seed": "ts-node prisma/seed.ts" } } diff --git a/prisma/schema.prisma b/prisma/schema.prisma new file mode 100644 index 0000000..d3534b8 --- /dev/null +++ b/prisma/schema.prisma @@ -0,0 +1,13 @@ +generator client { + provider = "prisma-client-js" +} + +datasource db { + provider = "postgresql" + url = env("DATABASE_URL") +} + +model Data { + id Int @id @default(autoincrement()) + data String +} diff --git a/prisma/seed.ts b/prisma/seed.ts new file mode 100644 index 0000000..888956f --- /dev/null +++ b/prisma/seed.ts @@ -0,0 +1,82 @@ +import { PrismaClient } from '@prisma/client' + +const prisma = new PrismaClient() + +async function main() { + const data = { + settings: { + avatar: '/avatar.jpeg', + name: 'John Doe', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec euismod, nisl eget aliquam consectetur, nisl nunc aliquet nunc, euismod aliquam nunc nisl euismod.', + font: 'baloo', + buttonsSchema: 'rounded', + outline: true, + colors: { + texts: 'neutral50', + socialLinks: 'rose', + buttonLinks: 'rose', + background: 'neutral700' + } + }, + socialLinks: [ + { + label: 'Email', + href: '1' + }, + { + label: 'GitHub', + href: '2' + }, + { + label: 'LinkedIn', + href: '3' + }, + { + label: 'Dev', + href: '4' + }, + { + label: 'Instagram', + href: '5' + }, + { + label: 'WhatsApp', + href: '6' + } + ], + buttonLinks: [ + { + label: 'Home', + href: '#' + }, + { + label: 'About', + href: '/about' + }, + { + label: 'Contact', + href: '/contact' + } + ] + } + + const hasData = await prisma.data.findFirst() + + if (!hasData) { + console.log(`Start seeding...`) + + await prisma.data.create({ + data: { data: JSON.stringify(data) } + }) + } +} + +main() + .catch(e => { + console.error(e) + process.exit(1) + }) + .finally(async () => { + await prisma.$disconnect() + }) diff --git a/prisma/tsconfig.json b/prisma/tsconfig.json new file mode 100644 index 0000000..0e7afc6 --- /dev/null +++ b/prisma/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "module": "commonjs" + } +} diff --git a/scripts/initialdata.ts b/scripts/initialdata.ts new file mode 100644 index 0000000..856ae20 --- /dev/null +++ b/scripts/initialdata.ts @@ -0,0 +1,29 @@ +import { PrismaClient } from '@prisma/client' +import fs from 'fs' + +const prisma = new PrismaClient() + +async function initialdata() { + const dataDir = './data' + const data = await prisma.data.findFirst() + + if (data) { + if (!fs.existsSync(dataDir)) { + fs.mkdirSync(dataDir) + } + + const parsedData = JSON.parse(data.data) + fs.writeFileSync(`${dataDir}/data.json`, JSON.stringify(parsedData, null, 2)) + } else { + throw new Error('No data found') + } +} + +initialdata() + .catch(e => { + console.error(e) + process.exit(1) + }) + .finally(async () => { + await prisma.$disconnect() + }) diff --git a/scripts/tsconfig.json b/scripts/tsconfig.json new file mode 100644 index 0000000..0e7afc6 --- /dev/null +++ b/scripts/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "module": "commonjs" + } +} diff --git a/src/components/Dash/index.tsx b/src/components/Dash/index.tsx index 7e9443b..1dd9014 100644 --- a/src/components/Dash/index.tsx +++ b/src/components/Dash/index.tsx @@ -2,6 +2,7 @@ import { isEqual } from 'lodash' import { useEffect, useState } from 'react' import { useData } from '../../contexts/DataContext' +import { api } from '../../services/api' import { theme } from '../../styles/stitches.config' import { getLocalStorageData, @@ -38,6 +39,16 @@ export function Dash() { } }, [data, initialData]) + const handleSave = async () => { + try { + await api.put('data', { data }) + setHasUnsavedChanges(false) + removeLocalStorageData() + } catch (error) { + console.error(error) + } + } + const handleChangeBackground = (background: string) => { setData({ ...data, @@ -64,7 +75,14 @@ export function Dash() { return ( -

Dash {hasUnsavedChanges && '- has unsaved changes'}

+

+ Dash{' '} + {hasUnsavedChanges && ( + <> + - has unsaved changes + + )} +

diff --git a/src/pages/api/data.ts b/src/pages/api/data.ts new file mode 100644 index 0000000..23cf06a --- /dev/null +++ b/src/pages/api/data.ts @@ -0,0 +1,38 @@ +import { NextApiRequest, NextApiResponse } from 'next' +import nc from 'next-connect' + +import { prisma } from '../../services/prisma' +const { RAILWAY_TOKEN } = process.env + +const handler = nc() + .get(async (_req, res) => { + try { + const data = await prisma.data.findFirst() + res.status(200).json(data?.data) + } catch (error) { + console.error(error) + res.status(500).send('Internal server error') + } + }) + + .put(async (req, res) => { + try { + const response = await prisma.data.update({ + where: { + id: 1 + }, + data: { data: JSON.stringify(req.body.data) } + }) + + if (RAILWAY_TOKEN) { + console.log('railway token', RAILWAY_TOKEN) + } + + res.status(200).json(response) + } catch (error) { + console.error(error) + res.status(500).send('Internal server error') + } + }) + +export default handler diff --git a/src/services/api.ts b/src/services/api.ts new file mode 100644 index 0000000..cbe003f --- /dev/null +++ b/src/services/api.ts @@ -0,0 +1,7 @@ +import axios from 'axios' + +const { RAILWAY_STATIC_URL } = process.env + +export const api = axios.create({ + baseURL: `${RAILWAY_STATIC_URL}/api` || 'http://localhost:3000/api' +}) diff --git a/src/services/prisma.ts b/src/services/prisma.ts new file mode 100644 index 0000000..04776c7 --- /dev/null +++ b/src/services/prisma.ts @@ -0,0 +1,9 @@ +import { PrismaClient } from '@prisma/client' + +declare global { + var prisma: PrismaClient | undefined +} + +export const prisma = global.prisma || new PrismaClient() + +if (process.env.NODE_ENV !== 'production') global.prisma = prisma diff --git a/yarn.lock b/yarn.lock index 88e05ed..cbc40da 100644 --- a/yarn.lock +++ b/yarn.lock @@ -212,6 +212,18 @@ dependencies: chalk "^4.0.0" +"@cspotcode/source-map-consumer@0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b" + integrity sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg== + +"@cspotcode/source-map-support@0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz#4789840aa859e46d2f3173727ab707c66bf344f5" + integrity sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA== + dependencies: + "@cspotcode/source-map-consumer" "0.8.0" + "@endemolshinegroup/cosmiconfig-typescript-loader@^3.0.2": version "3.0.2" resolved "https://registry.yarnpkg.com/@endemolshinegroup/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-3.0.2.tgz#eea4635828dde372838b0909693ebd9aafeec22d" @@ -391,6 +403,23 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@prisma/client@^3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@prisma/client/-/client-3.6.0.tgz#68a60cd4c73a369b11f72e173e86fd6789939293" + integrity sha512-ycSGY9EZGROtje0iCNsgC5Zqi/ttX2sO7BNMYaLsUMiTlf3F69ZPH+08pRo0hrDfkZzyimXYqeXJlaoYDH1w7A== + dependencies: + "@prisma/engines-version" "3.6.0-24.dc520b92b1ebb2d28dc3161f9f82e875bd35d727" + +"@prisma/engines-version@3.6.0-24.dc520b92b1ebb2d28dc3161f9f82e875bd35d727": + version "3.6.0-24.dc520b92b1ebb2d28dc3161f9f82e875bd35d727" + resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-3.6.0-24.dc520b92b1ebb2d28dc3161f9f82e875bd35d727.tgz#25aa447776849a774885866b998732b37ec4f4f5" + integrity sha512-vtoO2ys6mSfc8ONTWdcYztKN3GBU1tcKBj0aXObyjzSuGwHFcM/pEA0xF+n1W4/0TAJgfoPX2khNEit6g0jtNA== + +"@prisma/engines@3.6.0-24.dc520b92b1ebb2d28dc3161f9f82e875bd35d727": + version "3.6.0-24.dc520b92b1ebb2d28dc3161f9f82e875bd35d727" + resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-3.6.0-24.dc520b92b1ebb2d28dc3161f9f82e875bd35d727.tgz#c68ede6aeffa9ef7743a32cfa6daf9172a4e15b3" + integrity sha512-dRClHS7DsTVchDKzeG72OaEyeDskCv91pnZ72Fftn0mp4BkUvX2LvWup65hCNzwwQm5IDd6A88APldKDnMiEMA== + "@rushstack/eslint-patch@^1.0.8": version "1.1.0" resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.1.0.tgz#7f698254aadf921e48dda8c0a6b304026b8a9323" @@ -401,6 +430,26 @@ resolved "https://registry.yarnpkg.com/@stitches/react/-/react-1.2.6.tgz#61f2a3d1110334ecd33bcb7463650127d42470cb" integrity sha512-gRVITYj8W4jJmoiVxWDv72yCvd12VvtUUAnTzs07EqmtvGCVgKZu3Dx0x5KVCcb0b6tfgvvNH2L84YrzdM4Mag== +"@tsconfig/node10@^1.0.7": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9" + integrity sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg== + +"@tsconfig/node12@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.9.tgz#62c1f6dee2ebd9aead80dc3afa56810e58e1a04c" + integrity sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw== + +"@tsconfig/node14@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.1.tgz#95f2d167ffb9b8d2068b0b235302fafd4df711f2" + integrity sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg== + +"@tsconfig/node16@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e" + integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA== + "@types/json5@^0.0.29": version "0.0.29" resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" @@ -421,7 +470,7 @@ resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== -"@types/node@*", "@types/node@16.11.12": +"@types/node@*", "@types/node@^16.11.12": version "16.11.12" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.12.tgz#ac7fb693ac587ee182c3780c26eb65546a1a3c10" integrity sha512-+2Iggwg7PxoO5Kyhvsq9VarmPbIelXP070HMImEpbtGCoyWNINQj4wzjbQCXzdHTRXnqufutJb5KAURZANNBAw== @@ -512,12 +561,17 @@ acorn-jsx@^5.3.1: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== +acorn-walk@^8.1.1: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + acorn@8.5.0: version "8.5.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.5.0.tgz#4512ccb99b3698c752591e9bb4472e38ad43cee2" integrity sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q== -acorn@^8.6.0: +acorn@^8.4.1, acorn@^8.6.0: version "8.6.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.6.0.tgz#e3692ba0eb1a0c83eaa4f37f5fa7368dd7142895" integrity sha512-U1riIR+lBSNi3IbxtaHOIKdH8sLFv3NYfNv8sg7ZsNhcfl4HF2++BfqqrNAxoCLQW1iiylOj76ecnaUxz+z9yw== @@ -706,6 +760,13 @@ axe-core@^4.3.5: resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.3.5.tgz#78d6911ba317a8262bfee292aeafcc1e04b49cc5" integrity sha512-WKTW1+xAzhMS5dJsxWkliixlO/PqC4VhmO9T4juNYcaTg9jzWiJsou6m5pxWYGfigWbwzJWeFY6z47a+4neRXA== +axios@^0.24.0: + version "0.24.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.24.0.tgz#804e6fa1e4b9c5288501dd9dff56a7a0940d20d6" + integrity sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA== + dependencies: + follow-redirects "^1.14.4" + axobject-query@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" @@ -1797,6 +1858,11 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.4.tgz#28d9969ea90661b5134259f312ab6aa7929ac5e2" integrity sha512-8/sOawo8tJ4QOBX8YlQBMxL8+RLZfxMQOif9o0KUKTNTjMYElWPE0r/m5VNFxTRd0NSw8qSy8dajrwX4RYI1Hw== +follow-redirects@^1.14.4: + version "1.14.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.6.tgz#8cfb281bbc035b3c067d6cd975b0f6ade6e855cd" + integrity sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A== + foreach@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" @@ -2696,6 +2762,13 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= +next-connect@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/next-connect/-/next-connect-0.11.0.tgz#447c7b78937ff71f36c97d03f1623a6d0264ef49" + integrity sha512-7VW5z9MWOpd8wnbST9dXgVd0c0V76LLLk5mBDYLSMtEC2dj3v3YF/Bl3t58cJrzm4SZ0e/s3yeD361F888u0yg== + dependencies: + trouter "^3.1.0" + next@12.0.7: version "12.0.7" resolved "https://registry.yarnpkg.com/next/-/next-12.0.7.tgz#33ebf229b81b06e583ab5ae7613cffe1ca2103fc" @@ -3111,6 +3184,13 @@ pretty-quick@3.1.2: mri "^1.1.5" multimatch "^4.0.0" +prisma@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/prisma/-/prisma-3.6.0.tgz#99532abc02e045e58c6133a19771bdeb28cecdbe" + integrity sha512-6SqgHS/5Rq6HtHjsWsTxlj+ySamGyCLBUQfotc2lStOjPv52IQuDVpp58GieNqc9VnfuFyHUvTZw7aQB+G2fvQ== + dependencies: + "@prisma/engines" "3.6.0-24.dc520b92b1ebb2d28dc3161f9f82e875bd35d727" + process@0.11.10: version "0.11.10" resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" @@ -3305,6 +3385,11 @@ regexp.prototype.flags@^1.3.1: call-bind "^1.0.2" define-properties "^1.1.3" +regexparam@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/regexparam/-/regexparam-1.3.0.tgz#2fe42c93e32a40eff6235d635e0ffa344b92965f" + integrity sha512-6IQpFBv6e5vz1QAqI+V4k8P2e/3gRrqfCJ9FI+O1FLQTO+Uz6RXZEZOPmTJ6hlGj7gkERzY5BRCv09whKP96/g== + regexpp@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" @@ -3819,6 +3904,31 @@ trim-newlines@^3.0.0: resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== +trouter@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/trouter/-/trouter-3.2.0.tgz#a9c510fce21b8e659a28732c9de9d82871efe8df" + integrity sha512-rLLXbhTObLy2MBVjLC+jTnoIKw99n0GuJs9ov10J870vDw5qhTurPzsDrudNtBf5w/CZ9ctZy2p2IMmhGcel2w== + dependencies: + regexparam "^1.3.0" + +ts-node@^10.4.0: + version "10.4.0" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.4.0.tgz#680f88945885f4e6cf450e7f0d6223dd404895f7" + integrity sha512-g0FlPvvCXSIO1JDF6S232P5jPYqBkRL9qly81ZgAOSU7rwI0stphCgd2kLiCrU9DjQCrJMWEqcNSjQL02s6d8A== + dependencies: + "@cspotcode/source-map-support" "0.7.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + yn "3.1.1" + ts-node@^9: version "9.1.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d" @@ -3905,7 +4015,7 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== -typescript@4.5.3, typescript@^4.4.3: +typescript@^4.4.3, typescript@^4.5.3: version "4.5.3" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.5.3.tgz#afaa858e68c7103317d89eb90c5d8906268d353c" integrity sha512-eVYaEHALSt+s9LbvgEv4Ef+Tdq7hBiIZgii12xXJnukryt3pMgJf6aKhoCZ3FWQsu6sydEnkg11fYXLzhLBjeQ==