diff --git a/backend/typescript/middlewares/validators/teamMemberValidators.ts b/backend/typescript/middlewares/validators/teamMemberValidators.ts new file mode 100644 index 0000000..ad45391 --- /dev/null +++ b/backend/typescript/middlewares/validators/teamMemberValidators.ts @@ -0,0 +1,21 @@ +import { Request, Response, NextFunction } from "express"; +import { validatePrimitive, getApiValidationError } from "./util"; + +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ +/* eslint-disable-next-line import/prefer-default-export */ +export const createTeamMemberDtoValidator = async ( + req: Request, + res: Response, + next: NextFunction, +) => { + if (!validatePrimitive(req.body.firstName, "string")) { + return res.status(400).send(getApiValidationError("firstName", "string")); + } + if (!validatePrimitive(req.body.lastName, "string")) { + return res.status(400).send(getApiValidationError("lastName", "string")); + } + if (!validatePrimitive(req.body.teamRole, "string")) { + return res.status(400).send(getApiValidationError("role", "string")); + } + return next(); +}; diff --git a/backend/typescript/migrations/2024.10.01T20.44.32.2024.10.01T4.43.30.add-team-members-table.ts b/backend/typescript/migrations/2024.10.01T20.44.32.2024.10.01T4.43.30.add-team-members-table.ts new file mode 100644 index 0000000..1250314 --- /dev/null +++ b/backend/typescript/migrations/2024.10.01T20.44.32.2024.10.01T4.43.30.add-team-members-table.ts @@ -0,0 +1,34 @@ +import { DataType } from "sequelize-typescript"; + +import { Migration } from "../umzug"; +import { teamRoleEnum } from "../types"; + +const TABLE_NAME = "team_members"; + +export const up: Migration = async ({ context: sequelize }) => { + await sequelize.getQueryInterface().createTable(TABLE_NAME, { + id: { + type: DataType.INTEGER, + allowNull: false, + primaryKey: true, + autoIncrement: true, + }, + first_name: { + type: DataType.STRING, + allowNull: false, + }, + last_name: { + type: DataType.STRING, + allowNull: false, + }, + team_role: { + type: DataType.ENUM, + values: teamRoleEnum, + allowNull: false, + }, + }); +}; + +export const down: Migration = async ({ context: sequelize }) => { + await sequelize.getQueryInterface().dropTable(TABLE_NAME); +}; diff --git a/backend/typescript/models/teamMember.model.ts b/backend/typescript/models/teamMember.model.ts new file mode 100644 index 0000000..84e4f7d --- /dev/null +++ b/backend/typescript/models/teamMember.model.ts @@ -0,0 +1,24 @@ +import { + Column, + DataType, + Model, + Table, + AllowNull, +} from "sequelize-typescript"; +import { TeamRole, teamRoleEnum } from "../types"; + +@Table({ timestamps: false, tableName: "team_members" }) +export default class TeamMember extends Model { + @Column({ type: DataType.STRING, allowNull: false }) + first_name!: string; + + @Column({ type: DataType.STRING, allowNull: false }) + last_name!: string; + + @AllowNull(false) + @Column({ + type: DataType.ENUM(...Object.values(teamRoleEnum)), + allowNull: false, + }) + team_role!: TeamRole; +} diff --git a/backend/typescript/package.json b/backend/typescript/package.json index 70318ca..d4cd7c8 100644 --- a/backend/typescript/package.json +++ b/backend/typescript/package.json @@ -39,7 +39,7 @@ "pg": "^8.5.1", "reflect-metadata": "^0.1.13", "sequelize": "^6.5.0", - "sequelize-typescript": "^2.1.0", + "sequelize-typescript": "^2.1.6", "swagger-ui-express": "^4.1.6", "ts-node": "^10.0.0", "umzug": "^3.0.0-beta.16", diff --git a/backend/typescript/rest/teamMemberRoutes.ts b/backend/typescript/rest/teamMemberRoutes.ts new file mode 100644 index 0000000..ef6a809 --- /dev/null +++ b/backend/typescript/rest/teamMemberRoutes.ts @@ -0,0 +1,32 @@ +import { Router } from "express"; +import ITeamMemberService from "../services/interfaces/teamMemberService"; +import TeamMemberService from "../services/implementations/teamMemberService"; +import { CreateTeamMemberDTO, TeamMemberDTO, UserDTO } from "../types"; +import { getErrorMessage } from "../utilities/errorUtils"; +import { createTeamMemberDtoValidator } from "../middlewares/validators/teamMemberValidators"; + +const teamMemberRouter: Router = Router(); + +const teamMemberService: ITeamMemberService = new TeamMemberService(); + +/* Get all team members */ +teamMemberRouter.get("/", async (req, res) => { + try { + const teamMembers = await teamMemberService.getTeamMembers(); + res.status(200).json(teamMembers); + } catch (error: unknown) { + res.status(500).json({ error: getErrorMessage(error) }); + } +}); + +teamMemberRouter.post("/", createTeamMemberDtoValidator, async (req, res) => { + const data: CreateTeamMemberDTO = req.body; + try { + const newTeamMember = await teamMemberService.createTeamMember(data); + res.status(201).json(newTeamMember); + } catch (error: unknown) { + res.status(500).json({ error: getErrorMessage(error) }); + } +}); + +export default teamMemberRouter; diff --git a/backend/typescript/services/implementations/teamMemberService.ts b/backend/typescript/services/implementations/teamMemberService.ts new file mode 100644 index 0000000..f95e63a --- /dev/null +++ b/backend/typescript/services/implementations/teamMemberService.ts @@ -0,0 +1,54 @@ +import PgTeamMember from "../../models/teamMember.model"; +import { CreateTeamMemberDTO, TeamMemberDTO } from "../../types"; +import { getErrorMessage, NotFoundError } from "../../utilities/errorUtils"; +import logger from "../../utilities/logger"; +import ITeamMemberService from "../interfaces/teamMemberService"; + +const Logger = logger(__filename); + +class TeamMemberService implements ITeamMemberService { + /* eslint-disable class-methods-use-this */ + + async getTeamMembers(): Promise { + try { + const teamMembers: Array = await PgTeamMember.findAll(); + return teamMembers.map((teamMember) => ({ + id: String(teamMember.id), + firstName: teamMember.first_name, + lastName: teamMember.last_name, + teamRole: teamMember.team_role, + })); + } catch (error: unknown) { + Logger.error( + `Failed to get team members. Reason = ${getErrorMessage(error)}`, + ); + throw error; + } + } + + async createTeamMember( + teamMember: CreateTeamMemberDTO, + ): Promise { + let newTeamMember: PgTeamMember | null; + try { + newTeamMember = await PgTeamMember.create({ + first_name: teamMember.firstName, + last_name: teamMember.lastName, + team_role: teamMember.teamRole, + }); + } catch (error: unknown) { + Logger.error( + `Failed to create team member. Reason = ${getErrorMessage(error)}`, + ); + throw error; + } + return { + id: String(newTeamMember.id), + firstName: newTeamMember.first_name, + lastName: newTeamMember.last_name, + teamRole: newTeamMember.team_role, + }; + } +} + +export default TeamMemberService; diff --git a/backend/typescript/services/interfaces/teamMemberService.ts b/backend/typescript/services/interfaces/teamMemberService.ts new file mode 100644 index 0000000..f4ba016 --- /dev/null +++ b/backend/typescript/services/interfaces/teamMemberService.ts @@ -0,0 +1,20 @@ +import { CreateTeamMemberDTO, TeamMemberDTO } from "../../types"; + +interface ITeamMemberService { + /** + * Get a list of all the team members in the database + * @returns a TeamMemberDTO with a team member's information + * @throws Error if team member retrieval fails + */ + getTeamMembers(): Promise; + + /** + * Create a team member + * @param teamMember the team member to be created + * @returns a TeamMemberDTO with the created team member's information + * @throws Error if team member creation fails + */ + createTeamMember(teamMember: CreateTeamMemberDTO): Promise; +} + +export default ITeamMemberService; diff --git a/backend/typescript/types.ts b/backend/typescript/types.ts index daf6250..f21ebfe 100644 --- a/backend/typescript/types.ts +++ b/backend/typescript/types.ts @@ -23,8 +23,17 @@ export type UserDTO = { phoneNumber?: string | null; }; +export type TeamMemberDTO = { + id: string; + firstName: string; + lastName: string; + teamRole: TeamRole; +}; + export type CreateUserDTO = Omit & { password: string }; +export type CreateTeamMemberDTO = Omit; + export type UpdateUserDTO = Omit; export type RegisterUserDTO = Omit; @@ -33,6 +42,12 @@ export type AuthDTO = Token & UserDTO; export type Letters = "A" | "B" | "C" | "D"; +const teamRoleValues = ["PM", "DESIGNER", "PL", "DEVELOPER"] as const; + +export const teamRoleEnum: TeamRole[] = [...teamRoleValues]; + +export type TeamRole = typeof teamRoleValues[number]; + const sexValues = ["M", "F"] as const; export const sexEnum: Sex[] = [...sexValues]; diff --git a/backend/typescript/yarn.lock b/backend/typescript/yarn.lock index 7d1027c..86aad5c 100644 --- a/backend/typescript/yarn.lock +++ b/backend/typescript/yarn.lock @@ -561,15 +561,6 @@ camel-case "4.1.2" tslib "~2.1.0" -"@graphql-tools/utils@^7.6.0": - version "7.10.0" - resolved "https://registry.yarnpkg.com/@graphql-tools/utils/-/utils-7.10.0.tgz#07a4cb5d1bec1ff1dc1d47a935919ee6abd38699" - integrity sha512-d334r6bo9mxdSqZW6zWboEnnOOFRrAPVQJ7LkU8/6grglrbcu6WhwCLzHb90E94JI3TD3ricC3YGbUqIi9Xg0w== - dependencies: - "@ardatan/aggregate-error" "0.0.6" - camel-case "4.1.2" - tslib "~2.2.0" - "@grpc/grpc-js@~1.2.0": version "1.2.10" resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.2.10.tgz#f316d29a45fcc324e923d593cb849d292b1ed598" @@ -3416,10 +3407,10 @@ glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@~5.1.0: dependencies: is-glob "^4.0.1" -glob@7.1.6, glob@^7.1.3: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== +glob@7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -3440,6 +3431,18 @@ glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.4, glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.1.3: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + global-dirs@^2.0.1: version "2.1.0" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.1.0.tgz#e9046a49c806ff04d6c1825e196c8f0091e8df4d" @@ -3569,25 +3572,6 @@ graphql-middleware@^6.0.6: "@graphql-tools/delegate" "^7.1.1" "@graphql-tools/schema" "^7.1.3" -graphql-rate-limit@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/graphql-rate-limit/-/graphql-rate-limit-3.3.0.tgz#241e3f6dc4cc3cbd139d63d40e2ce613f8485646" - integrity sha512-mbbEv5z3SjkDLvVVdHi0XrVLavw2Mwo93GIqgQB/fx8dhcNSEv3eYI1OGdp8mhsm/MsZm7hjrRlwQMVRKBVxhA== - dependencies: - "@graphql-tools/utils" "^7.6.0" - graphql-shield "^7.5.0" - lodash.get "^4.4.2" - ms "^2.1.3" - -graphql-shield@^7.5.0: - version "7.5.0" - resolved "https://registry.yarnpkg.com/graphql-shield/-/graphql-shield-7.5.0.tgz#aa3af226946946dfadac33eccc6cbe7fec6e9000" - integrity sha512-T1A6OreOe/dHDk/1Qg3AHCrKLmTkDJ3fPFGYpSOmUbYXyDnjubK4J5ab5FjHdKHK5fWQRZNTvA0SrBObYsyfaw== - dependencies: - "@types/yup" "0.29.11" - object-hash "^2.0.3" - yup "^0.31.0" - graphql-subscriptions@^1.0.0: version "1.2.1" resolved "https://registry.yarnpkg.com/graphql-subscriptions/-/graphql-subscriptions-1.2.1.tgz#2142b2d729661ddf967b7388f7cf1dd4cf2e061d" @@ -6008,12 +5992,12 @@ sequelize-pool@^6.0.0: resolved "https://registry.yarnpkg.com/sequelize-pool/-/sequelize-pool-6.1.0.tgz#caaa0c1e324d3c2c3a399fed2c7998970925d668" integrity sha512-4YwEw3ZgK/tY/so+GfnSgXkdwIJJ1I32uZJztIEgZeAO6HMgj64OzySbWLgxj+tXhZCJnzRfkY9gINw8Ft8ZMg== -sequelize-typescript@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/sequelize-typescript/-/sequelize-typescript-2.1.0.tgz#7d42dac368f32829a736acc4f0c9f3b79fc089bb" - integrity sha512-wwPxydBQ/wIZ92pFxDQEAhW8uRHqwFZGm6JkPmpsCjrODWrH8TANZiOCjwGouygFMgBwCNK91RNwLe5TYoy5pg== +sequelize-typescript@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/sequelize-typescript/-/sequelize-typescript-2.1.6.tgz#9476c8a2510114ed1c3a26b424c47e05c2e6284e" + integrity sha512-Vc2N++3en346RsbGjL3h7tgAl2Y7V+2liYTAOZ8XL0KTw3ahFHsyAUzOwct51n+g70I1TOUDgs06Oh6+XGcFkQ== dependencies: - glob "7.1.6" + glob "7.2.0" sequelize@^6.5.0: version "6.5.0" diff --git a/frontend/src/APIClients/TeamMembersAPIClient.ts b/frontend/src/APIClients/TeamMembersAPIClient.ts new file mode 100644 index 0000000..0f03cae --- /dev/null +++ b/frontend/src/APIClients/TeamMembersAPIClient.ts @@ -0,0 +1,30 @@ +import { TeamMember, TeamRole } from "../types/TeamMemberTypes"; +import baseAPIClient from "./BaseAPIClient"; + +const get = async (): Promise => { + try { + const { data } = await baseAPIClient.get("team-members/"); + return data; + } catch (error) { + throw new Error(`Failed to get team members: ${error}`); + } +}; + +const create = async ( + firstName: string, + lastName: string, + teamRole: TeamRole, +): Promise => { + try { + const { data } = await baseAPIClient.post("team-members/", { + firstName, + lastName, + teamRole, + }); + return data; + } catch (error: unknown) { + return null; + } +}; + +export default { get, create }; diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 33c2e01..01a584f 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -28,6 +28,7 @@ import EditTeamInfoPage from "./components/pages/EditTeamPage"; import HooksDemo from "./components/pages/HooksDemo"; import { AuthenticatedUser } from "./types/AuthTypes"; +import TeamMembersPage from "./components/pages/TeamMembersPage"; const App = (): React.ReactElement => { const currentUser: AuthenticatedUser = getLocalStorageObj( @@ -117,6 +118,12 @@ const App = (): React.ReactElement => { component={Default} allowedRoles={AuthConstants.ALL_ROLES} /> + diff --git a/frontend/src/components/pages/TeamMembersPage.tsx b/frontend/src/components/pages/TeamMembersPage.tsx new file mode 100644 index 0000000..2c94301 --- /dev/null +++ b/frontend/src/components/pages/TeamMembersPage.tsx @@ -0,0 +1,71 @@ +import React, { useEffect, useState } from "react"; +import { + VStack, + TableContainer, + Thead, + Tr, + Th, + Tbody, + Td, + Table, + Button, +} from "@chakra-ui/react"; +import TeamMembersAPIClient from "../../APIClients/TeamMembersAPIClient"; +import { TeamMember } from "../../types/TeamMemberTypes"; + +const TeamMembersPage = () => { + const [teamMembers, setTeamMembers] = useState([]); + + const getTeamMembers = async () => { + const teamMembersData = await TeamMembersAPIClient.get(); + if (teamMembersData) { + setTeamMembers(teamMembersData); + } + }; + + const addTeamMember = async () => { + const addedTeamMember = await TeamMembersAPIClient.create( + "Vipasha", + "Gupta", + "DEVELOPER", + ); + if (addedTeamMember) { + getTeamMembers(); + } + }; + + useEffect(() => { + getTeamMembers(); + }, []); + + return ( + +

