diff --git a/package.json b/package.json index 8c8694b8..3581c377 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,9 @@ "packages/*" ], "devDependencies": { + "@babel/cli": "^7.13.16", + "@babel/plugin-transform-runtime": "^7.13.15", + "@babel/preset-env": "^7.14.1", "@typescript-eslint/eslint-plugin": "^4.22.0", "@typescript-eslint/parser": "^4.22.0", "eslint": "^7.25.0", diff --git a/packages/prisma-legacy/.babelrc b/packages/prisma-legacy/.babelrc deleted file mode 100644 index 5c8f017e..00000000 --- a/packages/prisma-legacy/.babelrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "presets": [ - [ - "@babel/preset-env", { - "targets": { "node": "12" } - } - ] - ] -} \ No newline at end of file diff --git a/packages/prisma-legacy/.babelrc.js b/packages/prisma-legacy/.babelrc.js new file mode 100644 index 00000000..302737b1 --- /dev/null +++ b/packages/prisma-legacy/.babelrc.js @@ -0,0 +1,9 @@ +// We aim to have the same support as Next.js +// https://nextjs.org/docs/getting-started#system-requirements +// https://nextjs.org/docs/basic-features/supported-browsers-features + +module.exports = { + presets: [["@babel/preset-env", { targets: { node: "10.13" } }]], + plugins: ["@babel/plugin-transform-runtime"], + comments: false, +} diff --git a/packages/prisma-legacy/index.d.ts b/packages/prisma-legacy/index.d.ts new file mode 100644 index 00000000..185925b4 --- /dev/null +++ b/packages/prisma-legacy/index.d.ts @@ -0,0 +1,14 @@ +import { PrismaClient } from ".prisma/client" +import { Adapter } from "next-auth/adapters" + +export type PrismaLegacyAdapter = Adapter<{ + prisma: PrismaClient + modelMapping?: { + User: string + Account: string + Session: string + VerificationRequest: string + } +}> + +export { PrismaLegacyAdapter as Adapter } diff --git a/packages/prisma-legacy/package.json b/packages/prisma-legacy/package.json index 465537b9..3d41f193 100644 --- a/packages/prisma-legacy/package.json +++ b/packages/prisma-legacy/package.json @@ -15,7 +15,8 @@ }, "main": "dist/index.js", "files": [ - "dist" + "dist", + "index.d.ts" ], "private": false, "publishConfig": { @@ -34,8 +35,7 @@ "@prisma/client": "^2.16.1", "next-auth": "^3.17.2" }, - "devDependencies": { - "@babel/cli": "^7.13.16", - "@babel/preset-env": "^7.13.15" + "dependencies": { + "@babel/runtime": "^7.14.0" } } diff --git a/packages/prisma-legacy/src/index.js b/packages/prisma-legacy/src/index.js index 96008d65..027011c1 100644 --- a/packages/prisma-legacy/src/index.js +++ b/packages/prisma-legacy/src/index.js @@ -1,8 +1,7 @@ import { createHash, randomBytes } from "crypto" -import { CreateUserError } from "next-auth/errors" - -function PrismaLegacyAdapter(config) { +/** @type {import("..").Adapter} */ +export function PrismaLegacyAdapter(config) { const { prisma, modelMapping = { @@ -21,410 +20,250 @@ function PrismaLegacyAdapter(config) { .digest("hex") } - async function getAdapter(appOptions) { - const { logger } = appOptions - function debug(debugCode, ...args) { - logger.debug(`PRISMA_${debugCode}`, ...args) - } - - if (appOptions && (!appOptions.session || !appOptions.session.maxAge)) { - debug( - "GET_ADAPTER", - "Session expiry not configured (defaulting to 30 days" - ) - } - - const defaultSessionMaxAge = 30 * 24 * 60 * 60 * 1000 - const sessionMaxAge = - appOptions && appOptions.session && appOptions.session.maxAge - ? appOptions.session.maxAge * 1000 - : defaultSessionMaxAge - const sessionUpdateAge = - appOptions && appOptions.session && appOptions.session.updateAge - ? appOptions.session.updateAge * 1000 - : 0 - - async function createUser(profile) { - debug("CREATE_USER", profile) - try { - return prisma[User].create({ - data: { - name: profile.name, - email: profile.email, - image: profile.image, - emailVerified: profile.emailVerified - ? profile.emailVerified.toISOString() - : null, - }, - }) - } catch (error) { - logger.error("CREATE_USER_ERROR", error) - return Promise.reject(new CreateUserError(error)) - } - } - - async function getUser(id) { - debug("GET_USER", id) - try { - return prisma[User].findUnique({ where: { id } }) - } catch (error) { - logger.error("GET_USER_BY_ID_ERROR", error) - return Promise.reject(new Error("GET_USER_BY_ID_ERROR", error)) - } - } - - async function getUserByEmail(email) { - debug("GET_USER_BY_EMAIL", email) - try { - if (!email) { - return Promise.resolve(null) - } - return prisma[User].findUnique({ where: { email } }) - } catch (error) { - logger.error("GET_USER_BY_EMAIL_ERROR", error) - return Promise.reject(new Error("GET_USER_BY_EMAIL_ERROR", error)) - } - } - - async function getUserByProviderAccountId(providerId, providerAccountId) { - debug("GET_USER_BY_PROVIDER_ACCOUNT_ID", providerId, providerAccountId) - try { - const account = await prisma[Account].findUnique({ - where: { compoundId: getCompoundId(providerId, providerAccountId) }, - }) - if (!account) { + return { + async getAdapter({ + session: { maxAge, updateAge }, + secret, + ...appOptions + }) { + const sessionMaxAge = maxAge * 1000 + const sessionUpdateAge = updateAge * 1000 + + /** + * @todo Move this to core package + * @todo Use bcrypt or a more secure method + */ + const hashToken = (token) => + createHash("sha256").update(`${token}${secret}`).digest("hex") + + return { + createUser(profile) { + return prisma[User].create({ + data: { + name: profile.name, + email: profile.email, + image: profile.image, + emailVerified: profile.emailVerified?.toISOString(), + }, + }) + }, + getUser(id) { + return prisma[User].findUnique({ where: { id } }) + }, + getUserByEmail(email) { + if (email) { + return prisma[User].findUnique({ where: { email } }) + } return null - } - return prisma[User].findUnique({ where: { id: account.userId } }) - } catch (error) { - logger.error("GET_USER_BY_PROVIDER_ACCOUNT_ID_ERROR", error) - return Promise.reject( - new Error("GET_USER_BY_PROVIDER_ACCOUNT_ID_ERROR", error) - ) - } - } - - async function updateUser(user) { - debug("UPDATE_USER", user) - try { - const { id, name, email, image, emailVerified } = user - return prisma[User].update({ - where: { id }, - data: { - name, - email, - image, - emailVerified: emailVerified ? emailVerified.toISOString() : null, - }, - }) - } catch (error) { - logger.error("UPDATE_USER_ERROR", error) - return Promise.reject(new Error("UPDATE_USER_ERROR", error)) - } - } - - async function deleteUser(userId) { - debug("DELETE_USER", userId) - try { - return prisma[User].delete({ where: { id: userId } }) - } catch (error) { - logger.error("DELETE_USER_ERROR", error) - return Promise.reject(new Error("DELETE_USER_ERROR", error)) - } - } - - async function linkAccount( - userId, - providerId, - providerType, - providerAccountId, - refreshToken, - accessToken, - accessTokenExpires - ) { - debug( - "LINK_ACCOUNT", - userId, - providerId, - providerType, - providerAccountId, - refreshToken, - accessToken, - accessTokenExpires - ) - try { - return prisma[Account].create({ - data: { - accessToken, - refreshToken, - compoundId: getCompoundId(providerId, providerAccountId), - providerAccountId: `${providerAccountId}`, - providerId, - providerType, - accessTokenExpires, - userId, - }, - }) - } catch (error) { - logger.error("LINK_ACCOUNT_ERROR", error) - return Promise.reject(new Error("LINK_ACCOUNT_ERROR", error)) - } - } - - async function unlinkAccount(userId, providerId, providerAccountId) { - debug("UNLINK_ACCOUNT", userId, providerId, providerAccountId) - try { - return prisma[Account].delete({ - where: { compoundId: getCompoundId(providerId, providerAccountId) }, - }) - } catch (error) { - logger.error("UNLINK_ACCOUNT_ERROR", error) - return Promise.reject(new Error("UNLINK_ACCOUNT_ERROR", error)) - } - } - - async function createSession(user) { - debug("CREATE_SESSION", user) - try { - let expires = null - if (sessionMaxAge) { - const dateExpires = new Date() - dateExpires.setTime(dateExpires.getTime() + sessionMaxAge) - expires = dateExpires.toISOString() - } - - return prisma[Session].create({ - data: { - expires, - userId: user.id, - sessionToken: randomBytes(32).toString("hex"), - accessToken: randomBytes(32).toString("hex"), - }, - }) - } catch (error) { - logger.error("CREATE_SESSION_ERROR", error) - return Promise.reject(new Error("CREATE_SESSION_ERROR", error)) - } - } - - async function getSession(sessionToken) { - debug("GET_SESSION", sessionToken) - try { - const session = await prisma[Session].findUnique({ - where: { sessionToken }, - }) - - // Check session has not expired (do not return it if it has) - if (session && session.expires && new Date() > session.expires) { - await prisma[Session].delete({ where: { sessionToken } }) + }, + async getUserByProviderAccountId(providerId, providerAccountId) { + const account = await prisma[Account].findUnique({ + where: { + compoundId: getCompoundId(providerId, providerAccountId), + }, + }) + if (account) { + return prisma[User].findUnique({ where: { id: account.userId } }) + } return null - } + }, + + updateUser(user) { + const { id, name, email, image, emailVerified } = user + return prisma[User].update({ + where: { id }, + data: { + name, + email, + image, + emailVerified: emailVerified?.toISOString(), + }, + }) + }, + + deleteUser(userId) { + return prisma[User].delete({ where: { id: userId } }) + }, + + linkAccount( + userId, + providerId, + providerType, + providerAccountId, + refreshToken, + accessToken, + accessTokenExpires + ) { + return prisma[Account].create({ + data: { + accessToken, + refreshToken, + compoundId: getCompoundId(providerId, providerAccountId), + providerAccountId: `${providerAccountId}`, + providerId, + providerType, + accessTokenExpires, + userId, + }, + }) + }, - return session - } catch (error) { - logger.error("GET_SESSION_ERROR", error) - return Promise.reject(new Error("GET_SESSION_ERROR", error)) - } - } + unlinkAccount(_, providerId, providerAccountId) { + return prisma[Account].delete({ + where: { + compoundId: getCompoundId(providerId, providerAccountId), + }, + }) + }, + + createSession(user) { + let expires = null + if (sessionMaxAge) { + const dateExpires = new Date() + dateExpires.setTime(dateExpires.getTime() + sessionMaxAge) + expires = dateExpires.toISOString() + } - async function updateSession(session, force) { - debug("UPDATE_SESSION", session) - try { - if ( - sessionMaxAge && - (sessionUpdateAge || sessionUpdateAge === 0) && - session.expires - ) { - // Calculate last updated date, to throttle write updates to database - // Formula: ({expiry date} - sessionMaxAge) + sessionUpdateAge - // e.g. ({expiry date} - 30 days) + 1 hour - // - // Default for sessionMaxAge is 30 days. - // Default for sessionUpdateAge is 1 hour. - const dateSessionIsDueToBeUpdated = new Date(session.expires) - dateSessionIsDueToBeUpdated.setTime( - dateSessionIsDueToBeUpdated.getTime() - sessionMaxAge - ) - dateSessionIsDueToBeUpdated.setTime( - dateSessionIsDueToBeUpdated.getTime() + sessionUpdateAge - ) + return prisma[Session].create({ + data: { + expires, + userId: user.id, + sessionToken: randomBytes(32).toString("hex"), + accessToken: randomBytes(32).toString("hex"), + }, + }) + }, - // Trigger update of session expiry date and write to database, only - // if the session was last updated more than {sessionUpdateAge} ago - if (new Date() > dateSessionIsDueToBeUpdated) { - const newExpiryDate = new Date() - newExpiryDate.setTime(newExpiryDate.getTime() + sessionMaxAge) - session.expires = newExpiryDate - } else if (!force) { + async getSession(sessionToken) { + const session = await prisma[Session].findUnique({ + where: { sessionToken }, + }) + + // Check session has not expired (do not return it if it has) + if (session?.expires && new Date() > session.expires) { + await prisma[Session].delete({ where: { sessionToken } }) return null } - } else { - // If session MaxAge, session UpdateAge or session.expires are - // missing then don't even try to save changes, unless force is set. - if (!force) { - return null + + return session + }, + + updateSession(session, force) { + if ( + sessionMaxAge && + (sessionUpdateAge || sessionUpdateAge === 0) && + session.expires + ) { + // Calculate last updated date, to throttle write updates to database + // Formula: ({expiry date} - sessionMaxAge) + sessionUpdateAge + // e.g. ({expiry date} - 30 days) + 1 hour + // + // Default for sessionMaxAge is 30 days. + // Default for sessionUpdateAge is 1 hour. + const dateSessionIsDueToBeUpdated = new Date(session.expires) + dateSessionIsDueToBeUpdated.setTime( + dateSessionIsDueToBeUpdated.getTime() - sessionMaxAge + ) + dateSessionIsDueToBeUpdated.setTime( + dateSessionIsDueToBeUpdated.getTime() + sessionUpdateAge + ) + + // Trigger update of session expiry date and write to database, only + // if the session was last updated more than {sessionUpdateAge} ago + if (new Date() > dateSessionIsDueToBeUpdated) { + const newExpiryDate = new Date() + newExpiryDate.setTime(newExpiryDate.getTime() + sessionMaxAge) + session.expires = newExpiryDate + } else if (!force) { + return null + } + } else { + // If session MaxAge, session UpdateAge or session.expires are + // missing then don't even try to save changes, unless force is set. + if (!force) { + return null + } } - } - const { id, expires } = session - return prisma[Session].update({ - where: { id }, - data: { expires: expires.toISOString() }, - }) - } catch (error) { - logger.error("UPDATE_SESSION_ERROR", error) - return Promise.reject(new Error("UPDATE_SESSION_ERROR", error)) - } - } + const { id, expires } = session + return prisma[Session].update({ + where: { id }, + data: { expires: expires.toISOString() }, + }) + }, - async function deleteSession(sessionToken) { - debug("DELETE_SESSION", sessionToken) - try { - return prisma[Session].delete({ where: { sessionToken } }) - } catch (error) { - logger.error("DELETE_SESSION_ERROR", error) - return Promise.reject(new Error("DELETE_SESSION_ERROR", error)) - } - } + deleteSession(sessionToken) { + return prisma[Session].delete({ where: { sessionToken } }) + }, - async function createVerificationRequest( - identifier, - url, - token, - secret, - provider - ) { - debug("CREATE_VERIFICATION_REQUEST", identifier) - try { - const { baseUrl } = appOptions - const { sendVerificationRequest, maxAge } = provider + async createVerificationRequest(identifier, url, token, _, provider) { + const { sendVerificationRequest, maxAge } = provider - // Store hashed token (using secret as salt) so that tokens cannot be exploited - // even if the contents of the database is compromised. - // @TODO Use bcrypt function here instead of simple salted hash - const hashedToken = createHash("sha256") - .update(`${token}${secret}`) - .digest("hex") + let expires = null + if (maxAge) { + const dateExpires = new Date() + dateExpires.setTime(dateExpires.getTime() + maxAge * 1000) + expires = dateExpires.toISOString() + } - let expires = null - if (maxAge) { - const dateExpires = new Date() - dateExpires.setTime(dateExpires.getTime() + maxAge * 1000) - expires = dateExpires.toISOString() - } + // Save to database + const verificationRequest = await prisma[VerificationRequest].create({ + data: { + identifier, + token: hashToken(token), + expires, + }, + }) - // Save to database - const verificationRequest = await prisma[VerificationRequest].create({ - data: { + // With the verificationCallback on a provider, you can send an email, or queue + // an email to be sent, or perform some other action (e.g. send a text message) + await sendVerificationRequest({ identifier, - token: hashedToken, - expires, - }, - }) - - // With the verificationCallback on a provider, you can send an email, or queue - // an email to be sent, or perform some other action (e.g. send a text message) - await sendVerificationRequest({ - identifier, - url, - token, - baseUrl, - provider, - }) + url, + token, + baseUrl: appOptions.baseUrl, + provider, + }) - return verificationRequest - } catch (error) { - logger.error("CREATE_VERIFICATION_REQUEST_ERROR", error) - return Promise.reject( - new Error("CREATE_VERIFICATION_REQUEST_ERROR", error) - ) - } - } + return verificationRequest + }, - async function getVerificationRequest(identifier, token, secret, provider) { - debug("GET_VERIFICATION_REQUEST", identifier, token) - try { - // Hash token provided with secret before trying to match it with database - // @TODO Use bcrypt instead of salted SHA-256 hash for token - const hashedToken = createHash("sha256") - .update(`${token}${secret}`) - .digest("hex") - const verificationRequest = await prisma[VerificationRequest].findFirst( - { + async getVerificationRequest(identifier, token) { + // Hash token provided with secret before trying to match it with database + // @TODO Use bcrypt instead of salted SHA-256 hash for token + const hashedToken = hashToken(token) + const verificationRequest = await prisma[ + VerificationRequest + ].findFirst({ where: { identifier, token: hashedToken, }, + }) + if ( + verificationRequest && + verificationRequest.expires && + new Date() > verificationRequest.expires + ) { + // Delete verification entry so it cannot be used again + await prisma[VerificationRequest].deleteMany({ + where: { identifier, token: hashedToken }, + }) + return null } - ) - if ( - verificationRequest && - verificationRequest.expires && - new Date() > verificationRequest.expires - ) { + + return verificationRequest + }, + + async deleteVerificationRequest(identifier, token) { // Delete verification entry so it cannot be used again await prisma[VerificationRequest].deleteMany({ - where: { identifier, token: hashedToken }, + where: { identifier, token: hashToken(token) }, }) - return null - } - - return verificationRequest - } catch (error) { - logger.error("GET_VERIFICATION_REQUEST_ERROR", error) - return Promise.reject( - new Error("GET_VERIFICATION_REQUEST_ERROR", error) - ) + }, } - } - - async function deleteVerificationRequest( - identifier, - token, - secret, - provider - ) { - debug("DELETE_VERIFICATION", identifier, token) - try { - // Delete verification entry so it cannot be used again - const hashedToken = createHash("sha256") - .update(`${token}${secret}`) - .digest("hex") - await prisma[VerificationRequest].deleteMany({ - where: { identifier, token: hashedToken }, - }) - } catch (error) { - logger.error("DELETE_VERIFICATION_REQUEST_ERROR", error) - return Promise.reject( - new Error("DELETE_VERIFICATION_REQUEST_ERROR", error) - ) - } - } - - return Promise.resolve({ - createUser, - getUser, - getUserByEmail, - getUserByProviderAccountId, - updateUser, - deleteUser, - linkAccount, - unlinkAccount, - createSession, - getSession, - updateSession, - deleteSession, - createVerificationRequest, - getVerificationRequest, - deleteVerificationRequest, - }) - } - - return { - getAdapter, + }, } } -export default { - Adapter: PrismaLegacyAdapter, -} +export { PrismaLegacyAdapter as Adapter } diff --git a/packages/typeorm-legacy/package.json b/packages/typeorm-legacy/package.json index 1c75ed03..109433d4 100644 --- a/packages/typeorm-legacy/package.json +++ b/packages/typeorm-legacy/package.json @@ -44,9 +44,6 @@ "typeorm": "^0.2.30" }, "devDependencies": { - "@babel/cli": "^7.13.16", - "@babel/plugin-transform-runtime": "^7.13.15", - "@babel/preset-env": "^7.13.15", "assert": "^2.0.0", "jest": "^26.6.3", "mongodb": "^3.6.3", diff --git a/yarn.lock b/yarn.lock index f60a73ea..6c22f931 100644 --- a/yarn.lock +++ b/yarn.lock @@ -102,11 +102,11 @@ source-map "^0.5.0" "@babel/generator@^7.14.0": - version "7.14.1" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.1.tgz#1f99331babd65700183628da186f36f63d615c93" - integrity sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ== + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.0.tgz#0f35d663506c43e4f10898fbda0d752ec75494be" + integrity sha512-C6u00HbmsrNPug6A+CiNl8rEys7TsdcXwg12BHi2ca5rUfAs3+UwZsuDQSXnc+wCElCXMB8gMaJ3YXDdh8fAlg== dependencies: - "@babel/types" "^7.14.1" + "@babel/types" "^7.14.0" jsesc "^2.5.1" source-map "^0.5.0" @@ -318,11 +318,16 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.12.13", "@babel/parser@^7.14.0": +"@babel/parser@^7.1.0", "@babel/parser@^7.12.13": version "7.14.1" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.1.tgz#1bd644b5db3f5797c4479d89ec1817fe02b84c47" integrity sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q== +"@babel/parser@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.0.tgz#2f0ebfed92bcddcc8395b91f1895191ce2760380" + integrity sha512-AHbfoxesfBALg33idaTBVUkLnfXtsgvJREf93p4p0Lwsz4ppfE7g1tpEXVm4vrxUcH4DVhAa9Z1m1zqf9WUC7Q== + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.13.12": version "7.13.12" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.13.12.tgz#a3484d84d0b549f3fc916b99ee4783f26fabad2a" @@ -831,7 +836,7 @@ "@babel/helper-create-regexp-features-plugin" "^7.12.13" "@babel/helper-plugin-utils" "^7.12.13" -"@babel/preset-env@^7.13.15": +"@babel/preset-env@^7.14.1": version "7.14.1" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.14.1.tgz#b55914e2e68885ea03f69600b2d3537e54574a93" integrity sha512-0M4yL1l7V4l+j/UHvxcdvNfLB9pPtIooHTbEhgD/6UGyh8Hy3Bm1Mj0buzjDXATCSz3JFibVdnoJZCrlUCanrQ== @@ -951,7 +956,7 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.16", "@babel/types@^7.14.0", "@babel/types@^7.14.1", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": +"@babel/types@^7.0.0", "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.13.16", "@babel/types@^7.14.1", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": version "7.14.1" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.1.tgz#095bd12f1c08ab63eff6e8f7745fa7c9cc15a9db" integrity sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA== @@ -959,6 +964,14 @@ "@babel/helper-validator-identifier" "^7.14.0" to-fast-properties "^2.0.0" +"@babel/types@^7.14.0": + version "7.14.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.0.tgz#3fc3fc74e0cdad878182e5f66cc6bcab1915a802" + integrity sha512-O2LVLdcnWplaGxiPBz12d0HcdN8QdxdsWYhz5LSeuukV/5mn2xUUc3gBeU4QBYPJ18g/UToe8F532XJ608prmg== + dependencies: + "@babel/helper-validator-identifier" "^7.14.0" + to-fast-properties "^2.0.0" + "@bcoe/v8-coverage@^0.2.3": version "0.2.3" resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" @@ -3606,9 +3619,9 @@ copy-descriptor@^0.1.0: integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= core-js-compat@^3.9.0, core-js-compat@^3.9.1: - version "3.12.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.12.0.tgz#a031e51fe411085e33cb629bfee2acaa53bc309a" - integrity sha512-vvaN8EOvYBEjrr+MN3vCKrMNc/xdYZI+Rt/uPMROi4T5Hj8Fz6TiPQm2mrB9aZoQVW1lCFHYmMrv99aUct9mkg== + version "3.12.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.12.1.tgz#2c302c4708505fa7072b0adb5156d26f7801a18b" + integrity sha512-i6h5qODpw6EsHAoIdQhKoZdWn+dGBF3dSS8m5tif36RlWvW3A6+yu2S16QHUo3CrkzrnEskMAt9f8FxmY9fhWQ== dependencies: browserslist "^4.16.6" semver "7.0.0"