From 404d193b46f9e6fd1a2af384fa0670583ddf230f Mon Sep 17 00:00:00 2001 From: Arthur DANJOU Date: Thu, 1 Jul 2021 16:13:22 +0200 Subject: [PATCH] Working Signed-off-by: Arthur DANJOU --- ace-manifest.json | 2 +- app/Controllers/Http/AuthController.ts | 25 ++++++++----- app/Controllers/Http/FileController.ts | 26 ++++++++----- app/Controllers/Http/FormsController.ts | 3 +- app/Controllers/Http/GuestBookController.ts | 23 ++++++++---- app/Controllers/Http/PostsController.ts | 8 ++-- app/Controllers/Http/ProfileController.ts | 11 +++--- app/Controllers/Http/ProjectsController.ts | 5 +-- app/Controllers/Http/StatesController.ts | 4 +- app/Controllers/Http/SubscribersController.ts | 17 +++++++-- app/Controllers/Http/UsersController.ts | 37 ++++++++++--------- app/Models/GuestBookMessage.ts | 4 +- app/Models/User.ts | 20 +++++----- app/Validators/guestbook/GuestValidator.ts | 6 +-- app/Validators/users/UserUpdateValidator.ts | 12 +++--- .../migrations/1608409476823_locations.ts | 2 +- database/migrations/1618661863952_forms.ts | 2 +- .../1621542488791_golden_messages.ts | 18 --------- .../1625146912533_guestbook_messages.ts | 22 +++++++++++ yarn.lock | 23 ++++++------ 20 files changed, 154 insertions(+), 116 deletions(-) delete mode 100755 database/migrations/1621542488791_golden_messages.ts create mode 100644 database/migrations/1625146912533_guestbook_messages.ts mode change 100755 => 100644 yarn.lock diff --git a/ace-manifest.json b/ace-manifest.json index 77bd59c..b53470f 100755 --- a/ace-manifest.json +++ b/ace-manifest.json @@ -136,7 +136,7 @@ "name": "connection", "propertyName": "connection", "type": "string", - "description": "Define a custom database connection for the migration" + "description": "The connection flag is used to lookup the directory for the migration file" }, { "name": "folder", diff --git a/app/Controllers/Http/AuthController.ts b/app/Controllers/Http/AuthController.ts index 2bac585..57cc783 100755 --- a/app/Controllers/Http/AuthController.ts +++ b/app/Controllers/Http/AuthController.ts @@ -7,24 +7,29 @@ export default class AuthController { public async login ({ request, auth, response }: HttpContextContract) { const email = request.input('email') const password = request.input('password') + const infinity = request.input('infinity', false) const token = await auth.attempt(email, password, { - expiresIn: '2 days' + expiresIn: infinity ? '' : '2 days' + }) + return response.status(200).send({ + token: token.toJSON() }) - return response.status(200).send(token.toJSON()) } public async createInfiniteToken ({ request, auth, response }: HttpContextContract) { const email = request.input('email') const password = request.input('password') const token = await auth.attempt(email, password) - return response.status(200).send(token.toJSON()) + return response.status(200).send({ + token: token.toJSON() + }) } public async logout ({ auth, response }: HttpContextContract) { await auth.logout() return response.status(200).send({ - message: 'You have been disconnected' + message: 'You have been disconnected!' }) } @@ -43,13 +48,13 @@ export default class AuthController { if (twitter.accessDenied()) { return response.status(403).send({ - message: 'Access Denied' + message: 'Access Denied!' }) } if (twitter.stateMisMatch()) { return response.status(405).send({ - message: 'Request expired. Retry again' + message: 'Request expired. Retry again!' }) } @@ -72,13 +77,13 @@ export default class AuthController { if (github.accessDenied()) { return response.status(403).send({ - message: 'Access Denied' + message: 'Access Denied!' }) } if (github.stateMisMatch()) { return response.status(405).send({ - message: 'Request expired. Retry again' + message: 'Request expired. Retry again!' }) } @@ -101,13 +106,13 @@ export default class AuthController { if (google.accessDenied()) { return response.status(403).send({ - message: 'Access Denied' + message: 'Access Denied!' }) } if (google.stateMisMatch()) { return response.status(405).send({ - message: 'Request expired. Retry again' + message: 'Request expired. Retry again!' }) } diff --git a/app/Controllers/Http/FileController.ts b/app/Controllers/Http/FileController.ts index 8acea6a..5cef60e 100755 --- a/app/Controllers/Http/FileController.ts +++ b/app/Controllers/Http/FileController.ts @@ -1,21 +1,23 @@ -import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext' +import {HttpContextContract} from '@ioc:Adonis/Core/HttpContext' import Application from "@ioc:Adonis/Core/Application"; import File from "App/Models/File"; export default class FileController { - public async index () { - return File.query() + public async index({response}: HttpContextContract) { + return response.status(200).send({ + files: File.query() + }) } - public async store ({request}: HttpContextContract) { + public async store({request, response}: HttpContextContract) { const file = await request.file('file', { extnames: ['jpg', 'png', 'jpeg'] }) const label = request.input('label') if (!file) { - return 'Please upload file' + return 'Please upload file!' } if (file.hasErrors) { return file.errors @@ -25,16 +27,20 @@ export default class FileController { name: `${label}.${file.extname}` }) - return await File.create({ - fileName: `${label}.${file.extname}`, - label: label + return response.status(200).send({ + file: await File.create({ + fileName: `${label}.${file.extname}`, + label: label + }) }) } - public async destroy({ params }: HttpContextContract) { + public async destroy({params, response}: HttpContextContract) { const file = await File.findOrFail(params.id) await file.delete() - return { message: "Le fichier a bien été supprimée" } + return response.status(200).send({ + message: 'File successfully deleted!' + }) } } diff --git a/app/Controllers/Http/FormsController.ts b/app/Controllers/Http/FormsController.ts index 711b19e..f97b3b0 100755 --- a/app/Controllers/Http/FormsController.ts +++ b/app/Controllers/Http/FormsController.ts @@ -1,4 +1,4 @@ -import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext' +import {HttpContextContract} from '@ioc:Adonis/Core/HttpContext' import FormValidator from "App/Validators/FormValidator"; import Form from "App/Models/Form"; import FormConfirmation from "App/Mailers/FormConfirmation"; @@ -7,7 +7,6 @@ export default class FormsController { public async send({ request, response }: HttpContextContract) { const data = await request.validate(FormValidator) - await Form.create(data) await new FormConfirmation(data.name, data.email).preview() diff --git a/app/Controllers/Http/GuestBookController.ts b/app/Controllers/Http/GuestBookController.ts index cd57426..e3cdf9a 100755 --- a/app/Controllers/Http/GuestBookController.ts +++ b/app/Controllers/Http/GuestBookController.ts @@ -4,15 +4,24 @@ import GuestValidator from "App/Validators/guestbook/GuestValidator"; export default class GuestBookController { - public async get () { - return GuestBookMessage.query().orderBy('created_at', 'desc') + public async get({response}: HttpContextContract) { + return response.status(200).send({ + guestbook_messages: GuestBookMessage.query().orderBy('created_at', 'desc') + }) } - public async store ({request, auth}: HttpContextContract) { - if (auth.isLoggedIn) { - const data = await request.validate(GuestValidator) - return await GuestBookMessage.create(data) - } + public async store({request, auth, response}: HttpContextContract) { + const data = await request.validate(GuestValidator) + const user = await auth.user! + const guestbook_message = user.related('guestbook_message').firstOrCreate({ + userId: user.id + }, { + ...data, + userId: user.id + }) + return response.status(200).send({ + guestbook_message + }) } } diff --git a/app/Controllers/Http/PostsController.ts b/app/Controllers/Http/PostsController.ts index 66ce3fa..5a54d0f 100755 --- a/app/Controllers/Http/PostsController.ts +++ b/app/Controllers/Http/PostsController.ts @@ -3,7 +3,7 @@ import {HttpContextContract} from "@ioc:Adonis/Core/HttpContext"; export default class PostsController { - public async getLikes ({params}: HttpContextContract) { + public async getLikes({params, response}: HttpContextContract) { let post = await Post.findBy('slug', params.slug) if (!post) { @@ -13,7 +13,9 @@ export default class PostsController { }) } - return post.likes + return response.status(200).send({ + likes: post.likes + }) } public async like ({params, response}: HttpContextContract) { @@ -32,7 +34,6 @@ export default class PostsController { likes: getLikes }).save() return response.status(200).send({ - status: 200, post }) } @@ -46,7 +47,6 @@ export default class PostsController { likes: getLikes }).save() return response.status(200).send({ - status: 200, post }) } diff --git a/app/Controllers/Http/ProfileController.ts b/app/Controllers/Http/ProfileController.ts index 78eedaf..b1324f2 100755 --- a/app/Controllers/Http/ProfileController.ts +++ b/app/Controllers/Http/ProfileController.ts @@ -10,7 +10,8 @@ export default class ProfileController { "Dev", "DevOps", "New technologies", - "Gaming" + "Gaming", + "Cloud" ], code: [ "Javascript", @@ -29,18 +30,18 @@ export default class ProfileController { "Software dev" ], technologies: { - web_app: ["VueJs", "NuxtJs", "Sass", "Tailwind"], + web_app: ["VueJs", "NuxtJs", "Sass", "Tailwind", "WindiCss"], desktop_app: ["ElectronJs"], - mobile_app: ["React Native"], + mobile_app: ["React Native", "Vue Native"], back_end: { typescript: ["AdonisJs"], java: ["Spring"] }, databases: ["MongoDB", "MariaDB", "Redis"], - messaging: ["RabbitMq"], + messaging: ["RabbitMQ"], other: ["Docker", "Git"], architecture: ["microservices", "event-driven", "design system pattern"], - operating_systems: ['Windows', 'Linux'] + operating_systems: ['MacOS', "Linux"] }, }) } diff --git a/app/Controllers/Http/ProjectsController.ts b/app/Controllers/Http/ProjectsController.ts index 212ce49..813f018 100755 --- a/app/Controllers/Http/ProjectsController.ts +++ b/app/Controllers/Http/ProjectsController.ts @@ -1,13 +1,12 @@ -import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext' +import {HttpContextContract} from '@ioc:Adonis/Core/HttpContext' import Project from "App/Models/Project"; import ProjectValidator from "App/Validators/project/ProjectValidator"; export default class ProjectsController { public async get ({ response }: HttpContextContract) { - const projects = await Project.query().orderBy('id', 'asc') return response.status(200).send({ - projects + projects: await Project.query().orderBy('id', 'asc') }) } diff --git a/app/Controllers/Http/StatesController.ts b/app/Controllers/Http/StatesController.ts index 7c4f067..765306f 100755 --- a/app/Controllers/Http/StatesController.ts +++ b/app/Controllers/Http/StatesController.ts @@ -4,7 +4,7 @@ import {UpdateGitHubReadme} from "App/Tasks/UpdateGithubReadme"; export default class StatesController { - public async get ({response}: HttpContextContract) { + public async get({response}: HttpContextContract) { const is_sleeping = await Redis.get('states:sleeping') const is_listening_music = await Redis.get('states:listening') const is_developing = await Redis.get('states:developing') @@ -18,7 +18,7 @@ export default class StatesController { }) } - public async set ({request, response, params}: HttpContextContract) { + public async set({request, response, params}: HttpContextContract) { const state = params.state const value = await request.input('value') diff --git a/app/Controllers/Http/SubscribersController.ts b/app/Controllers/Http/SubscribersController.ts index b4ef8e1..e26c4b7 100755 --- a/app/Controllers/Http/SubscribersController.ts +++ b/app/Controllers/Http/SubscribersController.ts @@ -1,4 +1,4 @@ -import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext' +import {HttpContextContract} from '@ioc:Adonis/Core/HttpContext' import Subscriber from "App/Models/Subscriber"; import SubscriberValidator from "App/Validators/subscriber/SubscriberValidator"; @@ -10,12 +10,23 @@ export default class SubscribersController { }) } - public async store ({ request, response }: HttpContextContract) { + public async store({request, response}: HttpContextContract) { const data = await request.validate(SubscriberValidator) await Subscriber.create(data) return response.status(200).send({ - message: 'Subscriber successfully registered !' + message: 'Subscriber successfully registered!' }) } + public async delete({request, response}: HttpContextContract) { + const data = await request.validate(SubscriberValidator) + const subscriber = await Subscriber.findBy('email', data.email) + if (subscriber) { + await subscriber.delete() + return response.status(200).send({ + message: 'Subscriber successfully deleted!' + }) + } + } + } diff --git a/app/Controllers/Http/UsersController.ts b/app/Controllers/Http/UsersController.ts index 992ffeb..ecb65dc 100755 --- a/app/Controllers/Http/UsersController.ts +++ b/app/Controllers/Http/UsersController.ts @@ -5,34 +5,33 @@ import UserUpdateValidator from "App/Validators/users/UserUpdateValidator"; export default class UsersController { - public async index () { - return User.query() + public async index({response}: HttpContextContract) { + return response.status(200).send({ + users: User.query() + }) } - public async store ({request}: HttpContextContract) { + public async store({request, response}: HttpContextContract) { const data = await request.validate(UserStoreValidator) - return await User.create(data) + return response.status(200).send({ + user: await User.create(data) + }) } - public async show ({params}: HttpContextContract) { - return await User.findOrFail(params.id) + public async show({params, response}: HttpContextContract) { + return response.status(200).send({ + user: await User.findOrFail(params.id) + }) } - public async update({ request, params, response }: HttpContextContract) { + public async update({request, params, response}: HttpContextContract) { const user = await User.findOrFail(params.id) const data = await request.validate(UserUpdateValidator) - const { email } = data - const user2 = await User.findBy('email', email) - - if (user2 !== null && user.email !== email) { - return response.abort({ - message: 'L\' adresse mail n\'est pas unique !' - }) - } - await user.merge(data).save() - return { message: 'Le compte a été mis à jour' } + return response.status(200).send({ + message: 'User successfully updated!' + }) } public async destroy({ response, params, auth }: HttpContextContract) { @@ -44,7 +43,9 @@ export default class UsersController { } await user.delete() - return { message: "L'utilisateur a bien été supprimé" } + return response.status(200).send({ + message: 'User successfully deleted!' + }) } } diff --git a/app/Models/GuestBookMessage.ts b/app/Models/GuestBookMessage.ts index 1a4e261..da4948f 100755 --- a/app/Models/GuestBookMessage.ts +++ b/app/Models/GuestBookMessage.ts @@ -1,6 +1,6 @@ -import { DateTime } from 'luxon' +import {DateTime} from 'luxon' import {BaseModel, BelongsTo, belongsTo, column} from '@ioc:Adonis/Lucid/Orm' -import User from "./User"; +import User from "App/Models/User"; export default class GuestBookMessage extends BaseModel { @column({ isPrimary: true }) diff --git a/app/Models/User.ts b/app/Models/User.ts index d92ef39..e51efd6 100755 --- a/app/Models/User.ts +++ b/app/Models/User.ts @@ -1,13 +1,10 @@ -import { DateTime } from 'luxon' +import {DateTime} from 'luxon' import Hash from '@ioc:Adonis/Core/Hash' -import { - column, - beforeSave, - BaseModel, -} from '@ioc:Adonis/Lucid/Orm' +import {BaseModel, beforeSave, column, hasOne, HasOne,} from '@ioc:Adonis/Lucid/Orm' +import GuestBookMessage from "App/Models/GuestBookMessage"; export default class User extends BaseModel { - @column({ isPrimary: true }) + @column({isPrimary: true}) public id: number @column() @@ -28,14 +25,17 @@ export default class User extends BaseModel { @column() public rememberMeToken?: string - @column.dateTime({ autoCreate: true }) + @hasOne(() => GuestBookMessage) + public guestbook_message: HasOne + + @column.dateTime({autoCreate: true}) public createdAt: DateTime - @column.dateTime({ autoCreate: true, autoUpdate: true }) + @column.dateTime({autoCreate: true, autoUpdate: true}) public updatedAt: DateTime @beforeSave() - public static async hashPassword (user: User) { + public static async hashPassword(user: User) { if (user.$dirty.password) { user.password = await Hash.make(user.password) } diff --git a/app/Validators/guestbook/GuestValidator.ts b/app/Validators/guestbook/GuestValidator.ts index dca0283..5736ff1 100755 --- a/app/Validators/guestbook/GuestValidator.ts +++ b/app/Validators/guestbook/GuestValidator.ts @@ -1,4 +1,4 @@ -import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext' +import {HttpContextContract} from '@ioc:Adonis/Core/HttpContext' import {rules, schema} from '@ioc:Adonis/Core/Validator' export default class GuestValidator { @@ -6,10 +6,10 @@ export default class GuestValidator { } public schema = schema.create({ - user_id: schema.number( [ + user_id: schema.number([ rules.required(), rules.unique({table: 'golden_messages', column: 'user_id'}), - rules.exists({ table: 'users', column: 'id'}) + rules.exists({table: 'users', column: 'id'}) ]), message: schema.string({}, [ rules.required() diff --git a/app/Validators/users/UserUpdateValidator.ts b/app/Validators/users/UserUpdateValidator.ts index 9badcf3..0ec1aaf 100755 --- a/app/Validators/users/UserUpdateValidator.ts +++ b/app/Validators/users/UserUpdateValidator.ts @@ -1,4 +1,4 @@ -import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext' +import {HttpContextContract} from '@ioc:Adonis/Core/HttpContext' import {rules, schema} from '@ioc:Adonis/Core/Validator' export default class UserUpdateValidator { @@ -6,11 +6,13 @@ export default class UserUpdateValidator { } public schema = schema.create({ - email: schema.string.optional({ trim: true, escape: true }, [rules.email()]), - password: schema.string.optional({ trim: true, escape: true }, [rules.confirmed()]), + email: schema.string.optional({trim: true, escape: true}, [rules.email(), rules.unique({ + table: 'users', column: 'email' + })]), + password: schema.string.optional({trim: true, escape: true}, [rules.confirmed()]), is_confirmed: schema.boolean.optional(), - confirmation_token: schema.string.optional({ trim: true, escape: true }), - remember_me: schema.string.optional({ trim: true, escape: true }), + confirmation_token: schema.string.optional({trim: true, escape: true}), + remember_me: schema.string.optional({trim: true, escape: true}), }) public cacheKey = this.ctx.routeKey diff --git a/database/migrations/1608409476823_locations.ts b/database/migrations/1608409476823_locations.ts index dd562e9..de1d485 100755 --- a/database/migrations/1608409476823_locations.ts +++ b/database/migrations/1608409476823_locations.ts @@ -5,7 +5,7 @@ export default class Locations extends BaseSchema { public async up () { this.schema.createTable(this.tableName, (table) => { - table.increments('id') + table.increments('id').primary() table.string('place') table.string('left') table.date('since') diff --git a/database/migrations/1618661863952_forms.ts b/database/migrations/1618661863952_forms.ts index b6a87ca..d59a0ed 100755 --- a/database/migrations/1618661863952_forms.ts +++ b/database/migrations/1618661863952_forms.ts @@ -5,7 +5,7 @@ export default class Forms extends BaseSchema { public async up () { this.schema.createTable(this.tableName, (table) => { - table.increments('id') + table.increments('id').primary() table.string('name') table.string('email') table.string('subject') diff --git a/database/migrations/1621542488791_golden_messages.ts b/database/migrations/1621542488791_golden_messages.ts deleted file mode 100755 index a954528..0000000 --- a/database/migrations/1621542488791_golden_messages.ts +++ /dev/null @@ -1,18 +0,0 @@ -import BaseSchema from '@ioc:Adonis/Lucid/Schema' - -export default class GoldenMessages extends BaseSchema { - protected tableName = 'golden_messages' - - public async up () { - this.schema.createTable(this.tableName, (table) => { - table.increments('id') - table.integer('user_id').notNullable() - table.string('message') - table.timestamps() - }) - } - - public async down () { - this.schema.dropTable(this.tableName) - } -} diff --git a/database/migrations/1625146912533_guestbook_messages.ts b/database/migrations/1625146912533_guestbook_messages.ts new file mode 100644 index 0000000..19f22c2 --- /dev/null +++ b/database/migrations/1625146912533_guestbook_messages.ts @@ -0,0 +1,22 @@ +import BaseSchema from '@ioc:Adonis/Lucid/Schema' + +export default class GuestbookMessages extends BaseSchema { + protected tableName = 'guestbook_messages' + + public async up() { + this.schema.createTable(this.tableName, (table) => { + table.increments('id').primary() + table + .integer('user_id') + .unsigned() + .references('users.id') + .onDelete('CASCADE') + table.string('message') + table.timestamps(true, true) + }) + } + + public async down() { + this.schema.dropTable(this.tableName) + } +} diff --git a/yarn.lock b/yarn.lock old mode 100755 new mode 100644 index da42bef..fea65ad --- a/yarn.lock +++ b/yarn.lock @@ -191,9 +191,9 @@ pino "^6.11.3" "@adonisjs/lucid@^15.0.1": - version "15.0.1" - resolved "https://registry.yarnpkg.com/@adonisjs/lucid/-/lucid-15.0.1.tgz#a8cdf12f3ae6bc5fa88d452e80423cf3afb8e598" - integrity sha512-ab3tJ9JgafaXvtOzyqd83Xs6Z1raNnSZfkVJlRHvwf3rviBEAPOLVYUDtjx7QskDkDAIam+21WkUNRHcByXQcw== + version "15.0.2" + resolved "https://registry.yarnpkg.com/@adonisjs/lucid/-/lucid-15.0.2.tgz#99051cce48fc1d8061860b9efb09c18d53818a81" + integrity sha512-SLC2YYG33efHeq++qAXe6DA2fkQkgdaQwdBz+tjku7DneRBMre+mltXlf6Mow5WHUfq9b0fxh5GQA9tKGDdWkg== dependencies: "@poppinss/hooks" "^3.0.4" "@poppinss/utils" "^3.1.3" @@ -202,9 +202,10 @@ fast-deep-equal "^3.1.3" igniculus "^1.5.0" knex "^0.95.6" - knex-dynamic-connection "^2.1.0" + knex-dynamic-connection "^2.1.1" luxon "^1.27.0" macroable "^5.1.3" + normalize-path "^3.0.0" pretty-hrtime "^1.0.3" qs "^6.10.1" @@ -514,9 +515,9 @@ "@types/responselike" "*" "@types/debug@^4.1.5": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd" - integrity sha512-Q1y515GcOdTHgagaVFhHnIFQ38ygs/kmxdNpvpou+raI9UO3YZcHDngBSYKQklcKlvA7iuQlmIKbzvmxcOE9CQ== + version "4.1.6" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.6.tgz#0b7018723084918a865eff99249c490505df2163" + integrity sha512-7fDOJFA/x8B+sO1901BmHlf5dE1cxBU8mRXj8QOEDnn16hhGJv/IHxJtZhvsabZsIMn0eLIyeOKAeqSNJJYTpA== "@types/faker@^5.5.6": version "5.5.6" @@ -2651,7 +2652,7 @@ kleur@^4.1.4: resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.4.tgz#8c202987d7e577766d039a8cd461934c01cda04d" integrity sha512-8QADVssbrFjivHWQU7KkMgptGTl6WAcSdlbBPY4uNF+mWr6DGcKrvY2w4FQJoXch7+fKMjj0dRrL75vk3k23OA== -knex-dynamic-connection@^2.1.0: +knex-dynamic-connection@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/knex-dynamic-connection/-/knex-dynamic-connection-2.1.1.tgz#a3c9934a51bf93e2ea6c3da2f9f3dca742f7a123" integrity sha512-/Lwg/T13eNRJVoSJ4e9SH3slVUmg37UHxDxVluAAKdJZxYVj8YsP2x50JSk310RmKsYbOZ8oB8SwVVEuRa4nYw== @@ -4637,9 +4638,9 @@ type-is@^1.6.18: mime-types "~2.1.24" typescript@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.4.tgz#3f85b986945bcf31071decdd96cf8bfa65f9dcbc" - integrity sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew== + version "4.3.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" + integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== uglify-js@^3.5.1: version "3.13.10"