Team Members Page

+ + + + + + + + + + + {teamMembers.map((teamMember, index) => ( + + + + + + ))} + +
First NameLast NameTeam Role
{teamMember.firstName}{teamMember.lastName}{teamMember.teamRole}
+
+ +
+ ); +}; + +export default TeamMembersPage; diff --git a/frontend/src/constants/Routes.ts b/frontend/src/constants/Routes.ts index 1358c79..6c06dce 100644 --- a/frontend/src/constants/Routes.ts +++ b/frontend/src/constants/Routes.ts @@ -20,4 +20,6 @@ export const UPDATE_SIMPLE_ENTITY_PAGE = "/simpleEntity/update"; export const HOOKS_PAGE = "/hooks"; +export const TEAM_MEMBERS_PAGE = "/team-members"; + export const DEV_UTILITY_PAGE = "/dev-utility"; // TODO: This is only here for development purposes diff --git a/frontend/src/types/TeamMemberTypes.ts b/frontend/src/types/TeamMemberTypes.ts new file mode 100644 index 0000000..3e7faa7 --- /dev/null +++ b/frontend/src/types/TeamMemberTypes.ts @@ -0,0 +1,8 @@ +export type TeamRole = "PM" | "DESIGNER" | "PL" | "DEVELOPER"; + +export type TeamMember = { + id: string; + firstName: string; + lastName: string; + teamRole: TeamRole; +}; diff --git a/frontend/yarn.lock b/frontend/yarn.lock index cef78bb..e305cf2 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2346,7 +2346,12 @@ dependencies: eslint-visitor-keys "^3.3.0" -"@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": +"@eslint-community/regexpp@^4.10.0": + version "4.11.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.1.tgz#a547badfc719eb3e5f4b556325e542fbe9d7a18f" + integrity sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q== + +"@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.6.1": version "4.10.0" resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== @@ -3249,7 +3254,7 @@ jest-diff "^26.0.0" pretty-format "^26.0.0" -"@types/json-schema@*", "@types/json-schema@^7.0.12", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -3412,7 +3417,7 @@ resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== -"@types/semver@^7.3.12", "@types/semver@^7.5.0": +"@types/semver@^7.3.12": version "7.5.8" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== @@ -3520,21 +3525,19 @@ tsutils "^3.21.0" "@typescript-eslint/eslint-plugin@^7.0.2": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.5.0.tgz#1dc52fe48454d5b54be2d5f089680452f1628a5a" - integrity sha512-HpqNTH8Du34nLxbKgVMGljZMG0rJd2O9ecvr2QLYp+7512ty1j42KnsFwspPXg1Vh8an9YImf6CokUBltisZFQ== - dependencies: - "@eslint-community/regexpp" "^4.5.1" - "@typescript-eslint/scope-manager" "7.5.0" - "@typescript-eslint/type-utils" "7.5.0" - "@typescript-eslint/utils" "7.5.0" - "@typescript-eslint/visitor-keys" "7.5.0" - debug "^4.3.4" + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz#b16d3cf3ee76bf572fdf511e79c248bdec619ea3" + integrity sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw== + dependencies: + "@eslint-community/regexpp" "^4.10.0" + "@typescript-eslint/scope-manager" "7.18.0" + "@typescript-eslint/type-utils" "7.18.0" + "@typescript-eslint/utils" "7.18.0" + "@typescript-eslint/visitor-keys" "7.18.0" graphemer "^1.4.0" - ignore "^5.2.4" + ignore "^5.3.1" natural-compare "^1.4.0" - semver "^7.5.4" - ts-api-utils "^1.0.1" + ts-api-utils "^1.3.0" "@typescript-eslint/experimental-utils@^5.0.0": version "5.62.0" @@ -3590,6 +3593,14 @@ "@typescript-eslint/types" "5.62.0" "@typescript-eslint/visitor-keys" "5.62.0" +"@typescript-eslint/scope-manager@7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz#c928e7a9fc2c0b3ed92ab3112c614d6bd9951c83" + integrity sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA== + dependencies: + "@typescript-eslint/types" "7.18.0" + "@typescript-eslint/visitor-keys" "7.18.0" + "@typescript-eslint/scope-manager@7.5.0": version "7.5.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.5.0.tgz#70f0a7361430ab1043a5f97386da2a0d8b2f4d56" @@ -3608,15 +3619,15 @@ debug "^4.3.4" tsutils "^3.21.0" -"@typescript-eslint/type-utils@7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.5.0.tgz#a8faa403232da3a3901655387c7082111f692cf9" - integrity sha512-A021Rj33+G8mx2Dqh0nMO9GyjjIBK3MqgVgZ2qlKf6CJy51wY/lkkFqq3TqqnH34XyAHUkq27IjlUkWlQRpLHw== +"@typescript-eslint/type-utils@7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz#2165ffaee00b1fbbdd2d40aa85232dab6998f53b" + integrity sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA== dependencies: - "@typescript-eslint/typescript-estree" "7.5.0" - "@typescript-eslint/utils" "7.5.0" + "@typescript-eslint/typescript-estree" "7.18.0" + "@typescript-eslint/utils" "7.18.0" debug "^4.3.4" - ts-api-utils "^1.0.1" + ts-api-utils "^1.3.0" "@typescript-eslint/types@4.33.0": version "4.33.0" @@ -3628,6 +3639,11 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== +"@typescript-eslint/types@7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.18.0.tgz#b90a57ccdea71797ffffa0321e744f379ec838c9" + integrity sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ== + "@typescript-eslint/types@7.5.0": version "7.5.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.5.0.tgz#0a284bcdef3cb850ec9fd57992df9f29d6bde1bc" @@ -3659,6 +3675,20 @@ semver "^7.3.7" tsutils "^3.21.0" +"@typescript-eslint/typescript-estree@7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz#b5868d486c51ce8f312309ba79bdb9f331b37931" + integrity sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA== + dependencies: + "@typescript-eslint/types" "7.18.0" + "@typescript-eslint/visitor-keys" "7.18.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + minimatch "^9.0.4" + semver "^7.6.0" + ts-api-utils "^1.3.0" + "@typescript-eslint/typescript-estree@7.5.0", "@typescript-eslint/typescript-estree@^7.0.2": version "7.5.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.5.0.tgz#aa5031c511874420f6b5edd90f8e4021525ee776" @@ -3687,18 +3717,15 @@ eslint-scope "^5.1.1" semver "^7.3.7" -"@typescript-eslint/utils@7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.5.0.tgz#bbd963647fbbe9ffea033f42c0fb7e89bb19c858" - integrity sha512-3vZl9u0R+/FLQcpy2EHyRGNqAS/ofJ3Ji8aebilfJe+fobK8+LbIFmrHciLVDxjDoONmufDcnVSF38KwMEOjzw== +"@typescript-eslint/utils@7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.18.0.tgz#bca01cde77f95fc6a8d5b0dbcbfb3d6ca4be451f" + integrity sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw== dependencies: "@eslint-community/eslint-utils" "^4.4.0" - "@types/json-schema" "^7.0.12" - "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "7.5.0" - "@typescript-eslint/types" "7.5.0" - "@typescript-eslint/typescript-estree" "7.5.0" - semver "^7.5.4" + "@typescript-eslint/scope-manager" "7.18.0" + "@typescript-eslint/types" "7.18.0" + "@typescript-eslint/typescript-estree" "7.18.0" "@typescript-eslint/visitor-keys@4.33.0": version "4.33.0" @@ -3716,6 +3743,14 @@ "@typescript-eslint/types" "5.62.0" eslint-visitor-keys "^3.3.0" +"@typescript-eslint/visitor-keys@7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz#0564629b6124d67607378d0f0332a0495b25e7d7" + integrity sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg== + dependencies: + "@typescript-eslint/types" "7.18.0" + eslint-visitor-keys "^3.4.3" + "@typescript-eslint/visitor-keys@7.5.0": version "7.5.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.5.0.tgz#8abcac66f93ef20b093e87a400c2d21e3a6d55ee" @@ -6885,11 +6920,16 @@ identity-obj-proxy@^3.0.0: dependencies: harmony-reflect "^1.4.6" -ignore@^5.2.0, ignore@^5.2.4: +ignore@^5.2.0: version "5.3.1" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== +ignore@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" + integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== + immer@^9.0.7: version "9.0.21" resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176" @@ -8386,6 +8426,13 @@ minimatch@^9.0.1: dependencies: brace-expansion "^2.0.1" +minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + minimist@^1.2.0, minimist@^1.2.6: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" @@ -10350,6 +10397,11 @@ semver@^7.3.2, semver@^7.3.5, semver@^7.3.7, semver@^7.5.3, semver@^7.5.4: dependencies: lru-cache "^6.0.0" +semver@^7.6.0: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + send@0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" @@ -11090,7 +11142,7 @@ tryer@^1.0.1: resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== -ts-api-utils@^1.0.1: +ts-api-utils@^1.0.1, ts-api-utils@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==