From 351ff4e9892d5ed9f53f1b1b5eaf0e52ee87ce64 Mon Sep 17 00:00:00 2001 From: Sugui Date: Mon, 25 Dec 2023 14:36:13 +0100 Subject: [PATCH 001/133] Test workflow --- .gitea/workflows/test.yaml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .gitea/workflows/test.yaml diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml new file mode 100644 index 0000000..43c3b96 --- /dev/null +++ b/.gitea/workflows/test.yaml @@ -0,0 +1,18 @@ +name: Gitea Actions Demo +run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀 +on: [push] + +jobs: + Explore-Gitea-Actions: + runs-on: ubuntu-latest + steps: + - run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event." + - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!" + - run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}." + - name: Check out repository code + uses: actions/checkout@v3 + - run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner." + - run: echo "🖥️ The workflow is now ready to test your code on the runner." + - name: List files in the repository + run: | + ls ${{ gitea.workspace }} \ No newline at end of file From f483f62c4203609c63a2bf5ab2660a15807158dc Mon Sep 17 00:00:00 2001 From: Sugui Date: Mon, 25 Dec 2023 14:40:10 +0100 Subject: [PATCH 002/133] change test workflow on pull request --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 43c3b96..32b6117 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -1,6 +1,6 @@ name: Gitea Actions Demo run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀 -on: [push] +on: [pull_request] jobs: Explore-Gitea-Actions: From c5e41d6f62eb23333572f338d6798392ef120fee Mon Sep 17 00:00:00 2001 From: Alie Date: Wed, 27 Dec 2023 16:52:15 +0100 Subject: [PATCH 003/133] added a test for / --- src/index.ts | 81 ++++++++++++++++++++++++----------------------- tests/app.test.ts | 12 +++++-- 2 files changed, 51 insertions(+), 42 deletions(-) diff --git a/src/index.ts b/src/index.ts index 627eaa3..9264b60 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,55 +7,56 @@ export const app = express(); app.use(express.json()); app.get("/", (_, res) => { - res.json({ message: "Blazing fast 🚀" }); + res.json({ message: "Blazing fast 🚀" }); }); -app.get("/images", async (req, res) => { - try { - const allImages = await ImageModel.find(); - res.json(allImages); - } catch (error) { - res.status(500).json({ message: error }); - } -}) +app.get("/images", async (_, res) => { + try { + const allImages = await ImageModel.find(); + res.json({ message: allImages }); + } catch (error) { + res.status(500).json({ message: error }); + } +}); app.post("/images", async (req, res) => { - try { - // Should add auth here before doing stuff - // Thowing a 401 if not auth provided - // Throwing a 403 for incorrect auth - const image = await ImageModel.create(req.body); - res.status(201).json(image); - } catch (error: any) { - if (error.code == 11000){ - // Should return 409 Conflict for existing urls - res.status(409).json({ message: "Existing URL" }); - } - // Should return 400 Bad request for invalid requests - res.status(400).json({ message: error }); + try { + // Should add auth here before doing stuff + // Thowing a 401 if not auth provided + // Throwing a 403 for incorrect auth + const image = await ImageModel.create(req.body); + res.status(201).json({ message: image }); + } catch (error: any) { + if (error.code == 11000) { + // Should return 409 Conflict for existing urls + res.status(409).json({ message: "Existing URL" }); } -}) + // Should return 400 Bad request for invalid requests + res.status(400).json({ message: error }); + } +}); // Set the default port to 8080, or use the PORT environment variable const start = async () => { - const port = process.env.PORT || 8080; - const mongo_uri: string = process.env.MONGODB_URI || ""; - const mongo_user = process.env.MONGODB_USER; - const mongo_pass = process.env.MONGODB_PASS; + const port = process.env.PORT || 8080; + const mongo_uri: string = process.env.MONGODB_URI || ""; + const mongo_user = process.env.MONGODB_USER; + const mongo_pass = process.env.MONGODB_PASS; - try { - await mongoose.connect(mongo_uri, { - authSource: "admin", - user: mongo_user, - pass: mongo_pass - }); - app.listen(port, () => console.log(`Express server listening on port ${port}`)); - } catch (error) { - console.error(error); - process.exit(1); - } -} + try { + await mongoose.connect(mongo_uri, { + authSource: "admin", + user: mongo_user, + pass: mongo_pass, + }); + app.listen(port, () => + console.log(`Express server listening on port ${port}`) + ); + } catch (error) { + console.error(error); + process.exit(1); + } +}; start(); - diff --git a/tests/app.test.ts b/tests/app.test.ts index a375b81..59a1810 100644 --- a/tests/app.test.ts +++ b/tests/app.test.ts @@ -1,12 +1,20 @@ -import { beforeAll, describe, expect, it } from "bun:test"; +import { describe, expect, it, mock } from "bun:test"; import request from "supertest"; import { app } from "../src"; +describe("GET / shows what it should",async () => { + const res = await request(app).get("/"); + + it("should be", async () => { + expect(res.body).toHaveProperty("message", "Blazing fast 🚀"); + }); +}) + describe("GET /images works properly", async () => { const res = await request(app).get("/images"); it("should be an array", async () => { - expect(Array.isArray(res.body)).toBeTrue(); + expect(Array.isArray(res.body.message)).toBeTrue(); }); it("should return a 200", async () => { From bf7961f1ca962fa81f5345107112270788d48639 Mon Sep 17 00:00:00 2001 From: Sugui Date: Wed, 27 Dec 2023 17:07:32 +0100 Subject: [PATCH 004/133] Now / lists the endpoints --- package.json | 2 ++ src/index.ts | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index acb29be..299b1a8 100644 --- a/package.json +++ b/package.json @@ -21,8 +21,10 @@ }, "dependencies": { "@types/express": "^4.17.21", + "@types/express-list-endpoints": "^6.0.3", "@types/mongoose": "^5.11.97", "express": "^4.18.2", + "express-list-endpoints": "^6.0.0", "mongoose": "^8.0.3" } } \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 9264b60..9fbb393 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,13 +1,15 @@ import express from "express"; import mongoose from "mongoose"; import ImageModel from "./ImageModel"; +import listEndpoints from "express-list-endpoints"; export const app = express(); app.use(express.json()); app.get("/", (_, res) => { - res.json({ message: "Blazing fast 🚀" }); + const endpoints = listEndpoints(app); + res.json({ endpoints }); }); app.get("/images", async (_, res) => { From e89bc6d508c7f82b9e8a7e9a629c7ee5edb8c119 Mon Sep 17 00:00:00 2001 From: Sugui Date: Wed, 27 Dec 2023 17:58:59 +0100 Subject: [PATCH 005/133] Separated things into Model-Service-Controller pattern --- src/controllers/ImageController.ts | 33 ++++++++++++++++++++++++++++++ src/index.ts | 31 ++++------------------------ src/{ => models}/ImageModel.ts | 10 +++++++-- src/services/ImageService.ts | 14 +++++++++++++ tests/app.test.ts | 10 ++++++--- 5 files changed, 66 insertions(+), 32 deletions(-) create mode 100644 src/controllers/ImageController.ts rename src/{ => models}/ImageModel.ts (55%) create mode 100644 src/services/ImageService.ts diff --git a/src/controllers/ImageController.ts b/src/controllers/ImageController.ts new file mode 100644 index 0000000..1b24a08 --- /dev/null +++ b/src/controllers/ImageController.ts @@ -0,0 +1,33 @@ +import { Request, Response } from "express"; +import imageService from "../services/ImageService"; + +class ImageController { + async getAllImages(req: Request, res: Response): Promise { + try { + const images = await imageService.findAll(); + res.json({ message: images }); + } catch (error) { + console.error(error); + res.status(500).json({ message: "Internal Server Error" }); + } + } + + async addImage(req: Request, res: Response): Promise { + try { + // Should add auth here before doing stuff + // Thowing a 401 if not auth provided + // Throwing a 403 for incorrect auth + const image = await imageService.add(req.body); + res.status(201).json({ message: image }); + } catch (error: any) { + if (error.code === 11000) { + // Should return 409 Conflict for existing urls + res.status(409).json({ message: "Existing URL" }); + } + // Should return 400 Bad request for invalid requests + res.status(400).json({ message: error }); + } + } +} + +export default new ImageController(); \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 9fbb393..8113fb9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ import express from "express"; import mongoose from "mongoose"; -import ImageModel from "./ImageModel"; import listEndpoints from "express-list-endpoints"; +import imageController from "./controllers/ImageController"; export const app = express(); @@ -9,34 +9,11 @@ app.use(express.json()); app.get("/", (_, res) => { const endpoints = listEndpoints(app); - res.json({ endpoints }); + res.json({ message: endpoints }); }); -app.get("/images", async (_, res) => { - try { - const allImages = await ImageModel.find(); - res.json({ message: allImages }); - } catch (error) { - res.status(500).json({ message: error }); - } -}); - -app.post("/images", async (req, res) => { - try { - // Should add auth here before doing stuff - // Thowing a 401 if not auth provided - // Throwing a 403 for incorrect auth - const image = await ImageModel.create(req.body); - res.status(201).json({ message: image }); - } catch (error: any) { - if (error.code == 11000) { - // Should return 409 Conflict for existing urls - res.status(409).json({ message: "Existing URL" }); - } - // Should return 400 Bad request for invalid requests - res.status(400).json({ message: error }); - } -}); +app.get("/images", imageController.getAllImages); +app.post("/images", imageController.addImage); // Set the default port to 8080, or use the PORT environment variable diff --git a/src/ImageModel.ts b/src/models/ImageModel.ts similarity index 55% rename from src/ImageModel.ts rename to src/models/ImageModel.ts index 0a74f50..5ef3b70 100644 --- a/src/ImageModel.ts +++ b/src/models/ImageModel.ts @@ -1,4 +1,10 @@ -import mongoose from "mongoose"; +import mongoose, { Document } from "mongoose"; + +export interface Image extends Document { + url: String; + enum: "consumed" | "unavailable" | "available"; + tags?: String[]; +} const ImageSchema = new mongoose.Schema({ url: { @@ -17,4 +23,4 @@ const ImageSchema = new mongoose.Schema({ } }); -export default mongoose.model('images', ImageSchema); +export default mongoose.model('images', ImageSchema); diff --git a/src/services/ImageService.ts b/src/services/ImageService.ts new file mode 100644 index 0000000..c8a3c16 --- /dev/null +++ b/src/services/ImageService.ts @@ -0,0 +1,14 @@ +import ImageModel, { Image } from "../models/ImageModel"; + +class ImageService { + async findAll(): Promise { + const allImages = await ImageModel.find(); + return allImages; + } + async add(image: Image): Promise { + const newImage = await ImageModel.create(image); + return newImage; + } +} + +export default new ImageService(); \ No newline at end of file diff --git a/tests/app.test.ts b/tests/app.test.ts index 59a1810..895542c 100644 --- a/tests/app.test.ts +++ b/tests/app.test.ts @@ -2,18 +2,22 @@ import { describe, expect, it, mock } from "bun:test"; import request from "supertest"; import { app } from "../src"; -describe("GET / shows what it should",async () => { +describe("GET / shows all of the endpoints", async () => { const res = await request(app).get("/"); it("should be", async () => { - expect(res.body).toHaveProperty("message", "Blazing fast 🚀"); + expect(res.body).toHaveProperty("message"); }); + + it("should be an array", () => { + expect(Array.isArray(res.body.message)).toBeTrue(); + }) }) describe("GET /images works properly", async () => { const res = await request(app).get("/images"); - it("should be an array", async () => { + it("should be an array", () => { expect(Array.isArray(res.body.message)).toBeTrue(); }); From 730b8368cd8e5dd78697c523aec05158dded2a50 Mon Sep 17 00:00:00 2001 From: Sugui Date: Wed, 27 Dec 2023 18:16:46 +0100 Subject: [PATCH 006/133] Deleted "message" attribute that was on all JSON responses --- src/controllers/ImageController.ts | 10 +++++----- src/index.ts | 2 +- tests/app.test.ts | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/controllers/ImageController.ts b/src/controllers/ImageController.ts index 1b24a08..58c2a92 100644 --- a/src/controllers/ImageController.ts +++ b/src/controllers/ImageController.ts @@ -5,10 +5,10 @@ class ImageController { async getAllImages(req: Request, res: Response): Promise { try { const images = await imageService.findAll(); - res.json({ message: images }); + res.json({ images }); } catch (error) { console.error(error); - res.status(500).json({ message: "Internal Server Error" }); + res.status(500).json({ error: "Internal Server Error" }); } } @@ -18,14 +18,14 @@ class ImageController { // Thowing a 401 if not auth provided // Throwing a 403 for incorrect auth const image = await imageService.add(req.body); - res.status(201).json({ message: image }); + res.status(201).json({ image }); } catch (error: any) { if (error.code === 11000) { // Should return 409 Conflict for existing urls - res.status(409).json({ message: "Existing URL" }); + res.status(409).json({ error: "Existing URL" }); } // Should return 400 Bad request for invalid requests - res.status(400).json({ message: error }); + res.status(400).json({ error: error }); } } } diff --git a/src/index.ts b/src/index.ts index 8113fb9..9dff064 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,7 +9,7 @@ app.use(express.json()); app.get("/", (_, res) => { const endpoints = listEndpoints(app); - res.json({ message: endpoints }); + res.json({ endpoints }); }); app.get("/images", imageController.getAllImages); diff --git a/tests/app.test.ts b/tests/app.test.ts index 895542c..f8ec9f4 100644 --- a/tests/app.test.ts +++ b/tests/app.test.ts @@ -6,11 +6,11 @@ describe("GET / shows all of the endpoints", async () => { const res = await request(app).get("/"); it("should be", async () => { - expect(res.body).toHaveProperty("message"); + expect(res.body).toHaveProperty("endpoints"); }); it("should be an array", () => { - expect(Array.isArray(res.body.message)).toBeTrue(); + expect(Array.isArray(res.body.endpoints)).toBeTrue(); }) }) @@ -18,7 +18,7 @@ describe("GET /images works properly", async () => { const res = await request(app).get("/images"); it("should be an array", () => { - expect(Array.isArray(res.body.message)).toBeTrue(); + expect(Array.isArray(res.body.images)).toBeTrue(); }); it("should return a 200", async () => { From d8bb908b03c82348a12f689d48b95c7276defc1f Mon Sep 17 00:00:00 2001 From: Alie Date: Wed, 27 Dec 2023 18:19:46 +0100 Subject: [PATCH 007/133] added basic auth controler --- package.json | 2 ++ src/controllers/AuthControler.ts | 52 ++++++++++++++++++++++++++++++++ src/models/AppModel.ts | 19 ++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 src/controllers/AuthControler.ts create mode 100644 src/models/AppModel.ts diff --git a/package.json b/package.json index 299b1a8..7a8021d 100644 --- a/package.json +++ b/package.json @@ -22,9 +22,11 @@ "dependencies": { "@types/express": "^4.17.21", "@types/express-list-endpoints": "^6.0.3", + "@types/jsonwebtoken": "^9.0.5", "@types/mongoose": "^5.11.97", "express": "^4.18.2", "express-list-endpoints": "^6.0.0", + "jsonwebtoken": "^9.0.2", "mongoose": "^8.0.3" } } \ No newline at end of file diff --git a/src/controllers/AuthControler.ts b/src/controllers/AuthControler.ts new file mode 100644 index 0000000..5d0e43e --- /dev/null +++ b/src/controllers/AuthControler.ts @@ -0,0 +1,52 @@ +import jwt from "jsonwebtoken"; +import AppModel from "../models/AppModel"; +import { Request, Response, NextFunction } from "express"; + +const authTokenSecret = process.env.JWTSECRET || "badsecret"; + +class AuthControler { + async login(req: Request, res: Response) { + // Read app and secret from request body + const { app, secret } = req.body; + + // Filter app from the apps by app and secret + const authenticated = await AppModel.findOne(app, secret); + + if (authenticated) { + console.log("Authenticated app ", authenticated.app); + // Generate an access token + const accessToken = jwt.sign({ app: authenticated.app }, authTokenSecret); + + res.json({ + accessToken, + }); + } else { + res.status(403).send("Credentials incorrect"); + } + } + + authorize(req: Request, res: Response, next: NextFunction) { + const authHeader = req.headers.authorization; + if (authHeader) { + const token = authHeader.split(" ")[1]; + + jwt.verify(token, authTokenSecret, (err, user) => { + if (err) { + return res.status(403).json("Invalid token provided"); + } + + console.log( + "Authorization provided for ", + next.name, + " to user ", + user + ); + next(); + }); + } else { + res.status(401).json("No Authorization header provided"); + } + } +} + +export default new AuthControler(); diff --git a/src/models/AppModel.ts b/src/models/AppModel.ts new file mode 100644 index 0000000..9ef6535 --- /dev/null +++ b/src/models/AppModel.ts @@ -0,0 +1,19 @@ +import mongoose, { Document } from "mongoose"; + +export interface App extends Document { + app: String, + secret: String +} + +const AppSchema = new mongoose.Schema({ + app: { + type: String, + required: true, + }, + secret: { + type: String, + required: true, + }, +}); + +export default mongoose.model("apps", AppSchema); From 95fd50a638d14c642b6e500e1b41d79dbaa4436a Mon Sep 17 00:00:00 2001 From: Alie Date: Wed, 27 Dec 2023 18:29:20 +0100 Subject: [PATCH 008/133] added auth service --- src/controllers/AuthControler.ts | 4 ++-- src/models/{AppModel.ts => AuthModel.ts} | 6 +++--- src/services/AuthService.ts | 9 +++++++++ 3 files changed, 14 insertions(+), 5 deletions(-) rename src/models/{AppModel.ts => AuthModel.ts} (59%) create mode 100644 src/services/AuthService.ts diff --git a/src/controllers/AuthControler.ts b/src/controllers/AuthControler.ts index 5d0e43e..0d0e95d 100644 --- a/src/controllers/AuthControler.ts +++ b/src/controllers/AuthControler.ts @@ -1,5 +1,5 @@ import jwt from "jsonwebtoken"; -import AppModel from "../models/AppModel"; +import AuthService from "../services/AuthService"; import { Request, Response, NextFunction } from "express"; const authTokenSecret = process.env.JWTSECRET || "badsecret"; @@ -10,7 +10,7 @@ class AuthControler { const { app, secret } = req.body; // Filter app from the apps by app and secret - const authenticated = await AppModel.findOne(app, secret); + const authenticated = await AuthService.find(app, secret); if (authenticated) { console.log("Authenticated app ", authenticated.app); diff --git a/src/models/AppModel.ts b/src/models/AuthModel.ts similarity index 59% rename from src/models/AppModel.ts rename to src/models/AuthModel.ts index 9ef6535..52dc172 100644 --- a/src/models/AppModel.ts +++ b/src/models/AuthModel.ts @@ -1,11 +1,11 @@ import mongoose, { Document } from "mongoose"; -export interface App extends Document { +export interface Auth extends Document { app: String, secret: String } -const AppSchema = new mongoose.Schema({ +const AuthSchema = new mongoose.Schema({ app: { type: String, required: true, @@ -16,4 +16,4 @@ const AppSchema = new mongoose.Schema({ }, }); -export default mongoose.model("apps", AppSchema); +export default mongoose.model("auth", AuthSchema); diff --git a/src/services/AuthService.ts b/src/services/AuthService.ts new file mode 100644 index 0000000..1b4bb62 --- /dev/null +++ b/src/services/AuthService.ts @@ -0,0 +1,9 @@ +import AuthModel, { Auth } from "../models/AuthModel"; + +class AuthService { + async find(app: String, secret: String): Promise { + return await AuthModel.findOne(app, secret); + } +} + +export default new AuthService(); From c428e956bc943f609273766b7ef1f8a0aed2c01c Mon Sep 17 00:00:00 2001 From: Alie Date: Wed, 27 Dec 2023 18:44:09 +0100 Subject: [PATCH 009/133] added expiry times to jwt decided against adding refresh tokens due to they not being that usefull in our architecture --- src/controllers/AuthControler.ts | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/controllers/AuthControler.ts b/src/controllers/AuthControler.ts index 0d0e95d..e983020 100644 --- a/src/controllers/AuthControler.ts +++ b/src/controllers/AuthControler.ts @@ -2,9 +2,9 @@ import jwt from "jsonwebtoken"; import AuthService from "../services/AuthService"; import { Request, Response, NextFunction } from "express"; -const authTokenSecret = process.env.JWTSECRET || "badsecret"; - class AuthControler { + authTokenSecret = process.env.JWTSECRET || "badsecret"; + async login(req: Request, res: Response) { // Read app and secret from request body const { app, secret } = req.body; @@ -15,7 +15,11 @@ class AuthControler { if (authenticated) { console.log("Authenticated app ", authenticated.app); // Generate an access token - const accessToken = jwt.sign({ app: authenticated.app }, authTokenSecret); + const accessToken = jwt.sign( + { app: authenticated.app }, + this.authTokenSecret, + { expiresIn: "1h" } + ); res.json({ accessToken, @@ -30,17 +34,12 @@ class AuthControler { if (authHeader) { const token = authHeader.split(" ")[1]; - jwt.verify(token, authTokenSecret, (err, user) => { + jwt.verify(token, this.authTokenSecret, (err, app) => { if (err) { return res.status(403).json("Invalid token provided"); } - console.log( - "Authorization provided for ", - next.name, - " to user ", - user - ); + console.log("Authorization provided for ", next.name, " to app ", app); next(); }); } else { From c6e194789906f938067fd58adb19713c58ae5579 Mon Sep 17 00:00:00 2001 From: Sugui Date: Wed, 27 Dec 2023 20:02:26 +0100 Subject: [PATCH 010/133] Now 500 error works, and it's reflected in the tests --- src/controllers/ImageController.ts | 13 ++++++++---- src/services/ImageService.ts | 6 +++--- tests/app.test.ts | 33 ++++++++++++++++++++++++++---- 3 files changed, 41 insertions(+), 11 deletions(-) diff --git a/src/controllers/ImageController.ts b/src/controllers/ImageController.ts index 58c2a92..5e1fcac 100644 --- a/src/controllers/ImageController.ts +++ b/src/controllers/ImageController.ts @@ -1,5 +1,6 @@ import { Request, Response } from "express"; import imageService from "../services/ImageService"; +import mongoose, { mongo } from "mongoose"; class ImageController { async getAllImages(req: Request, res: Response): Promise { @@ -20,12 +21,16 @@ class ImageController { const image = await imageService.add(req.body); res.status(201).json({ image }); } catch (error: any) { - if (error.code === 11000) { + if (error instanceof mongo.MongoServerError && error.code === 11000) { // Should return 409 Conflict for existing urls - res.status(409).json({ error: "Existing URL" }); + res.status(409).json({ error: `the image with URL ${error.keyValue.url} already exists` }); + } else if (error instanceof mongoose.Error.ValidationError) { + // Should return 400 Bad request for invalid requests + res.status(400).json({ error: error.message }); + } else { + // Return 500 in other case + res.status(500).json({ error: error }); } - // Should return 400 Bad request for invalid requests - res.status(400).json({ error: error }); } } } diff --git a/src/services/ImageService.ts b/src/services/ImageService.ts index c8a3c16..bfaab2f 100644 --- a/src/services/ImageService.ts +++ b/src/services/ImageService.ts @@ -1,12 +1,12 @@ -import ImageModel, { Image } from "../models/ImageModel"; +import imageModel, { Image } from "../models/ImageModel"; class ImageService { async findAll(): Promise { - const allImages = await ImageModel.find(); + const allImages = await imageModel.find(); return allImages; } async add(image: Image): Promise { - const newImage = await ImageModel.create(image); + const newImage = await imageModel.create(image); return newImage; } } diff --git a/tests/app.test.ts b/tests/app.test.ts index f8ec9f4..455b873 100644 --- a/tests/app.test.ts +++ b/tests/app.test.ts @@ -1,6 +1,14 @@ -import { describe, expect, it, mock } from "bun:test"; +import { afterEach, describe, expect, it, mock } from "bun:test"; import request from "supertest"; import { app } from "../src"; +import imageService from "../src/services/ImageService"; + +const imageServiceOriginal = imageService; + +afterEach(() => { + mock.restore(); + mock.module("../src/services/ImageService", () => ({ default: imageServiceOriginal })); +}) describe("GET / shows all of the endpoints", async () => { const res = await request(app).get("/"); @@ -49,15 +57,32 @@ describe("POST /images works properly", () => { tags: ["2girls", "touhou"] }); - expect(res.status).toSatisfy(status => [409].includes(status)); + expect(res.status).toBe(409); + }); + + it("should return 500 for an error on the service", async () => { + mock.module("../src/services/ImageService", () => ({ + default: { + add: () => { throw new Error("This is an expected testing error"); } + } + })); + + const res = await request(app).post("/images").send({ + url: "https://test.url.com/3", + status: "available", + tags: ["2girls", "touhou"] + }); + + expect(res.status).toBe(500); }); it("should return 400 for malformed requests", async () => { + mock.restore(); const res = await request(app).post("/images").send({ - url: "https://test.url.com/3", + url: "https://test.url.com/4", status: "wrong", tags: ["2girls", "touhou"] }); - expect(res.status).toSatisfy(status => [400].includes(status)); + expect(res.status).toBe(400); }); }); \ No newline at end of file From 8396d597f196ed26c364321d9914f3de2caf3727 Mon Sep 17 00:00:00 2001 From: Alie Date: Wed, 27 Dec 2023 20:03:22 +0100 Subject: [PATCH 011/133] fixed mongo issues, why does it need to end with s??? --- compose.yaml | 1 + mongo-init.js | 42 ++++++++++++++++++-------------- src/controllers/AuthControler.ts | 10 ++++---- src/index.ts | 2 ++ src/models/AuthModel.ts | 2 +- src/services/AuthService.ts | 3 ++- 6 files changed, 35 insertions(+), 25 deletions(-) diff --git a/compose.yaml b/compose.yaml index 68d1912..ecec3f3 100644 --- a/compose.yaml +++ b/compose.yaml @@ -27,6 +27,7 @@ services: MONGODB_URI: "mongodb://mongodb:27017/bot" MONGODB_USER: "root" MONGODB_PASS: "password" + JWTSECRET: "cooljwtsecret" volumes: - ./:/usr/src/app:ro diff --git a/mongo-init.js b/mongo-init.js index a7b191b..67b53c9 100644 --- a/mongo-init.js +++ b/mongo-init.js @@ -1,24 +1,30 @@ db.createUser({ - user: 'root', - pwd: 'password', - roles: [ - { - role: 'readWrite', - db: 'admin', - }, - { - role: 'readWrite', - db: 'bot', - }, - ], + user: "root", + pwd: "password", + roles: [ + { + role: "readWrite", + db: "admin", + }, + { + role: "readWrite", + db: "bot", + }, + ], }); db = new Mongo().getDB("bot"); -db.images.createIndex({ "status": 1 }); -db.images.createIndex({ "url": 1 }, { "unique": true }); +db.images.createIndex({ status: 1 }); +db.images.createIndex({ url: 1 }, { unique: true }); db.images.insert({ - url: "https://example.com", - status: "consumed", - tags: ["2girls", "sleeping"] -}); \ No newline at end of file + url: "https://example.com", + status: "consumed", + tags: ["2girls", "sleeping"], +}); + +db.authorizations.createIndex({ app: 1 }); +db.authorizations.insert({ + app: "tester", + secret: "test", +}); diff --git a/src/controllers/AuthControler.ts b/src/controllers/AuthControler.ts index e983020..072638e 100644 --- a/src/controllers/AuthControler.ts +++ b/src/controllers/AuthControler.ts @@ -2,9 +2,9 @@ import jwt from "jsonwebtoken"; import AuthService from "../services/AuthService"; import { Request, Response, NextFunction } from "express"; -class AuthControler { - authTokenSecret = process.env.JWTSECRET || "badsecret"; +const authTokenSecret = process.env.JWTSECRET || "badsecret"; +class AuthControler { async login(req: Request, res: Response) { // Read app and secret from request body const { app, secret } = req.body; @@ -17,12 +17,12 @@ class AuthControler { // Generate an access token const accessToken = jwt.sign( { app: authenticated.app }, - this.authTokenSecret, + authTokenSecret, { expiresIn: "1h" } ); res.json({ - accessToken, + token: accessToken, }); } else { res.status(403).send("Credentials incorrect"); @@ -34,7 +34,7 @@ class AuthControler { if (authHeader) { const token = authHeader.split(" ")[1]; - jwt.verify(token, this.authTokenSecret, (err, app) => { + jwt.verify(token, authTokenSecret, (err, app) => { if (err) { return res.status(403).json("Invalid token provided"); } diff --git a/src/index.ts b/src/index.ts index 9dff064..d48f3fe 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,7 @@ import express from "express"; import mongoose from "mongoose"; import listEndpoints from "express-list-endpoints"; import imageController from "./controllers/ImageController"; +import authControler from "./controllers/AuthControler"; export const app = express(); @@ -14,6 +15,7 @@ app.get("/", (_, res) => { app.get("/images", imageController.getAllImages); app.post("/images", imageController.addImage); +app.post("/login", authControler.login) // Set the default port to 8080, or use the PORT environment variable diff --git a/src/models/AuthModel.ts b/src/models/AuthModel.ts index 52dc172..394a64b 100644 --- a/src/models/AuthModel.ts +++ b/src/models/AuthModel.ts @@ -16,4 +16,4 @@ const AuthSchema = new mongoose.Schema({ }, }); -export default mongoose.model("auth", AuthSchema); +export default mongoose.model("authorizations", AuthSchema); diff --git a/src/services/AuthService.ts b/src/services/AuthService.ts index 1b4bb62..aed8d12 100644 --- a/src/services/AuthService.ts +++ b/src/services/AuthService.ts @@ -2,7 +2,8 @@ import AuthModel, { Auth } from "../models/AuthModel"; class AuthService { async find(app: String, secret: String): Promise { - return await AuthModel.findOne(app, secret); + const auth = await AuthModel.findOne({ app: app, secret: secret }).exec(); + return auth; } } From ada964c49387994b7070a94d3d38cbebfda086f8 Mon Sep 17 00:00:00 2001 From: Alie Date: Wed, 27 Dec 2023 20:33:25 +0100 Subject: [PATCH 012/133] added tests for Authorization --- src/controllers/AuthControler.ts | 2 - src/index.ts | 2 +- tests/app.test.ts | 171 ++++++++++++++++++++----------- tests/auth.test.ts | 22 ++++ 4 files changed, 132 insertions(+), 65 deletions(-) create mode 100644 tests/auth.test.ts diff --git a/src/controllers/AuthControler.ts b/src/controllers/AuthControler.ts index 072638e..a524f56 100644 --- a/src/controllers/AuthControler.ts +++ b/src/controllers/AuthControler.ts @@ -38,8 +38,6 @@ class AuthControler { if (err) { return res.status(403).json("Invalid token provided"); } - - console.log("Authorization provided for ", next.name, " to app ", app); next(); }); } else { diff --git a/src/index.ts b/src/index.ts index d48f3fe..f396445 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,7 +14,7 @@ app.get("/", (_, res) => { }); app.get("/images", imageController.getAllImages); -app.post("/images", imageController.addImage); +app.post("/images", authControler.authorize, imageController.addImage); app.post("/login", authControler.login) // Set the default port to 8080, or use the PORT environment variable diff --git a/tests/app.test.ts b/tests/app.test.ts index 455b873..3d249b9 100644 --- a/tests/app.test.ts +++ b/tests/app.test.ts @@ -1,88 +1,135 @@ -import { afterEach, describe, expect, it, mock } from "bun:test"; +import { afterEach, beforeAll, describe, expect, it, mock } from "bun:test"; import request from "supertest"; import { app } from "../src"; import imageService from "../src/services/ImageService"; const imageServiceOriginal = imageService; +const tok = await request(app) + .post("/login") + .send({ app: "tester", secret: "test" }); +const token = tok.body.token; afterEach(() => { - mock.restore(); - mock.module("../src/services/ImageService", () => ({ default: imageServiceOriginal })); -}) + mock.restore(); + mock.module("../src/services/ImageService", () => ({ + default: imageServiceOriginal, + })); +}); describe("GET / shows all of the endpoints", async () => { - const res = await request(app).get("/"); + const res = await request(app).get("/"); - it("should be", async () => { - expect(res.body).toHaveProperty("endpoints"); - }); + it("should be", async () => { + expect(res.body).toHaveProperty("endpoints"); + }); - it("should be an array", () => { - expect(Array.isArray(res.body.endpoints)).toBeTrue(); - }) -}) + it("should be an array", () => { + expect(Array.isArray(res.body.endpoints)).toBeTrue(); + }); +}); describe("GET /images works properly", async () => { - const res = await request(app).get("/images"); + const res = await request(app).get("/images"); - it("should be an array", () => { - expect(Array.isArray(res.body.images)).toBeTrue(); - }); + it("should be an array", () => { + expect(Array.isArray(res.body.images)).toBeTrue(); + }); - it("should return a 200", async () => { - expect(res.statusCode).toBe(200); - }); + it("should return a 200", async () => { + expect(res.statusCode).toBe(200); + }); }); describe("POST /images works properly", () => { - it("should return 201 for new image", async () => { - const res = await request(app).post("/images").send({ - url: "https://test.url.com/1", + + it("should return 401 for unauthenticated requests", async () => { + const res = await request(app) + .post("/images") + .send({ + url: "https://test.url.com/0", status: "available", - tags: ["2girls", "touhou"] - }); - expect(res.status).toSatisfy(status => [201].includes(status)); - }); + tags: ["2girls", "touhou"], + }); + expect(res.status).toBe(401); + }); - it("should return 409 for a repeated images", async () => { - await request(app).post("/images").send({ - url: "https://test.url.com/2", + it("should return 403 for invalid tokens", async () => { + const res = await request(app) + .post("/images") + .set("authorization", `Bearer token`) + .send({ + url: "https://test.url.com/0", status: "available", - tags: ["2girls", "touhou"] - }); + tags: ["2girls", "touhou"], + }); + expect(res.status).toBe(403); + }); - const res = await request(app).post("/images").send({ - url: "https://test.url.com/2", - status: "available", - tags: ["2girls", "touhou"] - }); + it("should return 201 for new image", async () => { + const res = await request(app) + .post("/images") + .set("authorization", `Bearer ${token}`) + .send({ + url: "https://test.url.com/1", + status: "available", + tags: ["2girls", "touhou"], + }); + expect(res.status).toBe(201); + }); - expect(res.status).toBe(409); - }); + it("should return 409 for a repeated images", async () => { + await request(app) + .post("/images") + .set("authorization", `Bearer ${token}`) + .send({ + url: "https://test.url.com/2", + status: "available", + tags: ["2girls", "touhou"], + }); - it("should return 500 for an error on the service", async () => { - mock.module("../src/services/ImageService", () => ({ - default: { - add: () => { throw new Error("This is an expected testing error"); } - } - })); + const res = await request(app) + .post("/images") + .set("authorization", `Bearer ${token}`) + .send({ + url: "https://test.url.com/2", + status: "available", + tags: ["2girls", "touhou"], + }); - const res = await request(app).post("/images").send({ - url: "https://test.url.com/3", - status: "available", - tags: ["2girls", "touhou"] - }); - - expect(res.status).toBe(500); - }); + expect(res.status).toBe(409); + }); - it("should return 400 for malformed requests", async () => { - mock.restore(); - const res = await request(app).post("/images").send({ - url: "https://test.url.com/4", - status: "wrong", - tags: ["2girls", "touhou"] - }); - expect(res.status).toBe(400); - }); -}); \ No newline at end of file + it("should return 500 for an error on the service", async () => { + mock.module("../src/services/ImageService", () => ({ + default: { + add: () => { + throw new Error("This is an expected testing error"); + }, + }, + })); + + const res = await request(app) + .post("/images") + .set("authorization", `Bearer ${token}`) + .send({ + url: "https://test.url.com/3", + status: "available", + tags: ["2girls", "touhou"], + }); + + expect(res.status).toBe(500); + }); + + it("should return 400 for malformed requests", async () => { + mock.restore(); + const res = await request(app) + .post("/images") + .set("authorization", `Bearer ${token}`) + .send({ + url: "https://test.url.com/4", + status: "wrong", + tags: ["2girls", "touhou"], + }); + expect(res.status).toBe(400); + }); +}); diff --git a/tests/auth.test.ts b/tests/auth.test.ts new file mode 100644 index 0000000..6951875 --- /dev/null +++ b/tests/auth.test.ts @@ -0,0 +1,22 @@ +import { describe, expect, it, mock } from "bun:test"; +import request from "supertest"; +import { app } from "../src"; + +describe("/login", async () => { + const correctRespose = await request(app).post("/login").send({ + app: "tester", + secret: "test", + }); + it("should return 200 for correct login", () => { + expect(correctRespose.status).toBe(200); + }); + it("should contain a token", () => { + expect(correctRespose.body).toHaveProperty("token"); + }); + + it("should return 403 for invalid credentials", async () => { + const res = await request(app).post("/login").send({}); + expect(res.status).toBe(403); + }); +}); + From 3be98d0e20911d4aff8015cc7a6f1d0f0f1945c6 Mon Sep 17 00:00:00 2001 From: Alie Date: Wed, 27 Dec 2023 20:38:15 +0100 Subject: [PATCH 013/133] fixed a comment position --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index f396445..006cb3d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -17,9 +17,9 @@ app.get("/images", imageController.getAllImages); app.post("/images", authControler.authorize, imageController.addImage); app.post("/login", authControler.login) -// Set the default port to 8080, or use the PORT environment variable const start = async () => { + // Set the default port to 8080, or use the PORT environment variable const port = process.env.PORT || 8080; const mongo_uri: string = process.env.MONGODB_URI || ""; const mongo_user = process.env.MONGODB_USER; From 0d2e8dfe36b3839944e3766d2c51a8a5a2257df0 Mon Sep 17 00:00:00 2001 From: Alie Date: Wed, 27 Dec 2023 20:41:35 +0100 Subject: [PATCH 014/133] fmt --- .gitignore | 2 +- compose.yaml | 2 +- package.json | 2 +- src/controllers/ImageController.ts | 60 ++++++++++++++++-------------- src/index.ts | 7 ++-- src/models/AuthModel.ts | 4 +- src/models/ImageModel.ts | 34 ++++++++--------- src/services/ImageService.ts | 18 ++++----- tests/app.test.ts | 39 ++++++++++--------- tests/auth.test.ts | 1 - 10 files changed, 85 insertions(+), 84 deletions(-) diff --git a/.gitignore b/.gitignore index c2b8d7c..1822831 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ node_modules/ -bun.lockb \ No newline at end of file +bun.lockb diff --git a/compose.yaml b/compose.yaml index ecec3f3..964794b 100644 --- a/compose.yaml +++ b/compose.yaml @@ -1,4 +1,4 @@ -version: '3' +version: "3" services: mongodb: diff --git a/package.json b/package.json index 7a8021d..2080221 100644 --- a/package.json +++ b/package.json @@ -29,4 +29,4 @@ "jsonwebtoken": "^9.0.2", "mongoose": "^8.0.3" } -} \ No newline at end of file +} diff --git a/src/controllers/ImageController.ts b/src/controllers/ImageController.ts index 5e1fcac..1b86aea 100644 --- a/src/controllers/ImageController.ts +++ b/src/controllers/ImageController.ts @@ -3,36 +3,40 @@ import imageService from "../services/ImageService"; import mongoose, { mongo } from "mongoose"; class ImageController { - async getAllImages(req: Request, res: Response): Promise { - try { - const images = await imageService.findAll(); - res.json({ images }); - } catch (error) { - console.error(error); - res.status(500).json({ error: "Internal Server Error" }); - } + async getAllImages(req: Request, res: Response): Promise { + try { + const images = await imageService.findAll(); + res.json({ images }); + } catch (error) { + console.error(error); + res.status(500).json({ error: "Internal Server Error" }); } + } - async addImage(req: Request, res: Response): Promise { - try { - // Should add auth here before doing stuff - // Thowing a 401 if not auth provided - // Throwing a 403 for incorrect auth - const image = await imageService.add(req.body); - res.status(201).json({ image }); - } catch (error: any) { - if (error instanceof mongo.MongoServerError && error.code === 11000) { - // Should return 409 Conflict for existing urls - res.status(409).json({ error: `the image with URL ${error.keyValue.url} already exists` }); - } else if (error instanceof mongoose.Error.ValidationError) { - // Should return 400 Bad request for invalid requests - res.status(400).json({ error: error.message }); - } else { - // Return 500 in other case - res.status(500).json({ error: error }); - } - } + async addImage(req: Request, res: Response): Promise { + try { + // Should add auth here before doing stuff + // Thowing a 401 if not auth provided + // Throwing a 403 for incorrect auth + const image = await imageService.add(req.body); + res.status(201).json({ image }); + } catch (error: any) { + if (error instanceof mongo.MongoServerError && error.code === 11000) { + // Should return 409 Conflict for existing urls + res + .status(409) + .json({ + error: `the image with URL ${error.keyValue.url} already exists`, + }); + } else if (error instanceof mongoose.Error.ValidationError) { + // Should return 400 Bad request for invalid requests + res.status(400).json({ error: error.message }); + } else { + // Return 500 in other case + res.status(500).json({ error: error }); + } } + } } -export default new ImageController(); \ No newline at end of file +export default new ImageController(); diff --git a/src/index.ts b/src/index.ts index 006cb3d..d74231b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -9,14 +9,13 @@ export const app = express(); app.use(express.json()); app.get("/", (_, res) => { - const endpoints = listEndpoints(app); - res.json({ endpoints }); + const endpoints = listEndpoints(app); + res.json({ endpoints }); }); app.get("/images", imageController.getAllImages); app.post("/images", authControler.authorize, imageController.addImage); -app.post("/login", authControler.login) - +app.post("/login", authControler.login); const start = async () => { // Set the default port to 8080, or use the PORT environment variable diff --git a/src/models/AuthModel.ts b/src/models/AuthModel.ts index 394a64b..df71afe 100644 --- a/src/models/AuthModel.ts +++ b/src/models/AuthModel.ts @@ -1,8 +1,8 @@ import mongoose, { Document } from "mongoose"; export interface Auth extends Document { - app: String, - secret: String + app: String; + secret: String; } const AuthSchema = new mongoose.Schema({ diff --git a/src/models/ImageModel.ts b/src/models/ImageModel.ts index 5ef3b70..d91ab18 100644 --- a/src/models/ImageModel.ts +++ b/src/models/ImageModel.ts @@ -1,26 +1,26 @@ import mongoose, { Document } from "mongoose"; export interface Image extends Document { - url: String; - enum: "consumed" | "unavailable" | "available"; - tags?: String[]; + url: String; + enum: "consumed" | "unavailable" | "available"; + tags?: String[]; } const ImageSchema = new mongoose.Schema({ - url: { - type: String, - required: true + url: { + type: String, + required: true, + }, + status: { + type: String, + enum: { + values: ["consumed", "unavailable", "available"], }, - status: { - type: String, - enum: { - values: ["consumed", "unavailable", "available"], - }, - required: true - }, - tags: { - type: [String] - } + required: true, + }, + tags: { + type: [String], + }, }); -export default mongoose.model('images', ImageSchema); +export default mongoose.model("images", ImageSchema); diff --git a/src/services/ImageService.ts b/src/services/ImageService.ts index bfaab2f..8691f7d 100644 --- a/src/services/ImageService.ts +++ b/src/services/ImageService.ts @@ -1,14 +1,14 @@ import imageModel, { Image } from "../models/ImageModel"; class ImageService { - async findAll(): Promise { - const allImages = await imageModel.find(); - return allImages; - } - async add(image: Image): Promise { - const newImage = await imageModel.create(image); - return newImage; - } + async findAll(): Promise { + const allImages = await imageModel.find(); + return allImages; + } + async add(image: Image): Promise { + const newImage = await imageModel.create(image); + return newImage; + } } -export default new ImageService(); \ No newline at end of file +export default new ImageService(); diff --git a/tests/app.test.ts b/tests/app.test.ts index 3d249b9..ac40ace 100644 --- a/tests/app.test.ts +++ b/tests/app.test.ts @@ -41,29 +41,28 @@ describe("GET /images works properly", async () => { }); describe("POST /images works properly", () => { - - it("should return 401 for unauthenticated requests", async () => { - const res = await request(app) - .post("/images") - .send({ - url: "https://test.url.com/0", - status: "available", - tags: ["2girls", "touhou"], - }); - expect(res.status).toBe(401); + it("should return 401 for unauthenticated requests", async () => { + const res = await request(app) + .post("/images") + .send({ + url: "https://test.url.com/0", + status: "available", + tags: ["2girls", "touhou"], }); + expect(res.status).toBe(401); + }); - it("should return 403 for invalid tokens", async () => { - const res = await request(app) - .post("/images") - .set("authorization", `Bearer token`) - .send({ - url: "https://test.url.com/0", - status: "available", - tags: ["2girls", "touhou"], - }); - expect(res.status).toBe(403); + it("should return 403 for invalid tokens", async () => { + const res = await request(app) + .post("/images") + .set("authorization", `Bearer token`) + .send({ + url: "https://test.url.com/0", + status: "available", + tags: ["2girls", "touhou"], }); + expect(res.status).toBe(403); + }); it("should return 201 for new image", async () => { const res = await request(app) diff --git a/tests/auth.test.ts b/tests/auth.test.ts index 6951875..bd20cd2 100644 --- a/tests/auth.test.ts +++ b/tests/auth.test.ts @@ -19,4 +19,3 @@ describe("/login", async () => { expect(res.status).toBe(403); }); }); - From 3fa770880bc603d503755882cd6bd136c7943041 Mon Sep 17 00:00:00 2001 From: bizcochito Date: Fri, 29 Dec 2023 08:44:40 +0000 Subject: [PATCH 015/133] updated container used for workflow --- .gitea/workflows/test.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 32b6117..0cca8ee 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -4,7 +4,8 @@ on: [pull_request] jobs: Explore-Gitea-Actions: - runs-on: ubuntu-latest + container: + image: oven/bun:1 steps: - run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event." - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!" From f859cdeeb10f53754d285266641d459326b41a88 Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 29 Dec 2023 09:53:31 +0100 Subject: [PATCH 016/133] remove unused variable --- src/controllers/AuthControler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/controllers/AuthControler.ts b/src/controllers/AuthControler.ts index a524f56..4f0649c 100644 --- a/src/controllers/AuthControler.ts +++ b/src/controllers/AuthControler.ts @@ -34,7 +34,7 @@ class AuthControler { if (authHeader) { const token = authHeader.split(" ")[1]; - jwt.verify(token, authTokenSecret, (err, app) => { + jwt.verify(token, authTokenSecret, (err, _) => { if (err) { return res.status(403).json("Invalid token provided"); } From 1b45481d279172f3be5c1ad0767b43a1b115706a Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 15:24:29 +0100 Subject: [PATCH 017/133] commit all changes to tests --- compose.yaml | 3 +- mongo-init.js | 30 ----- package.json | 2 + src/app.ts | 41 +++++++ src/index.ts | 43 +------ src/models/AuthModel.ts | 3 +- src/models/ImageModel.ts | 5 +- src/services/AuthService.ts | 4 +- tests/app.test.ts | 227 +++++++++++++++++++----------------- tests/auth.test.ts | 25 +++- tests/memoryServer.ts | 19 +++ tests/populateDatabase.ts | 15 +++ 12 files changed, 230 insertions(+), 187 deletions(-) delete mode 100644 mongo-init.js create mode 100644 src/app.ts create mode 100644 tests/memoryServer.ts create mode 100644 tests/populateDatabase.ts diff --git a/compose.yaml b/compose.yaml index 964794b..2ca513c 100644 --- a/compose.yaml +++ b/compose.yaml @@ -12,7 +12,6 @@ services: MONGO_INITDB_DATABASE: bot volumes: - mongodb_data:/data/db - - ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro bot-api: image: oven/bun:1 @@ -28,6 +27,8 @@ services: MONGODB_USER: "root" MONGODB_PASS: "password" JWTSECRET: "cooljwtsecret" + # DEDICATED_MONGODB_SERVER is for integration testing, for disabling memory server in tests + DEDICATED_MONGODB_SERVER: "true" volumes: - ./:/usr/src/app:ro diff --git a/mongo-init.js b/mongo-init.js deleted file mode 100644 index 67b53c9..0000000 --- a/mongo-init.js +++ /dev/null @@ -1,30 +0,0 @@ -db.createUser({ - user: "root", - pwd: "password", - roles: [ - { - role: "readWrite", - db: "admin", - }, - { - role: "readWrite", - db: "bot", - }, - ], -}); - -db = new Mongo().getDB("bot"); - -db.images.createIndex({ status: 1 }); -db.images.createIndex({ url: 1 }, { unique: true }); -db.images.insert({ - url: "https://example.com", - status: "consumed", - tags: ["2girls", "sleeping"], -}); - -db.authorizations.createIndex({ app: 1 }); -db.authorizations.insert({ - app: "tester", - secret: "test", -}); diff --git a/package.json b/package.json index 2080221..6d9c33c 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,11 @@ "type": "module", "devDependencies": { "@types/jest": "^29.5.11", + "@types/mongodb-memory-server": "^2.3.0", "@types/supertest": "^6.0.1", "bun-types": "latest", "jest": "^29.7.0", + "mongodb-memory-server": "^9.1.3", "supertest": "^6.3.3", "ts-jest": "^29.1.1" }, diff --git a/src/app.ts b/src/app.ts new file mode 100644 index 0000000..e132aa4 --- /dev/null +++ b/src/app.ts @@ -0,0 +1,41 @@ +import express from "express"; +import listEndpoints from "express-list-endpoints"; +import imageController from "./controllers/ImageController"; +import authControler from "./controllers/AuthControler"; +import mongoose from "mongoose"; + +export const app = express(); + +app.use(express.json()); + +app.get("/", (_, res) => { + const endpoints = listEndpoints(app); + res.json({ endpoints }); +}); + +app.get("/images", imageController.getAllImages); +app.post("/images", authControler.authorize, imageController.addImage); +app.post("/login", authControler.login); + +export const startApp = async () => { + const port = process.env.PORT || 8080; + const mongo_uri: string = process.env.MONGODB_URI || ""; + const mongo_user = process.env.MONGODB_USER; + const mongo_pass = process.env.MONGODB_PASS; + + try { + await mongoose.connect(mongo_uri, { + authSource: "admin", + user: mongo_user, + pass: mongo_pass, + }); + app.listen(port, () => + console.log(`Express server listening on port ${port}`) + ); + } catch (error) { + console.error(error); + process.exit(1); + } + }; + +export default app; \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index d74231b..cdff0b9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,42 +1,3 @@ -import express from "express"; -import mongoose from "mongoose"; -import listEndpoints from "express-list-endpoints"; -import imageController from "./controllers/ImageController"; -import authControler from "./controllers/AuthControler"; +import { startApp } from "./app"; -export const app = express(); - -app.use(express.json()); - -app.get("/", (_, res) => { - const endpoints = listEndpoints(app); - res.json({ endpoints }); -}); - -app.get("/images", imageController.getAllImages); -app.post("/images", authControler.authorize, imageController.addImage); -app.post("/login", authControler.login); - -const start = async () => { - // Set the default port to 8080, or use the PORT environment variable - const port = process.env.PORT || 8080; - const mongo_uri: string = process.env.MONGODB_URI || ""; - const mongo_user = process.env.MONGODB_USER; - const mongo_pass = process.env.MONGODB_PASS; - - try { - await mongoose.connect(mongo_uri, { - authSource: "admin", - user: mongo_user, - pass: mongo_pass, - }); - app.listen(port, () => - console.log(`Express server listening on port ${port}`) - ); - } catch (error) { - console.error(error); - process.exit(1); - } -}; - -start(); +startApp(); \ No newline at end of file diff --git a/src/models/AuthModel.ts b/src/models/AuthModel.ts index df71afe..96ce5e5 100644 --- a/src/models/AuthModel.ts +++ b/src/models/AuthModel.ts @@ -9,11 +9,12 @@ const AuthSchema = new mongoose.Schema({ app: { type: String, required: true, + index: true, }, secret: { type: String, required: true, }, -}); +}, { collection: "authorizations" }); export default mongoose.model("authorizations", AuthSchema); diff --git a/src/models/ImageModel.ts b/src/models/ImageModel.ts index d91ab18..b3bff2c 100644 --- a/src/models/ImageModel.ts +++ b/src/models/ImageModel.ts @@ -10,6 +10,8 @@ const ImageSchema = new mongoose.Schema({ url: { type: String, required: true, + index: true, + unique: true }, status: { type: String, @@ -17,10 +19,11 @@ const ImageSchema = new mongoose.Schema({ values: ["consumed", "unavailable", "available"], }, required: true, + index: true, }, tags: { type: [String], }, -}); +}, { collection: "images" }); export default mongoose.model("images", ImageSchema); diff --git a/src/services/AuthService.ts b/src/services/AuthService.ts index aed8d12..d44e7eb 100644 --- a/src/services/AuthService.ts +++ b/src/services/AuthService.ts @@ -1,8 +1,8 @@ import AuthModel, { Auth } from "../models/AuthModel"; class AuthService { - async find(app: String, secret: String): Promise { - const auth = await AuthModel.findOne({ app: app, secret: secret }).exec(); + async find(app: string, secret: string): Promise { + const auth = await AuthModel.findOne({ app: app, secret: secret }); return auth; } } diff --git a/tests/app.test.ts b/tests/app.test.ts index ac40ace..72a6ebc 100644 --- a/tests/app.test.ts +++ b/tests/app.test.ts @@ -1,134 +1,151 @@ -import { afterEach, beforeAll, describe, expect, it, mock } from "bun:test"; +import { afterAll, afterEach, beforeAll, describe, expect, it, mock } from "bun:test"; import request from "supertest"; -import { app } from "../src"; +import app, { startApp } from "../src/app"; import imageService from "../src/services/ImageService"; +import memoryServer from "./memoryServer"; +import populateDatabase from "./populateDatabase"; const imageServiceOriginal = imageService; -const tok = await request(app) - .post("/login") - .send({ app: "tester", secret: "test" }); -const token = tok.body.token; + +let token: string; + +beforeAll(async () => { + if (!process.env.DEDICATED_MONGODB_SERVER) + await memoryServer.start(); + await startApp(); + await populateDatabase(); + + const tok = await request(app) + .post("/login") + .send({ app: "tester", secret: "test" }); + token = tok.body.token; +}); + +afterAll(async () => { + if (!process.env.DEDICATED_MONGODB_SERVER) + await memoryServer.stop(); +}) afterEach(() => { - mock.restore(); - mock.module("../src/services/ImageService", () => ({ - default: imageServiceOriginal, - })); + mock.restore(); + mock.module("../src/services/ImageService", () => ({ + default: imageServiceOriginal, + })); }); describe("GET / shows all of the endpoints", async () => { - const res = await request(app).get("/"); + const res = await request(app).get("/"); - it("should be", async () => { - expect(res.body).toHaveProperty("endpoints"); - }); + it("should be", async () => { + expect(res.body).toHaveProperty("endpoints"); + }); - it("should be an array", () => { - expect(Array.isArray(res.body.endpoints)).toBeTrue(); - }); + it("should be an array", () => { + expect(Array.isArray(res.body.endpoints)).toBeTrue(); + }); }); describe("GET /images works properly", async () => { - const res = await request(app).get("/images"); + const res = await request(app).get("/images"); - it("should be an array", () => { - expect(Array.isArray(res.body.images)).toBeTrue(); - }); + it("should be an array", () => { + expect(Array.isArray(res.body.images)).toBeTrue(); + }); - it("should return a 200", async () => { - expect(res.statusCode).toBe(200); - }); + it("should return a 200", async () => { + expect(res.statusCode).toBe(200); + }); }); describe("POST /images works properly", () => { - it("should return 401 for unauthenticated requests", async () => { - const res = await request(app) - .post("/images") - .send({ - url: "https://test.url.com/0", - status: "available", - tags: ["2girls", "touhou"], - }); - expect(res.status).toBe(401); - }); + it("should return 401 for unauthenticated requests", async () => { + const res = await request(app) + .post("/images") + .send({ + url: "https://test.url.com/0", + status: "available", + tags: ["2girls", "touhou"], + }); + expect(res.status).toBe(401); + }); - it("should return 403 for invalid tokens", async () => { - const res = await request(app) - .post("/images") - .set("authorization", `Bearer token`) - .send({ - url: "https://test.url.com/0", - status: "available", - tags: ["2girls", "touhou"], - }); - expect(res.status).toBe(403); - }); + it("should return 403 for invalid tokens", async () => { + const res = await request(app) + .post("/images") + .set("authorization", `Bearer token`) + .send({ + url: "https://test.url.com/0", + status: "available", + tags: ["2girls", "touhou"], + }); + expect(res.status).toBe(403); + }); - it("should return 201 for new image", async () => { - const res = await request(app) - .post("/images") - .set("authorization", `Bearer ${token}`) - .send({ - url: "https://test.url.com/1", - status: "available", - tags: ["2girls", "touhou"], - }); - expect(res.status).toBe(201); - }); + it("should return 201 for new image", async () => { + const res = await request(app) + .post("/images") + .set("authorization", `Bearer ${token}`) + .send({ + url: "https://test.url.com/1", + status: "available", + tags: ["2girls", "touhou"], + }); + expect(res.status).toBe(201); + }); - it("should return 409 for a repeated images", async () => { - await request(app) - .post("/images") - .set("authorization", `Bearer ${token}`) - .send({ - url: "https://test.url.com/2", - status: "available", - tags: ["2girls", "touhou"], - }); + it("should return 409 for a repeated images", async () => { + await request(app) + .post("/images") + .set("authorization", `Bearer ${token}`) + .send({ + url: "https://test.url.com/2", + status: "available", + tags: ["2girls", "touhou"], + }); - const res = await request(app) - .post("/images") - .set("authorization", `Bearer ${token}`) - .send({ - url: "https://test.url.com/2", - status: "available", - tags: ["2girls", "touhou"], - }); + const res = await request(app) + .post("/images") + .set("authorization", `Bearer ${token}`) + .send({ + url: "https://test.url.com/2", + status: "available", + tags: ["2girls", "touhou"], + }); - expect(res.status).toBe(409); - }); + expect(res.status).toBe(409); + }); - it("should return 500 for an error on the service", async () => { - mock.module("../src/services/ImageService", () => ({ - default: { - add: () => { - throw new Error("This is an expected testing error"); - }, - }, - })); + it("should return 500 for an error on the service", async () => { + mock.module("../src/services/ImageService", () => ({ + default: { + add: () => { + throw new Error("This is an expected testing error"); + }, + }, + })); - const res = await request(app) - .post("/images") - .set("authorization", `Bearer ${token}`) - .send({ - url: "https://test.url.com/3", - status: "available", - tags: ["2girls", "touhou"], - }); + const res = await request(app) + .post("/images") + .set("authorization", `Bearer ${token}`) + .send({ + url: "https://test.url.com/3", + status: "available", + tags: ["2girls", "touhou"], + }); - expect(res.status).toBe(500); - }); + expect(res.status).toBe(500); + }); - it("should return 400 for malformed requests", async () => { - mock.restore(); - const res = await request(app) - .post("/images") - .set("authorization", `Bearer ${token}`) - .send({ - url: "https://test.url.com/4", - status: "wrong", - tags: ["2girls", "touhou"], - }); - expect(res.status).toBe(400); - }); + it("should return 400 for malformed requests", async () => { + mock.restore(); + const res = await request(app) + .post("/images") + .set("authorization", `Bearer ${token}`) + .send({ + url: "https://test.url.com/4", + status: "wrong", + tags: ["2girls", "touhou"], + }); + expect(res.status).toBe(400); + }); }); diff --git a/tests/auth.test.ts b/tests/auth.test.ts index bd20cd2..18c3789 100644 --- a/tests/auth.test.ts +++ b/tests/auth.test.ts @@ -1,12 +1,25 @@ -import { describe, expect, it, mock } from "bun:test"; +import { afterAll, beforeAll, describe, expect, it } from "bun:test"; import request from "supertest"; -import { app } from "../src"; +import app, { startApp } from "../src/app"; +import memoryServer from "./memoryServer"; +import populateDatabase from "./populateDatabase"; + +beforeAll(async () => { + if (!process.env.DEDICATED_MONGODB_SERVER) + await memoryServer.start(); + await startApp(); + await populateDatabase(); +}); + +afterAll(async () => { + if (!process.env.DEDICATED_MONGODB_SERVER) + await memoryServer.stop(); +}); describe("/login", async () => { - const correctRespose = await request(app).post("/login").send({ - app: "tester", - secret: "test", - }); + const correctRespose = await request(app) + .post("/login") + .send({ app: "tester", secret: "test" }); it("should return 200 for correct login", () => { expect(correctRespose.status).toBe(200); }); diff --git a/tests/memoryServer.ts b/tests/memoryServer.ts new file mode 100644 index 0000000..8dd7513 --- /dev/null +++ b/tests/memoryServer.ts @@ -0,0 +1,19 @@ +import { MongoMemoryServer } from "mongodb-memory-server"; + +class MemoryServer { + mongod: MongoMemoryServer | undefined; + + async start() { + this.mongod = await MongoMemoryServer.create(); + const uri = this.mongod.getUri("bot"); + process.env.MONGODB_URI = uri; + } + + async stop() { + if (this.mongod) { + await this.mongod.stop(); + } + } +} + +export default new MemoryServer(); \ No newline at end of file diff --git a/tests/populateDatabase.ts b/tests/populateDatabase.ts new file mode 100644 index 0000000..93f63c1 --- /dev/null +++ b/tests/populateDatabase.ts @@ -0,0 +1,15 @@ +import authModel from "../src/models/AuthModel"; +import imageModel from "../src/models/ImageModel"; + +export default async function () { + await imageModel.create({ + url: "https://example.com", + status: "consumed", + tags: ["2girls", "sleeping"], + }); + + await authModel.create({ + app: "tester", + secret: "test", + }); +} From 7c68174ca40d5be567ed4f38d4c3c5a171cb7e19 Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 29 Dec 2023 16:05:51 +0100 Subject: [PATCH 018/133] fixed the test issue, before all and things --- src/controllers/AuthControler.ts | 3 ++- src/index.ts | 11 ++++++++++- src/services/AuthService.ts | 4 +++- tests/auth.test.ts | 21 ++++++++++++--------- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/controllers/AuthControler.ts b/src/controllers/AuthControler.ts index 4f0649c..68c69ac 100644 --- a/src/controllers/AuthControler.ts +++ b/src/controllers/AuthControler.ts @@ -7,13 +7,14 @@ const authTokenSecret = process.env.JWTSECRET || "badsecret"; class AuthControler { async login(req: Request, res: Response) { // Read app and secret from request body + console.log(req.body) const { app, secret } = req.body; // Filter app from the apps by app and secret const authenticated = await AuthService.find(app, secret); if (authenticated) { - console.log("Authenticated app ", authenticated.app); + console.log("Authenticated app", authenticated.app); // Generate an access token const accessToken = jwt.sign( { app: authenticated.app }, diff --git a/src/index.ts b/src/index.ts index cdff0b9..7155635 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,12 @@ +import populateDatabase from "../tests/populateDatabase"; import { startApp } from "./app"; -startApp(); \ No newline at end of file +await startApp(); + + +try{ + await populateDatabase(); +} +catch { + +} \ No newline at end of file diff --git a/src/services/AuthService.ts b/src/services/AuthService.ts index d44e7eb..9dcdabe 100644 --- a/src/services/AuthService.ts +++ b/src/services/AuthService.ts @@ -1,8 +1,10 @@ import AuthModel, { Auth } from "../models/AuthModel"; class AuthService { - async find(app: string, secret: string): Promise { + async find(app: String, secret: String): Promise { + console.log(app, secret) const auth = await AuthModel.findOne({ app: app, secret: secret }); + console.log(auth) return auth; } } diff --git a/tests/auth.test.ts b/tests/auth.test.ts index 18c3789..affe74f 100644 --- a/tests/auth.test.ts +++ b/tests/auth.test.ts @@ -1,28 +1,31 @@ import { afterAll, beforeAll, describe, expect, it } from "bun:test"; -import request from "supertest"; +import request, { Response } from "supertest"; import app, { startApp } from "../src/app"; import memoryServer from "./memoryServer"; import populateDatabase from "./populateDatabase"; beforeAll(async () => { - if (!process.env.DEDICATED_MONGODB_SERVER) - await memoryServer.start(); + if (!process.env.DEDICATED_MONGODB_SERVER) await memoryServer.start(); await startApp(); await populateDatabase(); }); afterAll(async () => { - if (!process.env.DEDICATED_MONGODB_SERVER) - await memoryServer.stop(); + if (!process.env.DEDICATED_MONGODB_SERVER) await memoryServer.stop(); }); describe("/login", async () => { - const correctRespose = await request(app) - .post("/login") - .send({ app: "tester", secret: "test" }); - it("should return 200 for correct login", () => { + let correctRespose: Response; + beforeAll(async () => { + correctRespose = await request(app) + .post("/login") + .send({ app: "tester", secret: "test" }); + }); + + it("should return 200 for correct login", async () => { expect(correctRespose.status).toBe(200); }); + it("should contain a token", () => { expect(correctRespose.body).toHaveProperty("token"); }); From 6acb9ee3d97d962cb1b989405308b569c0bc4ae6 Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 29 Dec 2023 16:08:09 +0100 Subject: [PATCH 019/133] changes to the action --- .gitea/workflows/test.yaml | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 0cca8ee..c4db36b 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -1,19 +1,15 @@ -name: Gitea Actions Demo +name: Unit Tests run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀 on: [pull_request] jobs: - Explore-Gitea-Actions: + unit-test: container: image: oven/bun:1 steps: - - run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event." - - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!" - - run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}." - name: Check out repository code uses: actions/checkout@v3 - - run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner." - - run: echo "🖥️ The workflow is now ready to test your code on the runner." - - name: List files in the repository - run: | - ls ${{ gitea.workspace }} \ No newline at end of file + - name: Bun install + run: bun install + - name: Run the test + run: bun test \ No newline at end of file From 1c05d114a4665da52f705ac5c568badca91fc8f7 Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 29 Dec 2023 16:11:49 +0100 Subject: [PATCH 020/133] changed the image --- .gitea/workflows/test.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index c4db36b..80a39fb 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -4,11 +4,11 @@ on: [pull_request] jobs: unit-test: - container: - image: oven/bun:1 steps: - name: Check out repository code uses: actions/checkout@v3 + - name: Install Bun + run: curl -fsSL https://bun.sh/install - name: Bun install run: bun install - name: Run the test From e5d191dd58900523ce70b2d26cabb64115a8bdcb Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 29 Dec 2023 16:14:37 +0100 Subject: [PATCH 021/133] forgor to pipe --- .gitea/workflows/test.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 80a39fb..2b9102c 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -7,9 +7,9 @@ jobs: steps: - name: Check out repository code uses: actions/checkout@v3 - - name: Install Bun - run: curl -fsSL https://bun.sh/install - - name: Bun install + - name: Install Bun runtime + run: curl -fsSL https://bun.sh/install | sh + - name: Install dependencies run: bun install - name: Run the test run: bun test \ No newline at end of file From d9814a28eb74b431603919f208136718c6c2c0c0 Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 29 Dec 2023 16:16:57 +0100 Subject: [PATCH 022/133] container --- .gitea/workflows/test.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 2b9102c..df77dfe 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -4,6 +4,8 @@ on: [pull_request] jobs: unit-test: + container: + image: node:16-bullseye steps: - name: Check out repository code uses: actions/checkout@v3 From 90b617f86ca46aaa9076e8f263e1577a1a1acb8a Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 29 Dec 2023 16:17:50 +0100 Subject: [PATCH 023/133] bash --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index df77dfe..f58295e 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -10,7 +10,7 @@ jobs: - name: Check out repository code uses: actions/checkout@v3 - name: Install Bun runtime - run: curl -fsSL https://bun.sh/install | sh + run: curl -fsSL https://bun.sh/install | bash - name: Install dependencies run: bun install - name: Run the test From 1aa75a21fd1b58ba6303716a757bd235eaccb94b Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 29 Dec 2023 16:18:53 +0100 Subject: [PATCH 024/133] path --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index f58295e..9b8a134 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -10,7 +10,7 @@ jobs: - name: Check out repository code uses: actions/checkout@v3 - name: Install Bun runtime - run: curl -fsSL https://bun.sh/install | bash + run: curl -fsSL https://bun.sh/install | bash && source /root/.bashrc - name: Install dependencies run: bun install - name: Run the test From 1da18fba4e3b10d0f9ad080029cba0ad9fa772dd Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 29 Dec 2023 16:20:18 +0100 Subject: [PATCH 025/133] why does it not let you source??? --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 9b8a134..783ca77 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -10,7 +10,7 @@ jobs: - name: Check out repository code uses: actions/checkout@v3 - name: Install Bun runtime - run: curl -fsSL https://bun.sh/install | bash && source /root/.bashrc + run: curl -fsSL https://bun.sh/install | bash && bash - name: Install dependencies run: bun install - name: Run the test From c8fa9cc2ddf6b328ec198d8f1fd99313b1b8ac94 Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 29 Dec 2023 16:22:03 +0100 Subject: [PATCH 026/133] ok, then directly execute --- .gitea/workflows/test.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 783ca77..f4b14f5 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -10,8 +10,8 @@ jobs: - name: Check out repository code uses: actions/checkout@v3 - name: Install Bun runtime - run: curl -fsSL https://bun.sh/install | bash && bash + run: curl -fsSL https://bun.sh/install | bash - name: Install dependencies - run: bun install + run: ~/.bun/bin/bun install - name: Run the test - run: bun test \ No newline at end of file + run: ~/.bun/bin/bun test \ No newline at end of file From 86f20e6b45ed80541117bc53fcd2af179248ccd4 Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 29 Dec 2023 16:25:42 +0100 Subject: [PATCH 027/133] there is no mongo dor debian11 aarch64 :) --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index f4b14f5..c1746f2 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -5,7 +5,7 @@ on: [pull_request] jobs: unit-test: container: - image: node:16-bullseye + image: catthehacker/ubuntu:act-latest steps: - name: Check out repository code uses: actions/checkout@v3 From e64474a4f472f60d0dcee4f59bcdb064182112f9 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 16:37:24 +0100 Subject: [PATCH 028/133] Testing action with docker compose --- .gitea/workflows/test-compose.yaml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .gitea/workflows/test-compose.yaml diff --git a/.gitea/workflows/test-compose.yaml b/.gitea/workflows/test-compose.yaml new file mode 100644 index 0000000..3b3b6d2 --- /dev/null +++ b/.gitea/workflows/test-compose.yaml @@ -0,0 +1,17 @@ +name: Unit Tests with docker compose +run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀 +on: [pull_request] + +jobs: + unit-test: + container: + image: catthehacker/ubuntu:act-latest + steps: + - name: Check out repository code + uses: actions/checkout@v3 + - name: Install Bun runtime + run: curl -fsSL https://bun.sh/install | bash + - name: Install docker-compose + run: apt install -y docker.io + - name: Run docker-compose + run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file From 2684b2e1d51b5c8a52577890e496b756e2fef837 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 16:39:54 +0100 Subject: [PATCH 029/133] update --- .gitea/workflows/test-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test-compose.yaml b/.gitea/workflows/test-compose.yaml index 3b3b6d2..7b2ece1 100644 --- a/.gitea/workflows/test-compose.yaml +++ b/.gitea/workflows/test-compose.yaml @@ -12,6 +12,6 @@ jobs: - name: Install Bun runtime run: curl -fsSL https://bun.sh/install | bash - name: Install docker-compose - run: apt install -y docker.io + run: apt update && apt install -y docker.io - name: Run docker-compose run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file From 4dd4d18a92724b580eda18b5c921087395efaa71 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 16:48:26 +0100 Subject: [PATCH 030/133] testing moby --- .gitea/workflows/test-compose.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.gitea/workflows/test-compose.yaml b/.gitea/workflows/test-compose.yaml index 7b2ece1..fd2ea66 100644 --- a/.gitea/workflows/test-compose.yaml +++ b/.gitea/workflows/test-compose.yaml @@ -11,7 +11,5 @@ jobs: uses: actions/checkout@v3 - name: Install Bun runtime run: curl -fsSL https://bun.sh/install | bash - - name: Install docker-compose - run: apt update && apt install -y docker.io - name: Run docker-compose - run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file + run: moby compose down -v && moby compose run bot-api bun test \ No newline at end of file From 01318e7579a58718980b4eea3ca72cebf019acb7 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 16:53:56 +0100 Subject: [PATCH 031/133] using docker image --- .gitea/workflows/test-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test-compose.yaml b/.gitea/workflows/test-compose.yaml index fd2ea66..73bb422 100644 --- a/.gitea/workflows/test-compose.yaml +++ b/.gitea/workflows/test-compose.yaml @@ -5,7 +5,7 @@ on: [pull_request] jobs: unit-test: container: - image: catthehacker/ubuntu:act-latest + image: docker:latest steps: - name: Check out repository code uses: actions/checkout@v3 From 54a4025672234d85719498168cbfb77d91ec6fd3 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 16:58:34 +0100 Subject: [PATCH 032/133] adding nodejs --- .gitea/workflows/test-compose.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitea/workflows/test-compose.yaml b/.gitea/workflows/test-compose.yaml index 73bb422..58d6da1 100644 --- a/.gitea/workflows/test-compose.yaml +++ b/.gitea/workflows/test-compose.yaml @@ -7,6 +7,8 @@ jobs: container: image: docker:latest steps: + - name: Installing node + run: apk add nodejs - name: Check out repository code uses: actions/checkout@v3 - name: Install Bun runtime From 36e91e89f6662da5cb6399d2634a492537bb2150 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 17:00:09 +0100 Subject: [PATCH 033/133] adding git --- .gitea/workflows/test-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test-compose.yaml b/.gitea/workflows/test-compose.yaml index 58d6da1..ca6d1dd 100644 --- a/.gitea/workflows/test-compose.yaml +++ b/.gitea/workflows/test-compose.yaml @@ -8,7 +8,7 @@ jobs: image: docker:latest steps: - name: Installing node - run: apk add nodejs + run: apk add nodejs git - name: Check out repository code uses: actions/checkout@v3 - name: Install Bun runtime From 3c723a810936acdb0a8228d6c925614335059c7b Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 17:02:28 +0100 Subject: [PATCH 034/133] adding curl and bash --- .gitea/workflows/test-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test-compose.yaml b/.gitea/workflows/test-compose.yaml index ca6d1dd..4ba542f 100644 --- a/.gitea/workflows/test-compose.yaml +++ b/.gitea/workflows/test-compose.yaml @@ -8,7 +8,7 @@ jobs: image: docker:latest steps: - name: Installing node - run: apk add nodejs git + run: apk add nodejs git curl bash - name: Check out repository code uses: actions/checkout@v3 - name: Install Bun runtime From a09119ea4525b2e5326927efca17b98e2978bfd5 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 17:04:19 +0100 Subject: [PATCH 035/133] changed moby to docker --- .gitea/workflows/test-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test-compose.yaml b/.gitea/workflows/test-compose.yaml index 4ba542f..753aa8e 100644 --- a/.gitea/workflows/test-compose.yaml +++ b/.gitea/workflows/test-compose.yaml @@ -14,4 +14,4 @@ jobs: - name: Install Bun runtime run: curl -fsSL https://bun.sh/install | bash - name: Run docker-compose - run: moby compose down -v && moby compose run bot-api bun test \ No newline at end of file + run: ducker compose down -v && docker compose run bot-api bun test \ No newline at end of file From a4f4ebbbd2405c4748a5f4e9e13198452a9600c0 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 17:05:17 +0100 Subject: [PATCH 036/133] typo --- .gitea/workflows/test-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test-compose.yaml b/.gitea/workflows/test-compose.yaml index 753aa8e..5040055 100644 --- a/.gitea/workflows/test-compose.yaml +++ b/.gitea/workflows/test-compose.yaml @@ -14,4 +14,4 @@ jobs: - name: Install Bun runtime run: curl -fsSL https://bun.sh/install | bash - name: Run docker-compose - run: ducker compose down -v && docker compose run bot-api bun test \ No newline at end of file + run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file From 7230a08cc9ef407a7b38498aa59a502885bd516a Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 17:06:49 +0100 Subject: [PATCH 037/133] dind --- .gitea/workflows/test-compose.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/test-compose.yaml b/.gitea/workflows/test-compose.yaml index 5040055..c094113 100644 --- a/.gitea/workflows/test-compose.yaml +++ b/.gitea/workflows/test-compose.yaml @@ -5,7 +5,7 @@ on: [pull_request] jobs: unit-test: container: - image: docker:latest + image: docker:dind-latest steps: - name: Installing node run: apk add nodejs git curl bash @@ -14,4 +14,4 @@ jobs: - name: Install Bun runtime run: curl -fsSL https://bun.sh/install | bash - name: Run docker-compose - run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file + run: dind compose down -v && dind compose run bot-api bun test \ No newline at end of file From 42111a9e3034510ee744da966f443fcdd434dcfc Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 17:08:06 +0100 Subject: [PATCH 038/133] fixed dind --- .gitea/workflows/test-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test-compose.yaml b/.gitea/workflows/test-compose.yaml index c094113..06b6d5b 100644 --- a/.gitea/workflows/test-compose.yaml +++ b/.gitea/workflows/test-compose.yaml @@ -5,7 +5,7 @@ on: [pull_request] jobs: unit-test: container: - image: docker:dind-latest + image: docker:dind steps: - name: Installing node run: apk add nodejs git curl bash From 6850989f06469c849274d47dfb3ad09ee709f6c2 Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 29 Dec 2023 17:10:48 +0100 Subject: [PATCH 039/133] unified the tests in one file for port binding reasons --- src/controllers/AuthControler.ts | 1 - src/services/AuthService.ts | 2 -- tests/app.test.ts | 24 ++++++++++++++++++++- tests/auth.test.ts | 37 -------------------------------- 4 files changed, 23 insertions(+), 41 deletions(-) delete mode 100644 tests/auth.test.ts diff --git a/src/controllers/AuthControler.ts b/src/controllers/AuthControler.ts index 68c69ac..335e11a 100644 --- a/src/controllers/AuthControler.ts +++ b/src/controllers/AuthControler.ts @@ -7,7 +7,6 @@ const authTokenSecret = process.env.JWTSECRET || "badsecret"; class AuthControler { async login(req: Request, res: Response) { // Read app and secret from request body - console.log(req.body) const { app, secret } = req.body; // Filter app from the apps by app and secret diff --git a/src/services/AuthService.ts b/src/services/AuthService.ts index 9dcdabe..ac32127 100644 --- a/src/services/AuthService.ts +++ b/src/services/AuthService.ts @@ -2,9 +2,7 @@ import AuthModel, { Auth } from "../models/AuthModel"; class AuthService { async find(app: String, secret: String): Promise { - console.log(app, secret) const auth = await AuthModel.findOne({ app: app, secret: secret }); - console.log(auth) return auth; } } diff --git a/tests/app.test.ts b/tests/app.test.ts index 72a6ebc..3a116c8 100644 --- a/tests/app.test.ts +++ b/tests/app.test.ts @@ -1,5 +1,5 @@ import { afterAll, afterEach, beforeAll, describe, expect, it, mock } from "bun:test"; -import request from "supertest"; +import request, { Response } from "supertest"; import app, { startApp } from "../src/app"; import imageService from "../src/services/ImageService"; import memoryServer from "./memoryServer"; @@ -33,6 +33,28 @@ afterEach(() => { })); }); +describe("/login works as instended", async () => { + let correctRespose: Response; + beforeAll(async () => { + correctRespose = await request(app) + .post("/login") + .send({ app: "tester", secret: "test" }); + }); + + it("should return 200 for correct login", async () => { + expect(correctRespose.status).toBe(200); + }); + + it("should contain a token", () => { + expect(correctRespose.body).toHaveProperty("token"); + }); + + it("should return 403 for invalid credentials", async () => { + const res = await request(app).post("/login").send({}); + expect(res.status).toBe(403); + }); + }); + describe("GET / shows all of the endpoints", async () => { const res = await request(app).get("/"); diff --git a/tests/auth.test.ts b/tests/auth.test.ts deleted file mode 100644 index affe74f..0000000 --- a/tests/auth.test.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { afterAll, beforeAll, describe, expect, it } from "bun:test"; -import request, { Response } from "supertest"; -import app, { startApp } from "../src/app"; -import memoryServer from "./memoryServer"; -import populateDatabase from "./populateDatabase"; - -beforeAll(async () => { - if (!process.env.DEDICATED_MONGODB_SERVER) await memoryServer.start(); - await startApp(); - await populateDatabase(); -}); - -afterAll(async () => { - if (!process.env.DEDICATED_MONGODB_SERVER) await memoryServer.stop(); -}); - -describe("/login", async () => { - let correctRespose: Response; - beforeAll(async () => { - correctRespose = await request(app) - .post("/login") - .send({ app: "tester", secret: "test" }); - }); - - it("should return 200 for correct login", async () => { - expect(correctRespose.status).toBe(200); - }); - - it("should contain a token", () => { - expect(correctRespose.body).toHaveProperty("token"); - }); - - it("should return 403 for invalid credentials", async () => { - const res = await request(app).post("/login").send({}); - expect(res.status).toBe(403); - }); -}); From aca87e205b547364c27634a33f1124e81fad97c5 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 17:12:04 +0100 Subject: [PATCH 040/133] privileged --- .gitea/workflows/test-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test-compose.yaml b/.gitea/workflows/test-compose.yaml index 06b6d5b..c65a8f6 100644 --- a/.gitea/workflows/test-compose.yaml +++ b/.gitea/workflows/test-compose.yaml @@ -14,4 +14,4 @@ jobs: - name: Install Bun runtime run: curl -fsSL https://bun.sh/install | bash - name: Run docker-compose - run: dind compose down -v && dind compose run bot-api bun test \ No newline at end of file + run: dind --privileged compose down -v && dind --privileged compose run bot-api bun test \ No newline at end of file From c27ce7273a82c424876be37e6c54021a7de646ee Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 29 Dec 2023 17:20:35 +0100 Subject: [PATCH 041/133] enable debug --- package.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/package.json b/package.json index 6d9c33c..7d6fe8f 100644 --- a/package.json +++ b/package.json @@ -30,5 +30,10 @@ "express-list-endpoints": "^6.0.0", "jsonwebtoken": "^9.0.2", "mongoose": "^8.0.3" + }, + "config": { + "mongodbMemoryServer": { + "debug": "1" + } } } From 5b2196fbd907e5a8ddf79b7f47fe1158c8ec47cc Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 17:21:44 +0100 Subject: [PATCH 042/133] being root --- .gitea/workflows/test-compose.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/test-compose.yaml b/.gitea/workflows/test-compose.yaml index c65a8f6..0e4b740 100644 --- a/.gitea/workflows/test-compose.yaml +++ b/.gitea/workflows/test-compose.yaml @@ -13,5 +13,7 @@ jobs: uses: actions/checkout@v3 - name: Install Bun runtime run: curl -fsSL https://bun.sh/install | bash + - name: Be root + run: su - name: Run docker-compose - run: dind --privileged compose down -v && dind --privileged compose run bot-api bun test \ No newline at end of file + run: dind compose down -v && dind compose run bot-api bun test \ No newline at end of file From a71640dd9f3ab0e20e86b67c0fac303188df8b0a Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 17:23:02 +0100 Subject: [PATCH 043/133] rootless --- .gitea/workflows/test-compose.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.gitea/workflows/test-compose.yaml b/.gitea/workflows/test-compose.yaml index 0e4b740..f83f482 100644 --- a/.gitea/workflows/test-compose.yaml +++ b/.gitea/workflows/test-compose.yaml @@ -5,7 +5,7 @@ on: [pull_request] jobs: unit-test: container: - image: docker:dind + image: docker:dind-rootless steps: - name: Installing node run: apk add nodejs git curl bash @@ -13,7 +13,5 @@ jobs: uses: actions/checkout@v3 - name: Install Bun runtime run: curl -fsSL https://bun.sh/install | bash - - name: Be root - run: su - name: Run docker-compose run: dind compose down -v && dind compose run bot-api bun test \ No newline at end of file From 04bf90cee6f37879c66a798dd6c9544ad3c336df Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 17:29:01 +0100 Subject: [PATCH 044/133] echo --- .gitea/workflows/test-compose.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/test-compose.yaml b/.gitea/workflows/test-compose.yaml index f83f482..fb70337 100644 --- a/.gitea/workflows/test-compose.yaml +++ b/.gitea/workflows/test-compose.yaml @@ -5,8 +5,10 @@ on: [pull_request] jobs: unit-test: container: - image: docker:dind-rootless + image: docker:dind steps: + - name: echo + run: echo $DOCKER_HOST - name: Installing node run: apk add nodejs git curl bash - name: Check out repository code From c801bc448d4e18dcd0812fc7d0feefcca5460b87 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 17:31:49 +0100 Subject: [PATCH 045/133] Docker instead of dind --- .gitea/workflows/test-compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test-compose.yaml b/.gitea/workflows/test-compose.yaml index fb70337..9c7a939 100644 --- a/.gitea/workflows/test-compose.yaml +++ b/.gitea/workflows/test-compose.yaml @@ -16,4 +16,4 @@ jobs: - name: Install Bun runtime run: curl -fsSL https://bun.sh/install | bash - name: Run docker-compose - run: dind compose down -v && dind compose run bot-api bun test \ No newline at end of file + run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file From 471c84b18c93f016f6d5870c930aa34f49eeeb9b Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 17:53:29 +0100 Subject: [PATCH 046/133] Deleted not docker workflow --- .gitea/workflows/test-compose.yaml | 19 ------------------- .gitea/workflows/test.yaml | 16 +++++++++------- 2 files changed, 9 insertions(+), 26 deletions(-) delete mode 100644 .gitea/workflows/test-compose.yaml diff --git a/.gitea/workflows/test-compose.yaml b/.gitea/workflows/test-compose.yaml deleted file mode 100644 index 9c7a939..0000000 --- a/.gitea/workflows/test-compose.yaml +++ /dev/null @@ -1,19 +0,0 @@ -name: Unit Tests with docker compose -run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀 -on: [pull_request] - -jobs: - unit-test: - container: - image: docker:dind - steps: - - name: echo - run: echo $DOCKER_HOST - - name: Installing node - run: apk add nodejs git curl bash - - name: Check out repository code - uses: actions/checkout@v3 - - name: Install Bun runtime - run: curl -fsSL https://bun.sh/install | bash - - name: Run docker-compose - run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index c1746f2..9c7a939 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -1,17 +1,19 @@ -name: Unit Tests +name: Unit Tests with docker compose run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀 on: [pull_request] jobs: unit-test: container: - image: catthehacker/ubuntu:act-latest + image: docker:dind steps: + - name: echo + run: echo $DOCKER_HOST + - name: Installing node + run: apk add nodejs git curl bash - name: Check out repository code uses: actions/checkout@v3 - name: Install Bun runtime - run: curl -fsSL https://bun.sh/install | bash - - name: Install dependencies - run: ~/.bun/bin/bun install - - name: Run the test - run: ~/.bun/bin/bun test \ No newline at end of file + run: curl -fsSL https://bun.sh/install | bash + - name: Run docker-compose + run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file From 0b3081907625da038eff2bc8b71e907b022bca5a Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 17:55:36 +0100 Subject: [PATCH 047/133] dind --- .gitea/workflows/test.yaml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 9c7a939..c0253ab 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -7,13 +7,11 @@ jobs: container: image: docker:dind steps: - - name: echo - run: echo $DOCKER_HOST - - name: Installing node + - name: Installing necessary packages run: apk add nodejs git curl bash - name: Check out repository code uses: actions/checkout@v3 - name: Install Bun runtime run: curl -fsSL https://bun.sh/install | bash - name: Run docker-compose - run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file + run: dind compose down -v && dind compose run bot-api bun test \ No newline at end of file From 6efb03efbfb873c9e4ab02360722f7d9ad5f616b Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 17:59:11 +0100 Subject: [PATCH 048/133] dind-compose --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index c0253ab..c68111b 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -5,7 +5,7 @@ on: [pull_request] jobs: unit-test: container: - image: docker:dind + image: guglio/dind-compose:latest steps: - name: Installing necessary packages run: apk add nodejs git curl bash From 3526729166bcef960c2820ef5a0d4b6d0e9356b6 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 18:07:55 +0100 Subject: [PATCH 049/133] probamos --- .gitea/workflows/test.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index c68111b..c910075 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -5,7 +5,7 @@ on: [pull_request] jobs: unit-test: container: - image: guglio/dind-compose:latest + image: docker:latest steps: - name: Installing necessary packages run: apk add nodejs git curl bash @@ -14,4 +14,4 @@ jobs: - name: Install Bun runtime run: curl -fsSL https://bun.sh/install | bash - name: Run docker-compose - run: dind compose down -v && dind compose run bot-api bun test \ No newline at end of file + run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file From 511eaba5385248e347b2e3fa04c5231ea0f559b3 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 18:13:25 +0100 Subject: [PATCH 050/133] docker --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index c910075..258f841 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -5,7 +5,7 @@ on: [pull_request] jobs: unit-test: container: - image: docker:latest + image: docker:dind steps: - name: Installing necessary packages run: apk add nodejs git curl bash From e5122f59e4801329aada07ea4639536263a2575d Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 18:15:02 +0100 Subject: [PATCH 051/133] dind dind --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 258f841..fa42027 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -14,4 +14,4 @@ jobs: - name: Install Bun runtime run: curl -fsSL https://bun.sh/install | bash - name: Run docker-compose - run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file + run: dind docker compose down -v && dind docker compose run bot-api bun test \ No newline at end of file From 1c204590df8596cb7254ba3d8fecf6219dab1338 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 18:19:00 +0100 Subject: [PATCH 052/133] dind --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index fa42027..c0253ab 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -14,4 +14,4 @@ jobs: - name: Install Bun runtime run: curl -fsSL https://bun.sh/install | bash - name: Run docker-compose - run: dind docker compose down -v && dind docker compose run bot-api bun test \ No newline at end of file + run: dind compose down -v && dind compose run bot-api bun test \ No newline at end of file From 108e1793bf9a0e4909c870bd0ce0e9398007425a Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 18:26:02 +0100 Subject: [PATCH 053/133] ps --- .gitea/workflows/test.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index c0253ab..7ba87dc 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -7,6 +7,8 @@ jobs: container: image: docker:dind steps: + - name: ps + run: ps - name: Installing necessary packages run: apk add nodejs git curl bash - name: Check out repository code From b76865dadf44a43c4ace809b3216b7f4ff277421 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 18:33:20 +0100 Subject: [PATCH 054/133] docker init --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 7ba87dc..fe2615c 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -8,7 +8,7 @@ jobs: image: docker:dind steps: - name: ps - run: ps + run: docker-init -- dockerd --host=unix:///var/run/docker.sock - name: Installing necessary packages run: apk add nodejs git curl bash - name: Check out repository code From d62ed9ca18b4347b2be208740df867a3045d6922 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 18:34:15 +0100 Subject: [PATCH 055/133] & --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index fe2615c..eeefc17 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -8,7 +8,7 @@ jobs: image: docker:dind steps: - name: ps - run: docker-init -- dockerd --host=unix:///var/run/docker.sock + run: docker-init -- dockerd --host=unix:///var/run/docker.sock & - name: Installing necessary packages run: apk add nodejs git curl bash - name: Check out repository code From 18f456c83e904c42f7bab4209dcb7c9a9739fc0c Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 18:35:08 +0100 Subject: [PATCH 056/133] docker --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index eeefc17..6003096 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -16,4 +16,4 @@ jobs: - name: Install Bun runtime run: curl -fsSL https://bun.sh/install | bash - name: Run docker-compose - run: dind compose down -v && dind compose run bot-api bun test \ No newline at end of file + run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file From 006ea44a6a4386b841ff75d652d0b3d3e63de292 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 18:38:25 +0100 Subject: [PATCH 057/133] buni --- .gitea/workflows/test.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 6003096..d4fbf7b 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -13,7 +13,9 @@ jobs: run: apk add nodejs git curl bash - name: Check out repository code uses: actions/checkout@v3 - - name: Install Bun runtime + - name: Install bun runtime run: curl -fsSL https://bun.sh/install | bash + - name: Install project dependencies + run: bun install - name: Run docker-compose run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file From 15f3af264b3a20d032b60f47d296660ad80647b6 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 18:39:43 +0100 Subject: [PATCH 058/133] bun bin bun --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index d4fbf7b..3451eb2 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -16,6 +16,6 @@ jobs: - name: Install bun runtime run: curl -fsSL https://bun.sh/install | bash - name: Install project dependencies - run: bun install + run: ~/.bun/bin/bun install - name: Run docker-compose run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file From ac98daa71e9990aafac8317d6313546e35cfaa86 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 18:48:40 +0100 Subject: [PATCH 059/133] bash --- .gitea/workflows/test.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 3451eb2..390770f 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -7,7 +7,7 @@ jobs: container: image: docker:dind steps: - - name: ps + - name: Starting docker daemon run: docker-init -- dockerd --host=unix:///var/run/docker.sock & - name: Installing necessary packages run: apk add nodejs git curl bash @@ -15,7 +15,9 @@ jobs: uses: actions/checkout@v3 - name: Install bun runtime run: curl -fsSL https://bun.sh/install | bash + - name: Open a new shell + run: bash - name: Install project dependencies - run: ~/.bun/bin/bun install + run: bun install - name: Run docker-compose run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file From 0dba3d2f6fae234d627392d535ab3a3375bcc742 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 19:02:42 +0100 Subject: [PATCH 060/133] over bun --- .gitea/workflows/test.yaml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 390770f..4bb4530 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -13,11 +13,7 @@ jobs: run: apk add nodejs git curl bash - name: Check out repository code uses: actions/checkout@v3 - - name: Install bun runtime - run: curl -fsSL https://bun.sh/install | bash - - name: Open a new shell - run: bash - name: Install project dependencies - run: bun install + run: docker run over/bun:1 bun install - name: Run docker-compose run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file From 1bcf3d4590c8a2397be907536486227cbe3e4224 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 19:03:48 +0100 Subject: [PATCH 061/133] oven --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 4bb4530..3efdecb 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -14,6 +14,6 @@ jobs: - name: Check out repository code uses: actions/checkout@v3 - name: Install project dependencies - run: docker run over/bun:1 bun install + run: docker run oven/bun:1 bun install - name: Run docker-compose run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file From 6e546cc753e984a1d952c681d9fc5da16a02fbc3 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 19:07:26 +0100 Subject: [PATCH 062/133] yay --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 3efdecb..4c41e18 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -14,6 +14,6 @@ jobs: - name: Check out repository code uses: actions/checkout@v3 - name: Install project dependencies - run: docker run oven/bun:1 bun install + run: docker run -w /usr/src/app -v ./:/usr/src/app oven/bun i - name: Run docker-compose run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file From a59f288d22455251b525afb5894ba1e2094c48df Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 19:14:57 +0100 Subject: [PATCH 063/133] verbose --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 4c41e18..428e767 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -14,6 +14,6 @@ jobs: - name: Check out repository code uses: actions/checkout@v3 - name: Install project dependencies - run: docker run -w /usr/src/app -v ./:/usr/src/app oven/bun i + run: docker run -w /usr/src/app -v ./:/usr/src/app oven/bun install --verbose - name: Run docker-compose run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file From 5d2c9cd325d85752a3d977a189d57b4b37c59873 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 19:18:46 +0100 Subject: [PATCH 064/133] fixinggg --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 428e767..ac511a2 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -14,6 +14,6 @@ jobs: - name: Check out repository code uses: actions/checkout@v3 - name: Install project dependencies - run: docker run -w /usr/src/app -v ./:/usr/src/app oven/bun install --verbose + run: docker run -w /usr/src/app -v ./:/usr/src/app oven/bun:1 bun i --verbose - name: Run docker-compose run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file From 2081c2fea8230b24abe6193a748fa8b0fd5682de Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 19:24:43 +0100 Subject: [PATCH 065/133] testing with npm, also moved types to dev --- .gitea/workflows/test.yaml | 4 ++-- package.json | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index ac511a2..bdaab3f 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -10,10 +10,10 @@ jobs: - name: Starting docker daemon run: docker-init -- dockerd --host=unix:///var/run/docker.sock & - name: Installing necessary packages - run: apk add nodejs git curl bash + run: apk add nodejs git curl bash nodejs - name: Check out repository code uses: actions/checkout@v3 - name: Install project dependencies - run: docker run -w /usr/src/app -v ./:/usr/src/app oven/bun:1 bun i --verbose + run: npm install #docker run -w /usr/src/app -v ./:/usr/src/app oven/bun:1 bun i --verbose - name: Run docker-compose run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file diff --git a/package.json b/package.json index 7d6fe8f..20be423 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,10 @@ "@types/jest": "^29.5.11", "@types/mongodb-memory-server": "^2.3.0", "@types/supertest": "^6.0.1", + "@types/express": "^4.17.21", + "@types/express-list-endpoints": "^6.0.3", + "@types/jsonwebtoken": "^9.0.5", + "@types/mongoose": "^5.11.97", "bun-types": "latest", "jest": "^29.7.0", "mongodb-memory-server": "^9.1.3", @@ -22,10 +26,6 @@ "test": "docker compose down -v && docker compose run bot-api bun test" }, "dependencies": { - "@types/express": "^4.17.21", - "@types/express-list-endpoints": "^6.0.3", - "@types/jsonwebtoken": "^9.0.5", - "@types/mongoose": "^5.11.97", "express": "^4.18.2", "express-list-endpoints": "^6.0.0", "jsonwebtoken": "^9.0.2", From 8b27e2577f14d3e7f471a364b22cd299fafcfa17 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 19:25:48 +0100 Subject: [PATCH 066/133] npm --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index bdaab3f..8f326b5 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -10,7 +10,7 @@ jobs: - name: Starting docker daemon run: docker-init -- dockerd --host=unix:///var/run/docker.sock & - name: Installing necessary packages - run: apk add nodejs git curl bash nodejs + run: apk add nodejs git curl bash nodejs-npm - name: Check out repository code uses: actions/checkout@v3 - name: Install project dependencies From 49b159f9dc3748d0ef492c29d7624c839a156e57 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 19:28:38 +0100 Subject: [PATCH 067/133] node 20 --- .gitea/workflows/test.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 8f326b5..14460b3 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -10,10 +10,10 @@ jobs: - name: Starting docker daemon run: docker-init -- dockerd --host=unix:///var/run/docker.sock & - name: Installing necessary packages - run: apk add nodejs git curl bash nodejs-npm + run: apk add nodejs git curl bash - name: Check out repository code uses: actions/checkout@v3 - name: Install project dependencies - run: npm install #docker run -w /usr/src/app -v ./:/usr/src/app oven/bun:1 bun i --verbose + run: docker run -w /usr/src/app -v ./:/usr/src/app node:20 npm install - name: Run docker-compose run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file From 9cd61c101c305d4c7747e4c301c6a392fde2cb5b Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 29 Dec 2023 19:37:35 +0100 Subject: [PATCH 068/133] fmt, purged useless deps and removed mongoMS --- package.json | 7 - src/app.ts | 40 ++--- src/controllers/ImageController.ts | 8 +- src/index.ts | 10 +- src/models/AuthModel.ts | 23 +-- src/models/ImageModel.ts | 37 ++-- tests/app.test.ts | 272 +++++++++++++++-------------- tests/memoryServer.ts | 2 +- tests/populateDatabase.ts | 18 +- 9 files changed, 208 insertions(+), 209 deletions(-) diff --git a/package.json b/package.json index 20be423..0432e6b 100644 --- a/package.json +++ b/package.json @@ -4,12 +4,10 @@ "type": "module", "devDependencies": { "@types/jest": "^29.5.11", - "@types/mongodb-memory-server": "^2.3.0", "@types/supertest": "^6.0.1", "@types/express": "^4.17.21", "@types/express-list-endpoints": "^6.0.3", "@types/jsonwebtoken": "^9.0.5", - "@types/mongoose": "^5.11.97", "bun-types": "latest", "jest": "^29.7.0", "mongodb-memory-server": "^9.1.3", @@ -30,10 +28,5 @@ "express-list-endpoints": "^6.0.0", "jsonwebtoken": "^9.0.2", "mongoose": "^8.0.3" - }, - "config": { - "mongodbMemoryServer": { - "debug": "1" - } } } diff --git a/src/app.ts b/src/app.ts index e132aa4..43a3f6f 100644 --- a/src/app.ts +++ b/src/app.ts @@ -18,24 +18,24 @@ app.post("/images", authControler.authorize, imageController.addImage); app.post("/login", authControler.login); export const startApp = async () => { - const port = process.env.PORT || 8080; - const mongo_uri: string = process.env.MONGODB_URI || ""; - const mongo_user = process.env.MONGODB_USER; - const mongo_pass = process.env.MONGODB_PASS; - - try { - await mongoose.connect(mongo_uri, { - authSource: "admin", - user: mongo_user, - pass: mongo_pass, - }); - app.listen(port, () => - console.log(`Express server listening on port ${port}`) - ); - } catch (error) { - console.error(error); - process.exit(1); - } - }; + const port = process.env.PORT || 8080; + const mongo_uri: string = process.env.MONGODB_URI || ""; + const mongo_user = process.env.MONGODB_USER; + const mongo_pass = process.env.MONGODB_PASS; -export default app; \ No newline at end of file + try { + await mongoose.connect(mongo_uri, { + authSource: "admin", + user: mongo_user, + pass: mongo_pass, + }); + app.listen(port, () => + console.log(`Express server listening on port ${port}`) + ); + } catch (error) { + console.error(error); + process.exit(1); + } +}; + +export default app; diff --git a/src/controllers/ImageController.ts b/src/controllers/ImageController.ts index 1b86aea..e60bfea 100644 --- a/src/controllers/ImageController.ts +++ b/src/controllers/ImageController.ts @@ -23,11 +23,9 @@ class ImageController { } catch (error: any) { if (error instanceof mongo.MongoServerError && error.code === 11000) { // Should return 409 Conflict for existing urls - res - .status(409) - .json({ - error: `the image with URL ${error.keyValue.url} already exists`, - }); + res.status(409).json({ + error: `the image with URL ${error.keyValue.url} already exists`, + }); } else if (error instanceof mongoose.Error.ValidationError) { // Should return 400 Bad request for invalid requests res.status(400).json({ error: error.message }); diff --git a/src/index.ts b/src/index.ts index 7155635..4f8ee9f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,10 +3,6 @@ import { startApp } from "./app"; await startApp(); - -try{ - await populateDatabase(); -} -catch { - -} \ No newline at end of file +try { + await populateDatabase(); +} catch {} diff --git a/src/models/AuthModel.ts b/src/models/AuthModel.ts index 96ce5e5..8c4a94f 100644 --- a/src/models/AuthModel.ts +++ b/src/models/AuthModel.ts @@ -5,16 +5,19 @@ export interface Auth extends Document { secret: String; } -const AuthSchema = new mongoose.Schema({ - app: { - type: String, - required: true, - index: true, +const AuthSchema = new mongoose.Schema( + { + app: { + type: String, + required: true, + index: true, + }, + secret: { + type: String, + required: true, + }, }, - secret: { - type: String, - required: true, - }, -}, { collection: "authorizations" }); + { collection: "authorizations" } +); export default mongoose.model("authorizations", AuthSchema); diff --git a/src/models/ImageModel.ts b/src/models/ImageModel.ts index b3bff2c..f2baa49 100644 --- a/src/models/ImageModel.ts +++ b/src/models/ImageModel.ts @@ -6,24 +6,27 @@ export interface Image extends Document { tags?: String[]; } -const ImageSchema = new mongoose.Schema({ - url: { - type: String, - required: true, - index: true, - unique: true - }, - status: { - type: String, - enum: { - values: ["consumed", "unavailable", "available"], +const ImageSchema = new mongoose.Schema( + { + url: { + type: String, + required: true, + index: true, + unique: true, + }, + status: { + type: String, + enum: { + values: ["consumed", "unavailable", "available"], + }, + required: true, + index: true, + }, + tags: { + type: [String], }, - required: true, - index: true, }, - tags: { - type: [String], - }, -}, { collection: "images" }); + { collection: "images" } +); export default mongoose.model("images", ImageSchema); diff --git a/tests/app.test.ts b/tests/app.test.ts index 3a116c8..0e8fbda 100644 --- a/tests/app.test.ts +++ b/tests/app.test.ts @@ -1,4 +1,12 @@ -import { afterAll, afterEach, beforeAll, describe, expect, it, mock } from "bun:test"; +import { + afterAll, + afterEach, + beforeAll, + describe, + expect, + it, + mock, +} from "bun:test"; import request, { Response } from "supertest"; import app, { startApp } from "../src/app"; import imageService from "../src/services/ImageService"; @@ -10,164 +18,162 @@ const imageServiceOriginal = imageService; let token: string; beforeAll(async () => { - if (!process.env.DEDICATED_MONGODB_SERVER) - await memoryServer.start(); - await startApp(); - await populateDatabase(); + //if (!process.env.DEDICATED_MONGODB_SERVER) await memoryServer.start(); + await startApp(); + await populateDatabase(); - const tok = await request(app) - .post("/login") - .send({ app: "tester", secret: "test" }); - token = tok.body.token; + const tok = await request(app) + .post("/login") + .send({ app: "tester", secret: "test" }); + token = tok.body.token; }); -afterAll(async () => { - if (!process.env.DEDICATED_MONGODB_SERVER) - await memoryServer.stop(); -}) - +/* afterAll(async () => { + if (!process.env.DEDICATED_MONGODB_SERVER) await memoryServer.stop(); +}); + */ afterEach(() => { - mock.restore(); - mock.module("../src/services/ImageService", () => ({ - default: imageServiceOriginal, - })); + mock.restore(); + mock.module("../src/services/ImageService", () => ({ + default: imageServiceOriginal, + })); }); describe("/login works as instended", async () => { - let correctRespose: Response; - beforeAll(async () => { - correctRespose = await request(app) - .post("/login") - .send({ app: "tester", secret: "test" }); - }); - - it("should return 200 for correct login", async () => { - expect(correctRespose.status).toBe(200); - }); - - it("should contain a token", () => { - expect(correctRespose.body).toHaveProperty("token"); - }); - - it("should return 403 for invalid credentials", async () => { - const res = await request(app).post("/login").send({}); - expect(res.status).toBe(403); - }); - }); + let correctRespose: Response; + beforeAll(async () => { + correctRespose = await request(app) + .post("/login") + .send({ app: "tester", secret: "test" }); + }); + + it("should return 200 for correct login", async () => { + expect(correctRespose.status).toBe(200); + }); + + it("should contain a token", () => { + expect(correctRespose.body).toHaveProperty("token"); + }); + + it("should return 403 for invalid credentials", async () => { + const res = await request(app).post("/login").send({}); + expect(res.status).toBe(403); + }); +}); describe("GET / shows all of the endpoints", async () => { - const res = await request(app).get("/"); + const res = await request(app).get("/"); - it("should be", async () => { - expect(res.body).toHaveProperty("endpoints"); - }); + it("should be", async () => { + expect(res.body).toHaveProperty("endpoints"); + }); - it("should be an array", () => { - expect(Array.isArray(res.body.endpoints)).toBeTrue(); - }); + it("should be an array", () => { + expect(Array.isArray(res.body.endpoints)).toBeTrue(); + }); }); describe("GET /images works properly", async () => { - const res = await request(app).get("/images"); + const res = await request(app).get("/images"); - it("should be an array", () => { - expect(Array.isArray(res.body.images)).toBeTrue(); - }); + it("should be an array", () => { + expect(Array.isArray(res.body.images)).toBeTrue(); + }); - it("should return a 200", async () => { - expect(res.statusCode).toBe(200); - }); + it("should return a 200", async () => { + expect(res.statusCode).toBe(200); + }); }); describe("POST /images works properly", () => { - it("should return 401 for unauthenticated requests", async () => { - const res = await request(app) - .post("/images") - .send({ - url: "https://test.url.com/0", - status: "available", - tags: ["2girls", "touhou"], - }); - expect(res.status).toBe(401); - }); + it("should return 401 for unauthenticated requests", async () => { + const res = await request(app) + .post("/images") + .send({ + url: "https://test.url.com/0", + status: "available", + tags: ["2girls", "touhou"], + }); + expect(res.status).toBe(401); + }); - it("should return 403 for invalid tokens", async () => { - const res = await request(app) - .post("/images") - .set("authorization", `Bearer token`) - .send({ - url: "https://test.url.com/0", - status: "available", - tags: ["2girls", "touhou"], - }); - expect(res.status).toBe(403); - }); + it("should return 403 for invalid tokens", async () => { + const res = await request(app) + .post("/images") + .set("authorization", `Bearer token`) + .send({ + url: "https://test.url.com/0", + status: "available", + tags: ["2girls", "touhou"], + }); + expect(res.status).toBe(403); + }); - it("should return 201 for new image", async () => { - const res = await request(app) - .post("/images") - .set("authorization", `Bearer ${token}`) - .send({ - url: "https://test.url.com/1", - status: "available", - tags: ["2girls", "touhou"], - }); - expect(res.status).toBe(201); - }); + it("should return 201 for new image", async () => { + const res = await request(app) + .post("/images") + .set("authorization", `Bearer ${token}`) + .send({ + url: "https://test.url.com/1", + status: "available", + tags: ["2girls", "touhou"], + }); + expect(res.status).toBe(201); + }); - it("should return 409 for a repeated images", async () => { - await request(app) - .post("/images") - .set("authorization", `Bearer ${token}`) - .send({ - url: "https://test.url.com/2", - status: "available", - tags: ["2girls", "touhou"], - }); + it("should return 409 for a repeated images", async () => { + await request(app) + .post("/images") + .set("authorization", `Bearer ${token}`) + .send({ + url: "https://test.url.com/2", + status: "available", + tags: ["2girls", "touhou"], + }); - const res = await request(app) - .post("/images") - .set("authorization", `Bearer ${token}`) - .send({ - url: "https://test.url.com/2", - status: "available", - tags: ["2girls", "touhou"], - }); + const res = await request(app) + .post("/images") + .set("authorization", `Bearer ${token}`) + .send({ + url: "https://test.url.com/2", + status: "available", + tags: ["2girls", "touhou"], + }); - expect(res.status).toBe(409); - }); + expect(res.status).toBe(409); + }); - it("should return 500 for an error on the service", async () => { - mock.module("../src/services/ImageService", () => ({ - default: { - add: () => { - throw new Error("This is an expected testing error"); - }, - }, - })); + it("should return 500 for an error on the service", async () => { + mock.module("../src/services/ImageService", () => ({ + default: { + add: () => { + throw new Error("This is an expected testing error"); + }, + }, + })); - const res = await request(app) - .post("/images") - .set("authorization", `Bearer ${token}`) - .send({ - url: "https://test.url.com/3", - status: "available", - tags: ["2girls", "touhou"], - }); + const res = await request(app) + .post("/images") + .set("authorization", `Bearer ${token}`) + .send({ + url: "https://test.url.com/3", + status: "available", + tags: ["2girls", "touhou"], + }); - expect(res.status).toBe(500); - }); + expect(res.status).toBe(500); + }); - it("should return 400 for malformed requests", async () => { - mock.restore(); - const res = await request(app) - .post("/images") - .set("authorization", `Bearer ${token}`) - .send({ - url: "https://test.url.com/4", - status: "wrong", - tags: ["2girls", "touhou"], - }); - expect(res.status).toBe(400); - }); + it("should return 400 for malformed requests", async () => { + mock.restore(); + const res = await request(app) + .post("/images") + .set("authorization", `Bearer ${token}`) + .send({ + url: "https://test.url.com/4", + status: "wrong", + tags: ["2girls", "touhou"], + }); + expect(res.status).toBe(400); + }); }); diff --git a/tests/memoryServer.ts b/tests/memoryServer.ts index 8dd7513..a7e6e5c 100644 --- a/tests/memoryServer.ts +++ b/tests/memoryServer.ts @@ -16,4 +16,4 @@ class MemoryServer { } } -export default new MemoryServer(); \ No newline at end of file +export default new MemoryServer(); diff --git a/tests/populateDatabase.ts b/tests/populateDatabase.ts index 93f63c1..f60c9c4 100644 --- a/tests/populateDatabase.ts +++ b/tests/populateDatabase.ts @@ -2,14 +2,14 @@ import authModel from "../src/models/AuthModel"; import imageModel from "../src/models/ImageModel"; export default async function () { - await imageModel.create({ - url: "https://example.com", - status: "consumed", - tags: ["2girls", "sleeping"], - }); + await imageModel.create({ + url: "https://example.com", + status: "consumed", + tags: ["2girls", "sleeping"], + }); - await authModel.create({ - app: "tester", - secret: "test", - }); + await authModel.create({ + app: "tester", + secret: "test", + }); } From 76d576461624d18c233b4fa5a9d1914f26339aa9 Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 29 Dec 2023 19:47:35 +0100 Subject: [PATCH 069/133] added test coverage to image controler --- src/controllers/ImageController.ts | 2 +- tests/app.test.ts | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/controllers/ImageController.ts b/src/controllers/ImageController.ts index e60bfea..8c78e99 100644 --- a/src/controllers/ImageController.ts +++ b/src/controllers/ImageController.ts @@ -3,7 +3,7 @@ import imageService from "../services/ImageService"; import mongoose, { mongo } from "mongoose"; class ImageController { - async getAllImages(req: Request, res: Response): Promise { + async getAllImages(_: Request, res: Response): Promise { try { const images = await imageService.findAll(); res.json({ images }); diff --git a/tests/app.test.ts b/tests/app.test.ts index 0e8fbda..7d8fbb9 100644 --- a/tests/app.test.ts +++ b/tests/app.test.ts @@ -83,6 +83,21 @@ describe("GET /images works properly", async () => { it("should return a 200", async () => { expect(res.statusCode).toBe(200); }); + + it("should return 500 for an error on the service", async () => { + mock.module("../src/services/ImageService", () => ({ + default: { + add: () => { + throw new Error("This is an expected testing error"); + }, + }, + })); + + const res = await request(app) + .get("/images"); + + expect(res.status).toBe(500); + }); }); describe("POST /images works properly", () => { From 6561c710ff3951d31b667b671884b7b1490bcb45 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 19:54:56 +0100 Subject: [PATCH 070/133] Deleted DEDICATED_MONGO_SERVER env variable --- compose.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/compose.yaml b/compose.yaml index 2ca513c..9ffce94 100644 --- a/compose.yaml +++ b/compose.yaml @@ -27,8 +27,6 @@ services: MONGODB_USER: "root" MONGODB_PASS: "password" JWTSECRET: "cooljwtsecret" - # DEDICATED_MONGODB_SERVER is for integration testing, for disabling memory server in tests - DEDICATED_MONGODB_SERVER: "true" volumes: - ./:/usr/src/app:ro From cabe730ab8fcf179d4df852ae6735b30ea48b894 Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 20:10:36 +0100 Subject: [PATCH 071/133] Testing adding MONGO_URL as env var --- compose.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/compose.yaml b/compose.yaml index 9ffce94..b45561f 100644 --- a/compose.yaml +++ b/compose.yaml @@ -24,6 +24,7 @@ services: - mongodb environment: MONGODB_URI: "mongodb://mongodb:27017/bot" + MONGO_URL: "mongodb://mongodb:27017/bot" MONGODB_USER: "root" MONGODB_PASS: "password" JWTSECRET: "cooljwtsecret" From 6bb187305ad8eeb8568818ed74a47dae2eb2ccdf Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 20:22:27 +0100 Subject: [PATCH 072/133] undid last commit --- compose.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/compose.yaml b/compose.yaml index b45561f..9ffce94 100644 --- a/compose.yaml +++ b/compose.yaml @@ -24,7 +24,6 @@ services: - mongodb environment: MONGODB_URI: "mongodb://mongodb:27017/bot" - MONGO_URL: "mongodb://mongodb:27017/bot" MONGODB_USER: "root" MONGODB_PASS: "password" JWTSECRET: "cooljwtsecret" From 640514af6dc4b199f8325ee69f7fac041c487e6a Mon Sep 17 00:00:00 2001 From: Sugui Date: Fri, 29 Dec 2023 22:01:23 +0100 Subject: [PATCH 073/133] ping --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 14460b3..1a4ddc5 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -16,4 +16,4 @@ jobs: - name: Install project dependencies run: docker run -w /usr/src/app -v ./:/usr/src/app node:20 npm install - name: Run docker-compose - run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file + run: docker compose down -v && docker compose run bot-api ping mongodb \ No newline at end of file From d368c6bed0136085b17ee81e09caea06de80b89b Mon Sep 17 00:00:00 2001 From: Sugui Date: Sun, 31 Dec 2023 11:31:28 +0100 Subject: [PATCH 074/133] change to mongo:bionic to support the runner on pi --- compose.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compose.yaml b/compose.yaml index 9ffce94..30088de 100644 --- a/compose.yaml +++ b/compose.yaml @@ -2,7 +2,7 @@ version: "3" services: mongodb: - image: mongo + image: mongo:bionic container_name: mongodb ports: - "27017:27017" From 7fc78c0a036909d3a358712e79f1096bef8f00a7 Mon Sep 17 00:00:00 2001 From: Sugui Date: Sun, 31 Dec 2023 11:31:46 +0100 Subject: [PATCH 075/133] Added bun again to install dependencies in action --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 1a4ddc5..227b55b 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -14,6 +14,6 @@ jobs: - name: Check out repository code uses: actions/checkout@v3 - name: Install project dependencies - run: docker run -w /usr/src/app -v ./:/usr/src/app node:20 npm install + run: docker run -w /usr/src/app -v ./:/usr/src/app oven/bun:1 bun install - name: Run docker-compose run: docker compose down -v && docker compose run bot-api ping mongodb \ No newline at end of file From e1ced40c065014599a8b8cb523f08f366eacc236 Mon Sep 17 00:00:00 2001 From: Sugui Date: Sun, 31 Dec 2023 11:36:38 +0100 Subject: [PATCH 076/133] monothread and verbose on bun install --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 227b55b..b237d6a 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -14,6 +14,6 @@ jobs: - name: Check out repository code uses: actions/checkout@v3 - name: Install project dependencies - run: docker run -w /usr/src/app -v ./:/usr/src/app oven/bun:1 bun install + run: docker run -w /usr/src/app -v ./:/usr/src/app oven/bun:1 bun install --verbose --concurrent-scripts 1 - name: Run docker-compose run: docker compose down -v && docker compose run bot-api ping mongodb \ No newline at end of file From ec1b6935387267d29c8a4ba4b99f8900fa0ed856 Mon Sep 17 00:00:00 2001 From: Sugui Date: Sun, 31 Dec 2023 11:42:19 +0100 Subject: [PATCH 077/133] Removed mongodb-memory-server --- package.json | 5 ++--- tests/app.test.ts | 7 ------- tests/memoryServer.ts | 19 ------------------- 3 files changed, 2 insertions(+), 29 deletions(-) delete mode 100644 tests/memoryServer.ts diff --git a/package.json b/package.json index 0432e6b..e11f4b4 100644 --- a/package.json +++ b/package.json @@ -3,14 +3,13 @@ "module": "index.ts", "type": "module", "devDependencies": { - "@types/jest": "^29.5.11", - "@types/supertest": "^6.0.1", "@types/express": "^4.17.21", "@types/express-list-endpoints": "^6.0.3", + "@types/jest": "^29.5.11", "@types/jsonwebtoken": "^9.0.5", + "@types/supertest": "^6.0.1", "bun-types": "latest", "jest": "^29.7.0", - "mongodb-memory-server": "^9.1.3", "supertest": "^6.3.3", "ts-jest": "^29.1.1" }, diff --git a/tests/app.test.ts b/tests/app.test.ts index 7d8fbb9..f8f7652 100644 --- a/tests/app.test.ts +++ b/tests/app.test.ts @@ -1,5 +1,4 @@ import { - afterAll, afterEach, beforeAll, describe, @@ -10,7 +9,6 @@ import { import request, { Response } from "supertest"; import app, { startApp } from "../src/app"; import imageService from "../src/services/ImageService"; -import memoryServer from "./memoryServer"; import populateDatabase from "./populateDatabase"; const imageServiceOriginal = imageService; @@ -18,7 +16,6 @@ const imageServiceOriginal = imageService; let token: string; beforeAll(async () => { - //if (!process.env.DEDICATED_MONGODB_SERVER) await memoryServer.start(); await startApp(); await populateDatabase(); @@ -28,10 +25,6 @@ beforeAll(async () => { token = tok.body.token; }); -/* afterAll(async () => { - if (!process.env.DEDICATED_MONGODB_SERVER) await memoryServer.stop(); -}); - */ afterEach(() => { mock.restore(); mock.module("../src/services/ImageService", () => ({ diff --git a/tests/memoryServer.ts b/tests/memoryServer.ts deleted file mode 100644 index a7e6e5c..0000000 --- a/tests/memoryServer.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { MongoMemoryServer } from "mongodb-memory-server"; - -class MemoryServer { - mongod: MongoMemoryServer | undefined; - - async start() { - this.mongod = await MongoMemoryServer.create(); - const uri = this.mongod.getUri("bot"); - process.env.MONGODB_URI = uri; - } - - async stop() { - if (this.mongod) { - await this.mongod.stop(); - } - } -} - -export default new MemoryServer(); From 5941fcc1f2c56f7c7faa45f770f1937089223d50 Mon Sep 17 00:00:00 2001 From: Sugui Date: Sun, 31 Dec 2023 11:44:25 +0100 Subject: [PATCH 078/133] added node again --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index b237d6a..1a4ddc5 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -14,6 +14,6 @@ jobs: - name: Check out repository code uses: actions/checkout@v3 - name: Install project dependencies - run: docker run -w /usr/src/app -v ./:/usr/src/app oven/bun:1 bun install --verbose --concurrent-scripts 1 + run: docker run -w /usr/src/app -v ./:/usr/src/app node:20 npm install - name: Run docker-compose run: docker compose down -v && docker compose run bot-api ping mongodb \ No newline at end of file From 199f06db433305cbb87283959018a8cc72d97be2 Mon Sep 17 00:00:00 2001 From: Sugui Date: Sun, 31 Dec 2023 11:54:46 +0100 Subject: [PATCH 079/133] Now install packages without using a container, and fixed the ping thing --- .gitea/workflows/test.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 1a4ddc5..7c64ca0 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -10,10 +10,10 @@ jobs: - name: Starting docker daemon run: docker-init -- dockerd --host=unix:///var/run/docker.sock & - name: Installing necessary packages - run: apk add nodejs git curl bash + run: apk add npm git curl bash - name: Check out repository code uses: actions/checkout@v3 - name: Install project dependencies - run: docker run -w /usr/src/app -v ./:/usr/src/app node:20 npm install + run: npm install - name: Run docker-compose - run: docker compose down -v && docker compose run bot-api ping mongodb \ No newline at end of file + run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file From 98f9c5bf8e12a144cb66143c6a2e22665086aceb Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 31 Dec 2023 12:01:21 +0100 Subject: [PATCH 080/133] deleted a console log --- src/controllers/ImageController.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/controllers/ImageController.ts b/src/controllers/ImageController.ts index 8c78e99..75fca37 100644 --- a/src/controllers/ImageController.ts +++ b/src/controllers/ImageController.ts @@ -8,7 +8,6 @@ class ImageController { const images = await imageService.findAll(); res.json({ images }); } catch (error) { - console.error(error); res.status(500).json({ error: "Internal Server Error" }); } } From a59f951500ecf8ef58a66e33bd127ed71cb6a554 Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 31 Dec 2023 11:11:22 +0000 Subject: [PATCH 081/133] unit testing (#7) Co-authored-by: Sugui Reviewed-on: https://git.fai.st/fedi-image-bot/bot-api/pulls/7 Co-authored-by: Alie Co-committed-by: Alie --- .gitea/workflows/test.yaml | 22 +++++----- compose.yaml | 3 +- mongo-init.js | 30 ------------- package.json | 7 ++-- src/app.ts | 41 ++++++++++++++++++ src/controllers/AuthControler.ts | 2 +- src/controllers/ImageController.ts | 11 ++--- src/index.ts | 46 +++----------------- src/models/AuthModel.ts | 22 ++++++---- src/models/ImageModel.ts | 34 ++++++++------- src/services/AuthService.ts | 2 +- tests/app.test.ts | 67 ++++++++++++++++++++++++++---- tests/auth.test.ts | 21 ---------- tests/populateDatabase.ts | 15 +++++++ 14 files changed, 176 insertions(+), 147 deletions(-) delete mode 100644 mongo-init.js create mode 100644 src/app.ts delete mode 100644 tests/auth.test.ts create mode 100644 tests/populateDatabase.ts diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 0cca8ee..7c64ca0 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -1,19 +1,19 @@ -name: Gitea Actions Demo +name: Unit Tests with docker compose run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀 on: [pull_request] jobs: - Explore-Gitea-Actions: + unit-test: container: - image: oven/bun:1 + image: docker:dind steps: - - run: echo "🎉 The job was automatically triggered by a ${{ gitea.event_name }} event." - - run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by Gitea!" - - run: echo "🔎 The name of your branch is ${{ gitea.ref }} and your repository is ${{ gitea.repository }}." + - name: Starting docker daemon + run: docker-init -- dockerd --host=unix:///var/run/docker.sock & + - name: Installing necessary packages + run: apk add npm git curl bash - name: Check out repository code uses: actions/checkout@v3 - - run: echo "💡 The ${{ gitea.repository }} repository has been cloned to the runner." - - run: echo "🖥️ The workflow is now ready to test your code on the runner." - - name: List files in the repository - run: | - ls ${{ gitea.workspace }} \ No newline at end of file + - name: Install project dependencies + run: npm install + - name: Run docker-compose + run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file diff --git a/compose.yaml b/compose.yaml index 964794b..30088de 100644 --- a/compose.yaml +++ b/compose.yaml @@ -2,7 +2,7 @@ version: "3" services: mongodb: - image: mongo + image: mongo:bionic container_name: mongodb ports: - "27017:27017" @@ -12,7 +12,6 @@ services: MONGO_INITDB_DATABASE: bot volumes: - mongodb_data:/data/db - - ./mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro bot-api: image: oven/bun:1 diff --git a/mongo-init.js b/mongo-init.js deleted file mode 100644 index 67b53c9..0000000 --- a/mongo-init.js +++ /dev/null @@ -1,30 +0,0 @@ -db.createUser({ - user: "root", - pwd: "password", - roles: [ - { - role: "readWrite", - db: "admin", - }, - { - role: "readWrite", - db: "bot", - }, - ], -}); - -db = new Mongo().getDB("bot"); - -db.images.createIndex({ status: 1 }); -db.images.createIndex({ url: 1 }, { unique: true }); -db.images.insert({ - url: "https://example.com", - status: "consumed", - tags: ["2girls", "sleeping"], -}); - -db.authorizations.createIndex({ app: 1 }); -db.authorizations.insert({ - app: "tester", - secret: "test", -}); diff --git a/package.json b/package.json index 2080221..e11f4b4 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,10 @@ "module": "index.ts", "type": "module", "devDependencies": { + "@types/express": "^4.17.21", + "@types/express-list-endpoints": "^6.0.3", "@types/jest": "^29.5.11", + "@types/jsonwebtoken": "^9.0.5", "@types/supertest": "^6.0.1", "bun-types": "latest", "jest": "^29.7.0", @@ -20,10 +23,6 @@ "test": "docker compose down -v && docker compose run bot-api bun test" }, "dependencies": { - "@types/express": "^4.17.21", - "@types/express-list-endpoints": "^6.0.3", - "@types/jsonwebtoken": "^9.0.5", - "@types/mongoose": "^5.11.97", "express": "^4.18.2", "express-list-endpoints": "^6.0.0", "jsonwebtoken": "^9.0.2", diff --git a/src/app.ts b/src/app.ts new file mode 100644 index 0000000..43a3f6f --- /dev/null +++ b/src/app.ts @@ -0,0 +1,41 @@ +import express from "express"; +import listEndpoints from "express-list-endpoints"; +import imageController from "./controllers/ImageController"; +import authControler from "./controllers/AuthControler"; +import mongoose from "mongoose"; + +export const app = express(); + +app.use(express.json()); + +app.get("/", (_, res) => { + const endpoints = listEndpoints(app); + res.json({ endpoints }); +}); + +app.get("/images", imageController.getAllImages); +app.post("/images", authControler.authorize, imageController.addImage); +app.post("/login", authControler.login); + +export const startApp = async () => { + const port = process.env.PORT || 8080; + const mongo_uri: string = process.env.MONGODB_URI || ""; + const mongo_user = process.env.MONGODB_USER; + const mongo_pass = process.env.MONGODB_PASS; + + try { + await mongoose.connect(mongo_uri, { + authSource: "admin", + user: mongo_user, + pass: mongo_pass, + }); + app.listen(port, () => + console.log(`Express server listening on port ${port}`) + ); + } catch (error) { + console.error(error); + process.exit(1); + } +}; + +export default app; diff --git a/src/controllers/AuthControler.ts b/src/controllers/AuthControler.ts index 4f0649c..335e11a 100644 --- a/src/controllers/AuthControler.ts +++ b/src/controllers/AuthControler.ts @@ -13,7 +13,7 @@ class AuthControler { const authenticated = await AuthService.find(app, secret); if (authenticated) { - console.log("Authenticated app ", authenticated.app); + console.log("Authenticated app", authenticated.app); // Generate an access token const accessToken = jwt.sign( { app: authenticated.app }, diff --git a/src/controllers/ImageController.ts b/src/controllers/ImageController.ts index 1b86aea..75fca37 100644 --- a/src/controllers/ImageController.ts +++ b/src/controllers/ImageController.ts @@ -3,12 +3,11 @@ import imageService from "../services/ImageService"; import mongoose, { mongo } from "mongoose"; class ImageController { - async getAllImages(req: Request, res: Response): Promise { + async getAllImages(_: Request, res: Response): Promise { try { const images = await imageService.findAll(); res.json({ images }); } catch (error) { - console.error(error); res.status(500).json({ error: "Internal Server Error" }); } } @@ -23,11 +22,9 @@ class ImageController { } catch (error: any) { if (error instanceof mongo.MongoServerError && error.code === 11000) { // Should return 409 Conflict for existing urls - res - .status(409) - .json({ - error: `the image with URL ${error.keyValue.url} already exists`, - }); + res.status(409).json({ + error: `the image with URL ${error.keyValue.url} already exists`, + }); } else if (error instanceof mongoose.Error.ValidationError) { // Should return 400 Bad request for invalid requests res.status(400).json({ error: error.message }); diff --git a/src/index.ts b/src/index.ts index d74231b..4f8ee9f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,42 +1,8 @@ -import express from "express"; -import mongoose from "mongoose"; -import listEndpoints from "express-list-endpoints"; -import imageController from "./controllers/ImageController"; -import authControler from "./controllers/AuthControler"; +import populateDatabase from "../tests/populateDatabase"; +import { startApp } from "./app"; -export const app = express(); +await startApp(); -app.use(express.json()); - -app.get("/", (_, res) => { - const endpoints = listEndpoints(app); - res.json({ endpoints }); -}); - -app.get("/images", imageController.getAllImages); -app.post("/images", authControler.authorize, imageController.addImage); -app.post("/login", authControler.login); - -const start = async () => { - // Set the default port to 8080, or use the PORT environment variable - const port = process.env.PORT || 8080; - const mongo_uri: string = process.env.MONGODB_URI || ""; - const mongo_user = process.env.MONGODB_USER; - const mongo_pass = process.env.MONGODB_PASS; - - try { - await mongoose.connect(mongo_uri, { - authSource: "admin", - user: mongo_user, - pass: mongo_pass, - }); - app.listen(port, () => - console.log(`Express server listening on port ${port}`) - ); - } catch (error) { - console.error(error); - process.exit(1); - } -}; - -start(); +try { + await populateDatabase(); +} catch {} diff --git a/src/models/AuthModel.ts b/src/models/AuthModel.ts index df71afe..8c4a94f 100644 --- a/src/models/AuthModel.ts +++ b/src/models/AuthModel.ts @@ -5,15 +5,19 @@ export interface Auth extends Document { secret: String; } -const AuthSchema = new mongoose.Schema({ - app: { - type: String, - required: true, +const AuthSchema = new mongoose.Schema( + { + app: { + type: String, + required: true, + index: true, + }, + secret: { + type: String, + required: true, + }, }, - secret: { - type: String, - required: true, - }, -}); + { collection: "authorizations" } +); export default mongoose.model("authorizations", AuthSchema); diff --git a/src/models/ImageModel.ts b/src/models/ImageModel.ts index d91ab18..f2baa49 100644 --- a/src/models/ImageModel.ts +++ b/src/models/ImageModel.ts @@ -6,21 +6,27 @@ export interface Image extends Document { tags?: String[]; } -const ImageSchema = new mongoose.Schema({ - url: { - type: String, - required: true, - }, - status: { - type: String, - enum: { - values: ["consumed", "unavailable", "available"], +const ImageSchema = new mongoose.Schema( + { + url: { + type: String, + required: true, + index: true, + unique: true, + }, + status: { + type: String, + enum: { + values: ["consumed", "unavailable", "available"], + }, + required: true, + index: true, + }, + tags: { + type: [String], }, - required: true, }, - tags: { - type: [String], - }, -}); + { collection: "images" } +); export default mongoose.model("images", ImageSchema); diff --git a/src/services/AuthService.ts b/src/services/AuthService.ts index aed8d12..ac32127 100644 --- a/src/services/AuthService.ts +++ b/src/services/AuthService.ts @@ -2,7 +2,7 @@ import AuthModel, { Auth } from "../models/AuthModel"; class AuthService { async find(app: String, secret: String): Promise { - const auth = await AuthModel.findOne({ app: app, secret: secret }).exec(); + const auth = await AuthModel.findOne({ app: app, secret: secret }); return auth; } } diff --git a/tests/app.test.ts b/tests/app.test.ts index ac40ace..f8f7652 100644 --- a/tests/app.test.ts +++ b/tests/app.test.ts @@ -1,13 +1,29 @@ -import { afterEach, beforeAll, describe, expect, it, mock } from "bun:test"; -import request from "supertest"; -import { app } from "../src"; +import { + afterEach, + beforeAll, + describe, + expect, + it, + mock, +} from "bun:test"; +import request, { Response } from "supertest"; +import app, { startApp } from "../src/app"; import imageService from "../src/services/ImageService"; +import populateDatabase from "./populateDatabase"; const imageServiceOriginal = imageService; -const tok = await request(app) - .post("/login") - .send({ app: "tester", secret: "test" }); -const token = tok.body.token; + +let token: string; + +beforeAll(async () => { + await startApp(); + await populateDatabase(); + + const tok = await request(app) + .post("/login") + .send({ app: "tester", secret: "test" }); + token = tok.body.token; +}); afterEach(() => { mock.restore(); @@ -16,6 +32,28 @@ afterEach(() => { })); }); +describe("/login works as instended", async () => { + let correctRespose: Response; + beforeAll(async () => { + correctRespose = await request(app) + .post("/login") + .send({ app: "tester", secret: "test" }); + }); + + it("should return 200 for correct login", async () => { + expect(correctRespose.status).toBe(200); + }); + + it("should contain a token", () => { + expect(correctRespose.body).toHaveProperty("token"); + }); + + it("should return 403 for invalid credentials", async () => { + const res = await request(app).post("/login").send({}); + expect(res.status).toBe(403); + }); +}); + describe("GET / shows all of the endpoints", async () => { const res = await request(app).get("/"); @@ -38,6 +76,21 @@ describe("GET /images works properly", async () => { it("should return a 200", async () => { expect(res.statusCode).toBe(200); }); + + it("should return 500 for an error on the service", async () => { + mock.module("../src/services/ImageService", () => ({ + default: { + add: () => { + throw new Error("This is an expected testing error"); + }, + }, + })); + + const res = await request(app) + .get("/images"); + + expect(res.status).toBe(500); + }); }); describe("POST /images works properly", () => { diff --git a/tests/auth.test.ts b/tests/auth.test.ts deleted file mode 100644 index bd20cd2..0000000 --- a/tests/auth.test.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { describe, expect, it, mock } from "bun:test"; -import request from "supertest"; -import { app } from "../src"; - -describe("/login", async () => { - const correctRespose = await request(app).post("/login").send({ - app: "tester", - secret: "test", - }); - it("should return 200 for correct login", () => { - expect(correctRespose.status).toBe(200); - }); - it("should contain a token", () => { - expect(correctRespose.body).toHaveProperty("token"); - }); - - it("should return 403 for invalid credentials", async () => { - const res = await request(app).post("/login").send({}); - expect(res.status).toBe(403); - }); -}); diff --git a/tests/populateDatabase.ts b/tests/populateDatabase.ts new file mode 100644 index 0000000..f60c9c4 --- /dev/null +++ b/tests/populateDatabase.ts @@ -0,0 +1,15 @@ +import authModel from "../src/models/AuthModel"; +import imageModel from "../src/models/ImageModel"; + +export default async function () { + await imageModel.create({ + url: "https://example.com", + status: "consumed", + tags: ["2girls", "sleeping"], + }); + + await authModel.create({ + app: "tester", + secret: "test", + }); +} From 106c1b8726bfdedb0fa594505f89f8ba411f1644 Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 31 Dec 2023 12:29:31 +0100 Subject: [PATCH 082/133] fmt --- tests/app.test.ts | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/tests/app.test.ts b/tests/app.test.ts index f8f7652..4893ae0 100644 --- a/tests/app.test.ts +++ b/tests/app.test.ts @@ -1,11 +1,4 @@ -import { - afterEach, - beforeAll, - describe, - expect, - it, - mock, -} from "bun:test"; +import { afterEach, beforeAll, describe, expect, it, mock } from "bun:test"; import request, { Response } from "supertest"; import app, { startApp } from "../src/app"; import imageService from "../src/services/ImageService"; @@ -86,8 +79,7 @@ describe("GET /images works properly", async () => { }, })); - const res = await request(app) - .get("/images"); + const res = await request(app).get("/images"); expect(res.status).toBe(500); }); From e75bb6d8d980688e578a70336eff57db9613cf84 Mon Sep 17 00:00:00 2001 From: Sugui Date: Sun, 31 Dec 2023 13:10:24 +0100 Subject: [PATCH 083/133] cmd --- .gitea/workflows/test.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 7c64ca0..fc5d666 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -6,9 +6,8 @@ jobs: unit-test: container: image: docker:dind + cmd: "" steps: - - name: Starting docker daemon - run: docker-init -- dockerd --host=unix:///var/run/docker.sock & - name: Installing necessary packages run: apk add npm git curl bash - name: Check out repository code From b6d966dc2ea83bc64bf2b3ef01aff9350791f31f Mon Sep 17 00:00:00 2001 From: Sugui Date: Sun, 31 Dec 2023 13:16:41 +0100 Subject: [PATCH 084/133] Revert "cmd" This reverts commit e75bb6d8d980688e578a70336eff57db9613cf84. --- .gitea/workflows/test.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index fc5d666..7c64ca0 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -6,8 +6,9 @@ jobs: unit-test: container: image: docker:dind - cmd: "" steps: + - name: Starting docker daemon + run: docker-init -- dockerd --host=unix:///var/run/docker.sock & - name: Installing necessary packages run: apk add npm git curl bash - name: Check out repository code From 265761766f3d8542ba095e1bb181aae5913eb597 Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 31 Dec 2023 13:26:10 +0100 Subject: [PATCH 085/133] made the dockerfile usable to our usecase --- Dockerfile | 21 ++++----------------- src/index.ts | 6 +++++- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/Dockerfile b/Dockerfile index 7ecabac..2314c7c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,33 +8,20 @@ WORKDIR /usr/src/app # install dependencies into temp folder # this will cache them and speed up future builds FROM base AS install -RUN mkdir -p /temp/dev -COPY package.json bun.lockb /temp/dev/ -RUN cd /temp/dev && bun install # install with --production (exclude devDependencies) RUN mkdir -p /temp/prod COPY package.json bun.lockb /temp/prod/ RUN cd /temp/prod && bun install --production -# copy node_modules from temp folder -# then copy all (non-ignored) project files into the image -FROM install AS prerelease -COPY --from=install /temp/dev/node_modules node_modules -COPY . . - -# [optional] tests & build -# ENV NODE_ENV=production -# RUN bun test -# RUN bun run build - -# copy production dependencies and source code into final image +# Copy production dependencies and source code into final image FROM base AS release COPY --from=install /temp/prod/node_modules node_modules -COPY --from=prerelease /usr/src/app/index.ts . -COPY --from=prerelease /usr/src/app/package.json . +COPY --from=install /usr/src/app/src ./src +COPY --from=install /usr/src/app/package.json . # run the app USER bun +ENV NODE_ENV=production EXPOSE 8080/tcp CMD ["bun", "run", "start"] diff --git a/src/index.ts b/src/index.ts index 4f8ee9f..0d016b7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,6 +3,10 @@ import { startApp } from "./app"; await startApp(); +// This try carch is to prevent hot reload from making the process die due to coliding entries try { - await populateDatabase(); + // Not insert test data into production + if (process.env.NODE_ENV != "production"){ + await populateDatabase(); + } } catch {} From 810fd2aed1cd0d7248d2aac8a3baf6e4d4683323 Mon Sep 17 00:00:00 2001 From: Sugui Date: Mon, 1 Jan 2024 15:59:36 +0100 Subject: [PATCH 086/133] Testing docker-init in container's cmd parameter --- .gitea/workflows/test.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 7c64ca0..6d0427f 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -6,9 +6,8 @@ jobs: unit-test: container: image: docker:dind + cmd: "docker-init -- dockerd --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2376 --tlsverify --tlscacert /certs/server/ca.pem --tlscert /certs" steps: - - name: Starting docker daemon - run: docker-init -- dockerd --host=unix:///var/run/docker.sock & - name: Installing necessary packages run: apk add npm git curl bash - name: Check out repository code From dd9999de916ef15f165174d30f65bd2805f2a71e Mon Sep 17 00:00:00 2001 From: Sugui Date: Mon, 1 Jan 2024 16:01:44 +0100 Subject: [PATCH 087/133] Adding & to the cmd command --- .gitea/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 6d0427f..2e5e19d 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -6,7 +6,7 @@ jobs: unit-test: container: image: docker:dind - cmd: "docker-init -- dockerd --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2376 --tlsverify --tlscacert /certs/server/ca.pem --tlscert /certs" + cmd: "docker-init -- dockerd --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2376 --tlsverify --tlscacert /certs/server/ca.pem --tlscert /certs &" steps: - name: Installing necessary packages run: apk add npm git curl bash From e5c5ef51d5bf4338d0c6cf66db4e2f2b91cb3f10 Mon Sep 17 00:00:00 2001 From: Sugui Date: Mon, 1 Jan 2024 16:04:19 +0100 Subject: [PATCH 088/133] Removing cmd --- .gitea/workflows/test.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 2e5e19d..e5acb4f 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -6,7 +6,6 @@ jobs: unit-test: container: image: docker:dind - cmd: "docker-init -- dockerd --host=unix:///var/run/docker.sock --host=tcp://0.0.0.0:2376 --tlsverify --tlscacert /certs/server/ca.pem --tlscert /certs &" steps: - name: Installing necessary packages run: apk add npm git curl bash From 57a79c1e37447b88a34774f6cb99abd40b8398de Mon Sep 17 00:00:00 2001 From: Sugui Date: Mon, 1 Jan 2024 16:12:24 +0100 Subject: [PATCH 089/133] Addind docker:dind service --- .gitea/workflows/test.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index e5acb4f..fe70425 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -6,6 +6,8 @@ jobs: unit-test: container: image: docker:dind + services: + - docker:dind steps: - name: Installing necessary packages run: apk add npm git curl bash From 6cd2b09c1372d512ab0e894a4a4ea514f2952252 Mon Sep 17 00:00:00 2001 From: Sugui Date: Mon, 1 Jan 2024 16:18:14 +0100 Subject: [PATCH 090/133] Changing things to see if service works --- .gitea/workflows/test.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index fe70425..1c19ffb 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -5,10 +5,12 @@ on: [pull_request] jobs: unit-test: container: - image: docker:dind + image: docker services: - docker:dind steps: + - name: ps + run: ps - name: Installing necessary packages run: apk add npm git curl bash - name: Check out repository code From cda0b2485160d749e1a1a4e9a67452fd047a95ae Mon Sep 17 00:00:00 2001 From: Sugui Date: Mon, 1 Jan 2024 16:34:17 +0100 Subject: [PATCH 091/133] Restored initial working workflow --- .gitea/workflows/test.yaml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 1c19ffb..7c64ca0 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -5,12 +5,10 @@ on: [pull_request] jobs: unit-test: container: - image: docker - services: - - docker:dind + image: docker:dind steps: - - name: ps - run: ps + - name: Starting docker daemon + run: docker-init -- dockerd --host=unix:///var/run/docker.sock & - name: Installing necessary packages run: apk add npm git curl bash - name: Check out repository code From df99e9470c709ef81a4df4591415d7fa48c4459b Mon Sep 17 00:00:00 2001 From: Alie Date: Wed, 3 Jan 2024 13:58:18 +0100 Subject: [PATCH 092/133] added the images/id endpoint and the tests for it --- src/app.ts | 1 + src/controllers/ImageController.ts | 17 +++++++++++++++++ src/services/ImageService.ts | 4 ++++ tests/app.test.ts | 23 +++++++++++++++++++++++ 4 files changed, 45 insertions(+) diff --git a/src/app.ts b/src/app.ts index 43a3f6f..8ae7edd 100644 --- a/src/app.ts +++ b/src/app.ts @@ -14,6 +14,7 @@ app.get("/", (_, res) => { }); app.get("/images", imageController.getAllImages); +app.get("/images/:id", imageController.getImageById); app.post("/images", authControler.authorize, imageController.addImage); app.post("/login", authControler.login); diff --git a/src/controllers/ImageController.ts b/src/controllers/ImageController.ts index 75fca37..4b2301e 100644 --- a/src/controllers/ImageController.ts +++ b/src/controllers/ImageController.ts @@ -3,6 +3,23 @@ import imageService from "../services/ImageService"; import mongoose, { mongo } from "mongoose"; class ImageController { + async getImageById(req: Request, res: Response) { + try { + const image = await imageService.findById(req.params.id); + if (image) { + res.json({ image }); + } else { + res.status(404).json({ error: "Image not found" }); + } + } catch (error: any) { + if (error instanceof mongoose.Error.CastError) { + res.status(400).json({ error: "Invalid Id" }); + } else { + res.status(500).json({ error: "Internal Server Error" }); + } + } + } + async getAllImages(_: Request, res: Response): Promise { try { const images = await imageService.findAll(); diff --git a/src/services/ImageService.ts b/src/services/ImageService.ts index 8691f7d..8289ed5 100644 --- a/src/services/ImageService.ts +++ b/src/services/ImageService.ts @@ -1,6 +1,10 @@ import imageModel, { Image } from "../models/ImageModel"; class ImageService { + async findById(id: string) { + const image = await imageModel.findOne({ _id: id }); + return image; + } async findAll(): Promise { const allImages = await imageModel.find(); return allImages; diff --git a/tests/app.test.ts b/tests/app.test.ts index 4893ae0..91987dd 100644 --- a/tests/app.test.ts +++ b/tests/app.test.ts @@ -177,3 +177,26 @@ describe("POST /images works properly", () => { expect(res.status).toBe(400); }); }); + +describe("/images/:id works properly", () => { + it("should return 200 for existing ids", async () => { + const list = await request(app).get("/images"); + const id = list.body.images[0]._id; + const res = await request(app).get(`/images/${id}`); + expect(res.status).toBe(200); + }); + + it("should return 404 for non-existing ids", async () => { + const list = await request(app).get("/images"); + const id = "000000000000000000000000"; // this was the least posible to exist ID + if (!(id in list.body.images)) { + const res = await request(app).get(`/images/${id}`); + expect(res.status).toBe(404); + } + }); + + it("should return 400 for malformed ids", async () => { + const res = await request(app).get("/images/98439384"); + expect(res.status).toBe(400); + }); +}); From d9e2cb3917ffac229b0853ade0153891cd3e0fbe Mon Sep 17 00:00:00 2001 From: Alie Date: Sat, 6 Jan 2024 11:23:55 +0100 Subject: [PATCH 093/133] edited workflow --- .gitea/workflows/test.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 7c64ca0..73e2e08 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -1,5 +1,4 @@ name: Unit Tests with docker compose -run-name: ${{ gitea.actor }} is testing out Gitea Actions 🚀 on: [pull_request] jobs: From f74a0f26cc4ec006e9ac4d55ba4ed7e497f9efbd Mon Sep 17 00:00:00 2001 From: Alie Date: Sat, 6 Jan 2024 12:24:30 +0100 Subject: [PATCH 094/133] made the endpoint, works with manual tests --- src/app.ts | 1 + src/controllers/ImageController.ts | 29 +++++++++++++++++++++++++++++ src/services/ImageService.ts | 4 ++++ 3 files changed, 34 insertions(+) diff --git a/src/app.ts b/src/app.ts index 8ae7edd..9c985eb 100644 --- a/src/app.ts +++ b/src/app.ts @@ -15,6 +15,7 @@ app.get("/", (_, res) => { app.get("/images", imageController.getAllImages); app.get("/images/:id", imageController.getImageById); +app.put("/images/:id", imageController.editImage) app.post("/images", authControler.authorize, imageController.addImage); app.post("/login", authControler.login); diff --git a/src/controllers/ImageController.ts b/src/controllers/ImageController.ts index 4b2301e..ac1c207 100644 --- a/src/controllers/ImageController.ts +++ b/src/controllers/ImageController.ts @@ -1,8 +1,37 @@ import { Request, Response } from "express"; import imageService from "../services/ImageService"; import mongoose, { mongo } from "mongoose"; +import { Image } from "../models/ImageModel"; class ImageController { + async editImage(req: Request, res: Response) { + try { + const change: Image = req.body; + const result = await imageService.replaceOne(req.params.id, change); + if (result.matchedCount > 0) { + res.status(204).json(); + } else { + res.status(404).json({ error: "Image not found" }); + } + } catch (error: any) { + if (error instanceof mongoose.Error.CastError) { + res.status(400).json({ error: "Invalid Id" }); + } else if ( + error instanceof mongo.MongoServerError && + error.code === 11000 + ) { + // Should return 409 Conflict for existing urls + res.status(409).json({ + error: `the image with URL ${error.keyValue.url} already exists`, + }); + } else if (error instanceof mongoose.Error.ValidationError) { + // Should return 400 Bad request for invalid requests + res.status(400).json({ error: error.message }); + } else { + res.status(500).json({ error: "Internal Server Error" }); + } + } + } async getImageById(req: Request, res: Response) { try { const image = await imageService.findById(req.params.id); diff --git a/src/services/ImageService.ts b/src/services/ImageService.ts index 8289ed5..c4b6f7a 100644 --- a/src/services/ImageService.ts +++ b/src/services/ImageService.ts @@ -1,6 +1,10 @@ import imageModel, { Image } from "../models/ImageModel"; class ImageService { + async replaceOne(id: string, newimage: Image) { + const image = await imageModel.updateOne({ _id: id }, newimage); + return image; + } async findById(id: string) { const image = await imageModel.findOne({ _id: id }); return image; From 26311992d396611c67e6eaef24402646a1a06b74 Mon Sep 17 00:00:00 2001 From: Suguivy Date: Sat, 6 Jan 2024 11:43:21 +0000 Subject: [PATCH 095/133] Documentation for some API endpoints --- README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/README.md b/README.md index 87f9bbc..d4c7f57 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,33 @@ # bot-api +## Introduction +The function of the API is basically to access the images' metadata stored in the database. + +## Usage +The API exposes some endpoints to interact with the database. + +### GET `/images` +Allows to get a list of image documents. + +#### Query params +- `limit`: an optional parameter, which accepts a non-negative integer that dictates the number of documents that the list will have. If its value is equal to `0`, or if this parameter is missing, the endpoint will return all the image documents in the database. +- `status`: an optional parameter, which accepts the values `consumed`, `available` and `unavailable`. It filters the documents that have only the `status` attribute equal to that indicated in the parameter's value. If the parameter is missing, no filter will be applied to the document. + +#### Example +- `GET /images?limit=5&status=available`: will return 5 documents that have the `available` value in their `status` attribute. + +### PUT `/images/` +Modifies an existing image document. The request must provide a JSON-formatted body, with one or more valid document attributes. The existing document attributes will be replaced with the provided new ones. + +#### Params +- `id`: the id of the document to be modified. + +#### Example +- `PUT /images/61f7e48f0c651345677b7775` with body `{ "status": "consumed" }`: will modify the document referenced by the `id` param, changing their `status` value to `consumed`. + +### POST `/images` +### POST `/login` +## Installation To install dependencies: ```bash From ebf2ec17d134707b35891b47dec4926b9cfa556b Mon Sep 17 00:00:00 2001 From: Alie Date: Sat, 6 Jan 2024 12:57:22 +0100 Subject: [PATCH 096/133] added tests and auth to PUT images --- src/app.ts | 3 +- src/controllers/ImageController.ts | 6 +- src/index.ts | 2 +- src/services/ImageService.ts | 4 +- tests/app.test.ts | 89 +++++++++++++++++++++++++++++- 5 files changed, 96 insertions(+), 8 deletions(-) diff --git a/src/app.ts b/src/app.ts index 9c985eb..e76640e 100644 --- a/src/app.ts +++ b/src/app.ts @@ -15,7 +15,7 @@ app.get("/", (_, res) => { app.get("/images", imageController.getAllImages); app.get("/images/:id", imageController.getImageById); -app.put("/images/:id", imageController.editImage) +app.put("/images/:id", authControler.authorize, imageController.editImage); app.post("/images", authControler.authorize, imageController.addImage); app.post("/login", authControler.login); @@ -31,6 +31,7 @@ export const startApp = async () => { user: mongo_user, pass: mongo_pass, }); + mongoose.set("runValidators", true); app.listen(port, () => console.log(`Express server listening on port ${port}`) ); diff --git a/src/controllers/ImageController.ts b/src/controllers/ImageController.ts index ac1c207..47cc0ae 100644 --- a/src/controllers/ImageController.ts +++ b/src/controllers/ImageController.ts @@ -16,6 +16,9 @@ class ImageController { } catch (error: any) { if (error instanceof mongoose.Error.CastError) { res.status(400).json({ error: "Invalid Id" }); + } else if (error instanceof mongoose.Error.ValidationError) { + // Should return 400 Bad request for invalid requests + res.status(400).json({ error: error.message }); } else if ( error instanceof mongo.MongoServerError && error.code === 11000 @@ -24,9 +27,6 @@ class ImageController { res.status(409).json({ error: `the image with URL ${error.keyValue.url} already exists`, }); - } else if (error instanceof mongoose.Error.ValidationError) { - // Should return 400 Bad request for invalid requests - res.status(400).json({ error: error.message }); } else { res.status(500).json({ error: "Internal Server Error" }); } diff --git a/src/index.ts b/src/index.ts index 0d016b7..b431ebd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,7 +6,7 @@ await startApp(); // This try carch is to prevent hot reload from making the process die due to coliding entries try { // Not insert test data into production - if (process.env.NODE_ENV != "production"){ + if (process.env.NODE_ENV != "production") { await populateDatabase(); } } catch {} diff --git a/src/services/ImageService.ts b/src/services/ImageService.ts index c4b6f7a..257ef77 100644 --- a/src/services/ImageService.ts +++ b/src/services/ImageService.ts @@ -2,8 +2,8 @@ import imageModel, { Image } from "../models/ImageModel"; class ImageService { async replaceOne(id: string, newimage: Image) { - const image = await imageModel.updateOne({ _id: id }, newimage); - return image; + const result = await imageModel.updateOne({ _id: id }, newimage); + return result; } async findById(id: string) { const image = await imageModel.findOne({ _id: id }); diff --git a/tests/app.test.ts b/tests/app.test.ts index 91987dd..befa85a 100644 --- a/tests/app.test.ts +++ b/tests/app.test.ts @@ -3,6 +3,7 @@ import request, { Response } from "supertest"; import app, { startApp } from "../src/app"; import imageService from "../src/services/ImageService"; import populateDatabase from "./populateDatabase"; +import { Image } from "../src/models/ImageModel"; const imageServiceOriginal = imageService; @@ -178,7 +179,7 @@ describe("POST /images works properly", () => { }); }); -describe("/images/:id works properly", () => { +describe("GET /images/ works properly", () => { it("should return 200 for existing ids", async () => { const list = await request(app).get("/images"); const id = list.body.images[0]._id; @@ -200,3 +201,89 @@ describe("/images/:id works properly", () => { expect(res.status).toBe(400); }); }); + +describe("PUT /images/ works properly", () => { + let id: string; + let list: Image[]; + beforeAll(async () => { + const res = await request(app).get("/images"); + list = res.body.images; + id = list[0]._id; + }); + + it("should return 204 for valid modifications", async () => { + const res = await request(app) + .put(`/images/${id}`) + .set("authorization", `Bearer ${token}`) + .send({ status: "available" }); + expect(res.status).toBe(204); + }); + + it("should return 404 for non-existing ids", async () => { + const id = "000000000000000000000000"; // this was the least posible to exist ID + if (!(id in list)) { + const res = await request(app) + .put(`/images/${id}`) + .set("authorization", `Bearer ${token}`) + .send({ status: "available" }); + expect(res.status).toBe(404); + } + }); + + it("should return 400 for malformed ids", async () => { + const res = await request(app) + .put("/images/98439384") + .set("authorization", `Bearer ${token}`) + .send({ status: "available" }); + expect(res.status).toBe(400); + expect(res.body).toEqual({ error: "Invalid Id" }); + }); + + it("should return 400 for malformed requests", async () => { + const res = await request(app) + .put(`/images/${id}`) + .set("authorization", `Bearer ${token}`) + .send({ status: "wrong" }); + expect(res.status).toBe(400); + }); + + it("should return 409 if we try to modify the url into an existing one", async () => { + const res = await request(app) + .put(`/images/${id}`) + .set("authorization", `Bearer ${token}`) + .send({ url: "https://test.url.com/2" }); + expect(res.status).toBe(409); + }); + + it("should return 500 for an error on the service", async () => { + mock.module("../src/services/ImageService", () => ({ + default: { + replaceOne: () => { + throw new Error("This is an expected testing error"); + }, + }, + })); + + const res = await request(app) + .put(`/images/${id}`) + .set("authorization", `Bearer ${token}`) + .send({ status: "available" }); + + expect(res.status).toBe(500); + }); + + it("should return 401 for unauthenticated requests", async () => { + const res = await request(app) + .put(`/images/${id}`) + .send({ status: "available" }); + expect(res.status).toBe(401); + }); + + it("should return 403 for invalid tokens", async () => { + const res = await request(app) + .put(`/images/${id}`) + .set("authorization", `Bearer token`) + .send({ status: "available" }); + expect(res.status).toBe(403); + }); +}); From fb2d9479133a86ab65893e2a12f9f8e35be7dd56 Mon Sep 17 00:00:00 2001 From: Alie Date: Sat, 6 Jan 2024 13:10:45 +0100 Subject: [PATCH 097/133] added a functional test and optimized a test --- tests/app.test.ts | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/tests/app.test.ts b/tests/app.test.ts index befa85a..d62ee1c 100644 --- a/tests/app.test.ts +++ b/tests/app.test.ts @@ -166,7 +166,6 @@ describe("POST /images works properly", () => { }); it("should return 400 for malformed requests", async () => { - mock.restore(); const res = await request(app) .post("/images") .set("authorization", `Bearer ${token}`) @@ -180,17 +179,22 @@ describe("POST /images works properly", () => { }); describe("GET /images/ works properly", () => { + let id: string; + let list: Image[]; + beforeAll(async () => { + const res = await request(app).get("/images"); + list = res.body.images; + id = list[0]._id; + }); + it("should return 200 for existing ids", async () => { - const list = await request(app).get("/images"); - const id = list.body.images[0]._id; const res = await request(app).get(`/images/${id}`); expect(res.status).toBe(200); }); it("should return 404 for non-existing ids", async () => { - const list = await request(app).get("/images"); const id = "000000000000000000000000"; // this was the least posible to exist ID - if (!(id in list.body.images)) { + if (!(id in list)) { const res = await request(app).get(`/images/${id}`); expect(res.status).toBe(404); } @@ -286,4 +290,23 @@ describe("PUT /images/ works properly", () => { .send({ status: "available" }); expect(res.status).toBe(403); }); + + it("should have its changes be reflected onto the DB", async () => { + const image = await request(app) + .post("/images") + .set("authorization", `Bearer ${token}`) + .send({ + url: "https://test.url.com/5", + status: "available", + tags: ["2girls", "touhou"], + }); + const id = image.body.image._id; + await request(app) + .put(`/images/${id}`) + .set("authorization", `Bearer ${token}`) + .send({ status: "consumed" }); + + const res = await request(app).get(`/images/${id}`); + expect(res.body.image).toHaveProperty("status", "consumed"); + }) }); From 1e1823443720f7ca9a0c4550dddd4ff1ff874b47 Mon Sep 17 00:00:00 2001 From: Sugui Date: Sat, 6 Jan 2024 13:25:24 +0100 Subject: [PATCH 098/133] Added fake data for testing and dev environment --- package.json | 1 + tests/populateDatabase.ts | 20 ++++++++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index e11f4b4..95c8a32 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "module": "index.ts", "type": "module", "devDependencies": { + "@faker-js/faker": "^8.3.1", "@types/express": "^4.17.21", "@types/express-list-endpoints": "^6.0.3", "@types/jest": "^29.5.11", diff --git a/tests/populateDatabase.ts b/tests/populateDatabase.ts index f60c9c4..89e604b 100644 --- a/tests/populateDatabase.ts +++ b/tests/populateDatabase.ts @@ -1,12 +1,20 @@ import authModel from "../src/models/AuthModel"; -import imageModel from "../src/models/ImageModel"; +import imageModel, { Image } from "../src/models/ImageModel"; +import { faker } from '@faker-js/faker'; export default async function () { - await imageModel.create({ - url: "https://example.com", - status: "consumed", - tags: ["2girls", "sleeping"], - }); + const images = faker.helpers.multiple(() => ({ + url: faker.helpers.unique(faker.internet.url), + status: faker.helpers.arrayElement(["available", "unavailable", "consumed"]), + tags: faker.helpers.arrayElements([ + "2girls", "sleeping", "touhou", + "pokemon", "closed_eyes", "yume_nikki", + "waifu", "computer", "party", "yuru_camp" + ], { min: 0, max: 5 }), + }), {count: {min: 5, max:50}}); + + // Wait until all images are inserted + await Promise.allSettled(images.map(image => imageModel.create(image))); await authModel.create({ app: "tester", From e015500057dce2d1457047db5c09d50fa81071c2 Mon Sep 17 00:00:00 2001 From: Alie Date: Sat, 6 Jan 2024 13:43:37 +0100 Subject: [PATCH 099/133] changed the action to use cache --- .gitea/workflows/test.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 73e2e08..65dd6e2 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -5,6 +5,8 @@ jobs: unit-test: container: image: docker:dind + volumes: + - /var/lib/docker:/var/lib/docker steps: - name: Starting docker daemon run: docker-init -- dockerd --host=unix:///var/run/docker.sock & From cf03c90c4680587c4810b3e9893c2d3d321c4ff6 Mon Sep 17 00:00:00 2001 From: Alie Date: Sat, 6 Jan 2024 18:57:40 +0000 Subject: [PATCH 100/133] changed the action to use cache (#19) Reviewed-on: https://git.fai.st/fedi-image-bot/bot-api/pulls/19 Co-authored-by: Alie Co-committed-by: Alie --- .gitea/workflows/test.yaml | 8 +- README.md | 5 +- bunfig.toml | 4 + package.json | 2 +- yarn.lock | 3052 ++++++++++++++++++++++++++++++++++++ 5 files changed, 3065 insertions(+), 6 deletions(-) create mode 100644 bunfig.toml create mode 100644 yarn.lock diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 73e2e08..2b656bd 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -5,14 +5,18 @@ jobs: unit-test: container: image: docker:dind + volumes: + - /usr/local/share/.cache/yarn:/usr/local/share/.cache/yarn + - /var/lib/docker/image:/var/lib/docker/image + - /var/lib/docker/overlay2:/var/lib/docker/overlay2 steps: - name: Starting docker daemon run: docker-init -- dockerd --host=unix:///var/run/docker.sock & - name: Installing necessary packages - run: apk add npm git curl bash + run: apk add yarn git curl bash - name: Check out repository code uses: actions/checkout@v3 - name: Install project dependencies - run: npm install + run: yarn install --frozen-lockfile --ignore-scripts - name: Run docker-compose run: docker compose down -v && docker compose run bot-api bun test \ No newline at end of file diff --git a/README.md b/README.md index d4c7f57..62f16e5 100644 --- a/README.md +++ b/README.md @@ -37,13 +37,12 @@ bun install To run: ```bash -docker compose up +bun run dev ``` For testing, remember: ```bash -docker compose down -v -docker compose run bot-api bun run test +bun run test ``` This project was created using `bun init` in bun v1.0.13. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. diff --git a/bunfig.toml b/bunfig.toml new file mode 100644 index 0000000..252e66d --- /dev/null +++ b/bunfig.toml @@ -0,0 +1,4 @@ +[install.lockfile] +# whether to save a non-Bun lockfile alongside bun.lockb +# only "yarn" is supported +print = "yarn" diff --git a/package.json b/package.json index 95c8a32..9e10900 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "fib-api", + "name": "bot-api", "module": "index.ts", "type": "module", "devDependencies": { diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..1cf8075 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,3052 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 +# bun ./bun.lockb --hash: 738A3B3B61512E75-26d27a9609e246ac-33059F282FFA6348-27fd5707ca8843fa + + +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5": + version "7.23.5" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz" + integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== + dependencies: + "@babel/highlight" "^7.23.4" + chalk "^2.4.2" + +"@babel/compat-data@^7.23.5": + version "7.23.5" + resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz" + integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== + +"@babel/core@>=7.0.0-beta.0 <8", "@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.8.0": + version "7.23.7" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz" + integrity sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.6" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helpers" "^7.23.7" + "@babel/parser" "^7.23.6" + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.7" + "@babel/types" "^7.23.6" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/generator@^7.23.6", "@babel/generator@^7.7.2": + version "7.23.6" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz" + integrity sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw== + dependencies: + "@babel/types" "^7.23.6" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + +"@babel/helper-compilation-targets@^7.23.6": + version "7.23.6" + resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz" + integrity sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ== + dependencies: + "@babel/compat-data" "^7.23.5" + "@babel/helper-validator-option" "^7.23.5" + browserslist "^4.22.2" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== + +"@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== + dependencies: + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" + +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-imports@^7.22.15": + version "7.22.15" + resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz" + integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== + dependencies: + "@babel/types" "^7.22.15" + +"@babel/helper-module-transforms@^7.23.3": + version "7.23.3" + resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz" + integrity sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.20" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.23.4": + version "7.23.4" + resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz" + integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== + +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + +"@babel/helper-validator-option@^7.23.5": + version "7.23.5" + resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz" + integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== + +"@babel/helpers@^7.23.7": + version "7.23.7" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.7.tgz" + integrity sha512-6AMnjCoC8wjqBzDHkuqpa7jAKwvMo4dC+lr/TFBz+ucfulO1XMpDnwWPGBNwClOKZ8h6xn5N81W/R5OrcKtCbQ== + dependencies: + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.7" + "@babel/types" "^7.23.6" + +"@babel/highlight@^7.23.4": + version "7.23.4" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz" + integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.23.6": + version "7.23.6" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz" + integrity sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ== + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.13" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-import-meta@^7.8.3": + version "7.10.4" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@^7.7.2": + version "7.23.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz" + integrity sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": + version "7.10.4" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.10.4" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.14.5" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-typescript@^7.7.2": + version "7.23.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz" + integrity sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/template@^7.22.15", "@babel/template@^7.3.3": + version "7.22.15" + resolved "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz" + integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/parser" "^7.22.15" + "@babel/types" "^7.22.15" + +"@babel/traverse@^7.23.7": + version "7.23.7" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz" + integrity sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg== + dependencies: + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.6" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.23.6" + "@babel/types" "^7.23.6" + debug "^4.3.1" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.6", "@babel/types@^7.3.3": + version "7.23.6" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz" + integrity sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg== + dependencies: + "@babel/helper-string-parser" "^7.23.4" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + +"@faker-js/faker@^8.3.1": + version "8.3.1" + resolved "https://registry.npmjs.org/@faker-js/faker/-/faker-8.3.1.tgz" + integrity sha512-FdgpFxY6V6rLZE9mmIBb9hM0xpfvQOSNOLnzolzKwsE1DH+gC7lEKV1p1IbR0lAYyvYd5a4u3qWJzowUkw1bIw== + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/console@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz" + integrity sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + slash "^3.0.0" + +"@jest/core@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz" + integrity sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg== + dependencies: + "@jest/console" "^29.7.0" + "@jest/reporters" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + ci-info "^3.2.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^29.7.0" + jest-config "^29.7.0" + jest-haste-map "^29.7.0" + jest-message-util "^29.7.0" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-resolve-dependencies "^29.7.0" + jest-runner "^29.7.0" + jest-runtime "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + jest-watcher "^29.7.0" + micromatch "^4.0.4" + pretty-format "^29.7.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz" + integrity sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw== + dependencies: + "@jest/fake-timers" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + jest-mock "^29.7.0" + +"@jest/expect@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz" + integrity sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ== + dependencies: + expect "^29.7.0" + jest-snapshot "^29.7.0" + +"@jest/expect-utils@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz" + integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA== + dependencies: + jest-get-type "^29.6.3" + +"@jest/fake-timers@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz" + integrity sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ== + dependencies: + "@jest/types" "^29.6.3" + "@sinonjs/fake-timers" "^10.0.2" + "@types/node" "*" + jest-message-util "^29.7.0" + jest-mock "^29.7.0" + jest-util "^29.7.0" + +"@jest/globals@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz" + integrity sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/expect" "^29.7.0" + "@jest/types" "^29.6.3" + jest-mock "^29.7.0" + +"@jest/reporters@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz" + integrity sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@jridgewell/trace-mapping" "^0.3.18" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^6.0.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + jest-worker "^29.7.0" + slash "^3.0.0" + string-length "^4.0.1" + strip-ansi "^6.0.0" + v8-to-istanbul "^9.0.1" + +"@jest/schemas@^29.6.3": + version "29.6.3" + resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz" + integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== + dependencies: + "@sinclair/typebox" "^0.27.8" + +"@jest/source-map@^29.6.3": + version "29.6.3" + resolved "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz" + integrity sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw== + dependencies: + "@jridgewell/trace-mapping" "^0.3.18" + callsites "^3.0.0" + graceful-fs "^4.2.9" + +"@jest/test-result@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz" + integrity sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA== + dependencies: + "@jest/console" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz" + integrity sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw== + dependencies: + "@jest/test-result" "^29.7.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + slash "^3.0.0" + +"@jest/transform@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz" + integrity sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw== + dependencies: + "@babel/core" "^7.11.6" + "@jest/types" "^29.6.3" + "@jridgewell/trace-mapping" "^0.3.18" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^2.0.0" + fast-json-stable-stringify "^2.1.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + jest-regex-util "^29.6.3" + jest-util "^29.7.0" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + write-file-atomic "^4.0.2" + +"@jest/types@^29.0.0", "@jest/types@^29.6.3": + version "29.6.3" + resolved "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz" + integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== + dependencies: + "@jest/schemas" "^29.6.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.20" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz" + integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@mongodb-js/saslprep@^1.1.0": + version "1.1.1" + resolved "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.1.tgz" + integrity sha512-t7c5K033joZZMspnHg/gWPE4kandgc2OxE74aYOtGKfgB9VPuVJPix0H6fhmm2erj5PBJ21mqcx34lpIGtUCsQ== + dependencies: + sparse-bitfield "^3.0.3" + +"@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== + +"@sinonjs/commons@^3.0.0": + version "3.0.0" + resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz" + integrity sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^10.0.2": + version "10.3.0" + resolved "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz" + integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA== + dependencies: + "@sinonjs/commons" "^3.0.0" + +"@types/babel__core@^7.1.14": + version "7.20.5" + resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz" + integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== + dependencies: + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.8" + resolved "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz" + integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.4" + resolved "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz" + integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": + version "7.20.5" + resolved "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz" + integrity sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ== + dependencies: + "@babel/types" "^7.20.7" + +"@types/body-parser@*": + version "1.19.5" + resolved "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz" + integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.38" + resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz" + integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== + dependencies: + "@types/node" "*" + +"@types/cookiejar@^2.1.5": + version "2.1.5" + resolved "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.5.tgz" + integrity sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q== + +"@types/express@*", "@types/express@^4.17.21": + version "4.17.21" + resolved "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz" + integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.33" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/express-list-endpoints@^6.0.3": + version "6.0.3" + resolved "https://registry.npmjs.org/@types/express-list-endpoints/-/express-list-endpoints-6.0.3.tgz" + integrity sha512-0lZ5pOHtivd8Vx49E5gBQHMTmccMCQTLGjPBsBKHABdC9b55VY86dxvhfMkbJefzaH0YHhgExWOg5WoG2gDIeg== + dependencies: + "@types/express" "*" + +"@types/express-serve-static-core@^4.17.33": + version "4.17.41" + resolved "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz" + integrity sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/send" "*" + +"@types/graceful-fs@^4.1.3": + version "4.1.9" + resolved "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz" + integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ== + dependencies: + "@types/node" "*" + +"@types/http-errors@*": + version "2.0.4" + resolved "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz" + integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": + version "2.0.6" + resolved "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz" + integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== + +"@types/istanbul-lib-report@*": + version "3.0.3" + resolved "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz" + integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.4" + resolved "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz" + integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/jest@^29.5.11": + version "29.5.11" + resolved "https://registry.npmjs.org/@types/jest/-/jest-29.5.11.tgz" + integrity sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ== + dependencies: + expect "^29.0.0" + pretty-format "^29.0.0" + +"@types/jsonwebtoken@^9.0.5": + version "9.0.5" + resolved "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.5.tgz" + integrity sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA== + dependencies: + "@types/node" "*" + +"@types/methods@^1.1.4": + version "1.1.4" + resolved "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz" + integrity sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ== + +"@types/mime@^1": + version "1.3.5" + resolved "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz" + integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== + +"@types/mime@*": + version "3.0.4" + resolved "https://registry.npmjs.org/@types/mime/-/mime-3.0.4.tgz" + integrity sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw== + +"@types/node@*": + version "20.10.6" + resolved "https://registry.npmjs.org/@types/node/-/node-20.10.6.tgz" + integrity sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw== + dependencies: + undici-types "~5.26.4" + +"@types/qs@*": + version "6.9.11" + resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz" + integrity sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ== + +"@types/range-parser@*": + version "1.2.7" + resolved "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz" + integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== + +"@types/send@*": + version "0.17.4" + resolved "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz" + integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/serve-static@*": + version "1.15.5" + resolved "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz" + integrity sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ== + dependencies: + "@types/http-errors" "*" + "@types/mime" "*" + "@types/node" "*" + +"@types/stack-utils@^2.0.0": + version "2.0.3" + resolved "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz" + integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== + +"@types/superagent@^8.1.0": + version "8.1.1" + resolved "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.1.tgz" + integrity sha512-YQyEXA4PgCl7EVOoSAS3o0fyPFU6erv5mMixztQYe1bqbWmmn8c+IrqoxjQeZe4MgwXikgcaZPiI/DsbmOVlzA== + dependencies: + "@types/cookiejar" "^2.1.5" + "@types/node" "*" + "@types/methods" "^1.1.4" + +"@types/supertest@^6.0.1": + version "6.0.2" + resolved "https://registry.npmjs.org/@types/supertest/-/supertest-6.0.2.tgz" + integrity sha512-137ypx2lk/wTQbW6An6safu9hXmajAifU/s7szAHLN/FeIm5w7yR0Wkl9fdJMRSHwOn4HLAI0DaB2TOORuhPDg== + dependencies: + "@types/methods" "^1.1.4" + "@types/superagent" "^8.1.0" + +"@types/webidl-conversions@*": + version "7.0.3" + resolved "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz" + integrity sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA== + +"@types/whatwg-url@^8.2.1": + version "8.2.2" + resolved "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz" + integrity sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA== + dependencies: + "@types/node" "*" + "@types/webidl-conversions" "*" + +"@types/ws@*": + version "8.5.10" + resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz" + integrity sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A== + dependencies: + "@types/node" "*" + +"@types/yargs@^17.0.8": + version "17.0.32" + resolved "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz" + integrity sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog== + dependencies: + "@types/yargs-parser" "*" + +"@types/yargs-parser@*": + version "21.0.3" + resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz" + integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== + +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +ansi-escapes@^4.2.1: + version "4.3.2" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + +anymatch@^3.0.3: + version "3.1.3" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +asap@^2.0.0: + version "2.0.6" + resolved "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz" + integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +babel-jest@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz" + integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== + dependencies: + "@jest/transform" "^29.7.0" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^29.6.3" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^29.6.3: + version "29.6.3" + resolved "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz" + integrity sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.1.14" + "@types/babel__traverse" "^7.0.6" + +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + +babel-preset-jest@^29.6.3: + version "29.6.3" + resolved "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz" + integrity sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA== + dependencies: + babel-plugin-jest-hoist "^29.6.3" + babel-preset-current-node-syntax "^1.0.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +body-parser@1.20.1: + version "1.20.1" + resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +"browserslist@>= 4.21.0", browserslist@^4.22.2: + version "4.22.2" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz" + integrity sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A== + dependencies: + caniuse-lite "^1.0.30001565" + electron-to-chromium "^1.4.601" + node-releases "^2.0.14" + update-browserslist-db "^1.0.13" + +bs-logger@0.x: + version "0.2.6" + resolved "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +bson@^6.2.0: + version "6.2.0" + resolved "https://registry.npmjs.org/bson/-/bson-6.2.0.tgz" + integrity sha512-ID1cI+7bazPDyL9wYy9GaQ8gEEohWvcUl/Yf0dIdutJxnmInEEyCsb4awy/OiBfall7zBA179Pahi3vCdFze3Q== + +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz" + integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +bun-types@latest: + version "1.0.21" + resolved "https://registry.npmjs.org/bun-types/-/bun-types-1.0.21.tgz" + integrity sha512-Ugagjf+XZUXDvxDRa3EnhLeMzm2g8ZYFleBF55Ac3GZSzPqdMLAdK9kvZB6M1H4nAFvrEHdV2PHqkzIoNs+3wQ== + dependencies: + "@types/node" "*" + "@types/ws" "*" + undici-types "^5.26.4" + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind@^1.0.0: + version "1.0.5" + resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz" + integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== + dependencies: + function-bind "^1.1.2" + get-intrinsic "^1.2.1" + set-function-length "^1.1.1" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-lite@^1.0.30001565: + version "1.0.30001574" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001574.tgz" + integrity sha512-BtYEK4r/iHt/txm81KBudCUcTy7t+s9emrIaHqjYurQ10x71zJ5VQ9x1dYPcz/b+pKSp4y/v1xSI67A+LzpNyg== + +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + +ci-info@^3.2.0: + version "3.9.0" + resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz" + integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== + +cjs-module-lexer@^1.0.0: + version "1.2.3" + resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz" + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== + +collect-v8-coverage@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz" + integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +component-emitter@^1.3.0: + version "1.3.1" + resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz" + integrity sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4: + version "1.0.5" + resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookiejar@^2.1.4: + version "2.1.4" + resolved "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz" + integrity sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw== + +create-jest@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz" + integrity sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q== + dependencies: + "@jest/types" "^29.6.3" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-config "^29.7.0" + jest-util "^29.7.0" + prompts "^2.0.1" + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4.x, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +dedent@^1.0.0: + version "1.5.1" + resolved "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz" + integrity sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg== + +deepmerge@^4.2.2: + version "4.3.1" + resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + +define-data-property@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz" + integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== + dependencies: + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + +dezalgo@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz" + integrity sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig== + dependencies: + asap "^2.0.0" + wrappy "1" + +diff-sequences@^29.6.3: + version "29.6.3" + resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz" + integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== + +ecdsa-sig-formatter@1.0.11: + version "1.0.11" + resolved "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz" + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== + dependencies: + safe-buffer "^5.0.1" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +electron-to-chromium@^1.4.601: + version "1.4.623" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.623.tgz" + integrity sha512-lKoz10iCYlP1WtRYdh5MvocQPWVRoI7ysp6qf18bmeBgR8abE6+I2CsfyNKztRDZvhdWc+krKT6wS7Neg8sw3A== + +emittery@^0.13.1: + version "0.13.1" + resolved "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz" + integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz" + integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== + +expect@^29.0.0, expect@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz" + integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== + dependencies: + "@jest/expect-utils" "^29.7.0" + jest-get-type "^29.6.3" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + +express@^4.18.2: + version "4.18.2" + resolved "https://registry.npmjs.org/express/-/express-4.18.2.tgz" + integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +express-list-endpoints@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/express-list-endpoints/-/express-list-endpoints-6.0.0.tgz" + integrity sha512-1I30bSVego+AU/eSsX/bV2xrOXW5tFhsuXZp7wZd9396bAAxH7KHaAwLXQYra0Aw33xA67HmNiceGf2SOvXaLg== + +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-safe-stringify@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz" + integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== + +fb-watchman@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz" + integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== + dependencies: + bser "2.1.1" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +formidable@^2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz" + integrity sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g== + dependencies: + dezalgo "^1.0.4" + hexoid "^1.0.0" + once "^1.4.0" + qs "^6.11.0" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@^2.3.2: + version "2.3.3" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +"gensync@^1.0.0-beta.2": + version "1.0.0-beta.2" + resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: + version "1.2.2" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz" + integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== + dependencies: + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +glob@^7.1.3, glob@^7.1.4: + version "7.2.3" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-property-descriptors@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz" + integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== + dependencies: + get-intrinsic "^1.2.2" + +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +hasown@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz" + integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== + dependencies: + function-bind "^1.1.2" + +hexoid@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz" + integrity sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g== + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-core-module@^2.13.0: + version "2.13.1" + resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== + dependencies: + hasown "^2.0.0" + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.2" + resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz" + integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== + +istanbul-lib-instrument@^5.0.4: + version "5.2.1" + resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz" + integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + +istanbul-lib-instrument@^6.0.0: + version "6.0.1" + resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz" + integrity sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^7.5.4" + +istanbul-lib-report@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz" + integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^4.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.1.3: + version "3.1.6" + resolved "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz" + integrity sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jest@^29.0.0, jest@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz" + integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== + dependencies: + "@jest/core" "^29.7.0" + "@jest/types" "^29.6.3" + import-local "^3.0.2" + jest-cli "^29.7.0" + +jest-changed-files@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz" + integrity sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w== + dependencies: + execa "^5.0.0" + jest-util "^29.7.0" + p-limit "^3.1.0" + +jest-circus@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz" + integrity sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/expect" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^1.0.0" + is-generator-fn "^2.0.0" + jest-each "^29.7.0" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-runtime "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + p-limit "^3.1.0" + pretty-format "^29.7.0" + pure-rand "^6.0.0" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-cli@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz" + integrity sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg== + dependencies: + "@jest/core" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" + chalk "^4.0.0" + create-jest "^29.7.0" + exit "^0.1.2" + import-local "^3.0.2" + jest-config "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + yargs "^17.3.1" + +jest-config@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz" + integrity sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ== + dependencies: + "@babel/core" "^7.11.6" + "@jest/test-sequencer" "^29.7.0" + "@jest/types" "^29.6.3" + babel-jest "^29.7.0" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-circus "^29.7.0" + jest-environment-node "^29.7.0" + jest-get-type "^29.6.3" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-runner "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^29.7.0" + slash "^3.0.0" + strip-json-comments "^3.1.1" + +jest-diff@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz" + integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== + dependencies: + chalk "^4.0.0" + diff-sequences "^29.6.3" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + +jest-docblock@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz" + integrity sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g== + dependencies: + detect-newline "^3.0.0" + +jest-each@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz" + integrity sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ== + dependencies: + "@jest/types" "^29.6.3" + chalk "^4.0.0" + jest-get-type "^29.6.3" + jest-util "^29.7.0" + pretty-format "^29.7.0" + +jest-environment-node@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz" + integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + jest-mock "^29.7.0" + jest-util "^29.7.0" + +jest-get-type@^29.6.3: + version "29.6.3" + resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz" + integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== + +jest-haste-map@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz" + integrity sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA== + dependencies: + "@jest/types" "^29.6.3" + "@types/graceful-fs" "^4.1.3" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^29.6.3" + jest-util "^29.7.0" + jest-worker "^29.7.0" + micromatch "^4.0.4" + walker "^1.0.8" + optionalDependencies: + fsevents "^2.3.2" + +jest-leak-detector@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz" + integrity sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw== + dependencies: + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + +jest-matcher-utils@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz" + integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== + dependencies: + chalk "^4.0.0" + jest-diff "^29.7.0" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + +jest-message-util@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz" + integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^29.6.3" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^29.7.0" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-mock@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz" + integrity sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + jest-util "^29.7.0" + +jest-pnp-resolver@^1.2.2: + version "1.2.3" + resolved "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz" + integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== + +jest-regex-util@^29.6.3: + version "29.6.3" + resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz" + integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg== + +jest-resolve@*, jest-resolve@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz" + integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA== + dependencies: + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + jest-pnp-resolver "^1.2.2" + jest-util "^29.7.0" + jest-validate "^29.7.0" + resolve "^1.20.0" + resolve.exports "^2.0.0" + slash "^3.0.0" + +jest-resolve-dependencies@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz" + integrity sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA== + dependencies: + jest-regex-util "^29.6.3" + jest-snapshot "^29.7.0" + +jest-runner@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz" + integrity sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ== + dependencies: + "@jest/console" "^29.7.0" + "@jest/environment" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.13.1" + graceful-fs "^4.2.9" + jest-docblock "^29.7.0" + jest-environment-node "^29.7.0" + jest-haste-map "^29.7.0" + jest-leak-detector "^29.7.0" + jest-message-util "^29.7.0" + jest-resolve "^29.7.0" + jest-runtime "^29.7.0" + jest-util "^29.7.0" + jest-watcher "^29.7.0" + jest-worker "^29.7.0" + p-limit "^3.1.0" + source-map-support "0.5.13" + +jest-runtime@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz" + integrity sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" + "@jest/globals" "^29.7.0" + "@jest/source-map" "^29.6.3" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + jest-message-util "^29.7.0" + jest-mock "^29.7.0" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + slash "^3.0.0" + strip-bom "^4.0.0" + +jest-snapshot@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz" + integrity sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw== + dependencies: + "@babel/core" "^7.11.6" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-jsx" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/types" "^7.3.3" + "@jest/expect-utils" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^29.7.0" + graceful-fs "^4.2.9" + jest-diff "^29.7.0" + jest-get-type "^29.6.3" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + natural-compare "^1.4.0" + pretty-format "^29.7.0" + semver "^7.5.3" + +jest-util@^29.0.0, jest-util@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz" + integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-validate@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz" + integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw== + dependencies: + "@jest/types" "^29.6.3" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^29.6.3" + leven "^3.1.0" + pretty-format "^29.7.0" + +jest-watcher@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz" + integrity sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g== + dependencies: + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.13.1" + jest-util "^29.7.0" + string-length "^4.0.1" + +jest-worker@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz" + integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw== + dependencies: + "@types/node" "*" + jest-util "^29.7.0" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json5@^2.2.3: + version "2.2.3" + resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +jsonwebtoken@^9.0.2: + version "9.0.2" + resolved "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz" + integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== + dependencies: + jws "^3.2.2" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + semver "^7.5.4" + +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz" + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jws@^3.2.2: + version "3.2.2" + resolved "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz" + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== + dependencies: + jwa "^1.4.1" + safe-buffer "^5.0.1" + +kareem@2.5.1: + version "2.5.1" + resolved "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz" + integrity sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA== + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz" + integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz" + integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== + +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz" + integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz" + integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz" + integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz" + integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== + +lodash.memoize@4.x: + version "4.1.2" + resolved "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz" + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== + +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz" + integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +make-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz" + integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== + dependencies: + semver "^7.5.3" + +make-error@1.x: + version "1.3.6" + resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +memory-pager@^1.0.2: + version "1.5.0" + resolved "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz" + integrity sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg== + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +methods@^1.1.2, methods@~1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@2.6.0: + version "2.6.0" + resolved "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimatch@^3.0.4, minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +mongodb@6.2.0: + version "6.2.0" + resolved "https://registry.npmjs.org/mongodb/-/mongodb-6.2.0.tgz" + integrity sha512-d7OSuGjGWDZ5usZPqfvb36laQ9CPhnWkAGHT61x5P95p/8nMVeH8asloMwW6GcYFeB0Vj4CB/1wOTDG2RA9BFA== + dependencies: + "@mongodb-js/saslprep" "^1.1.0" + bson "^6.2.0" + mongodb-connection-string-url "^2.6.0" + +mongodb-connection-string-url@^2.6.0: + version "2.6.0" + resolved "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz" + integrity sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ== + dependencies: + "@types/whatwg-url" "^8.2.1" + whatwg-url "^11.0.0" + +mongoose@^8.0.3: + version "8.0.3" + resolved "https://registry.npmjs.org/mongoose/-/mongoose-8.0.3.tgz" + integrity sha512-LJRT0yP4TW14HT4r2RkxqyvoTylMSzWpl5QOeVHTnRggCLQSpkoBdgbUtORFq/mSL2o9cLCPJz+6uzFj25qbHw== + dependencies: + bson "^6.2.0" + kareem "2.5.1" + mongodb "6.2.0" + mpath "0.9.0" + mquery "5.0.0" + ms "2.1.3" + sift "16.0.1" + +mpath@0.9.0: + version "0.9.0" + resolved "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz" + integrity sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew== + +mquery@5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz" + integrity sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg== + dependencies: + debug "4.x" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz" + integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== + +node-releases@^2.0.14: + version "2.0.14" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz" + integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +object-inspect@^1.9.0: + version "1.13.1" + resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz" + integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +once@^1.3.0, once@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pirates@^4.0.4: + version "4.0.6" + resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +pretty-format@^29.0.0, pretty-format@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz" + integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== + dependencies: + "@jest/schemas" "^29.6.3" + ansi-styles "^5.0.0" + react-is "^18.0.0" + +prompts@^2.0.1: + version "2.4.2" + resolved "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +punycode@^2.1.1: + version "2.3.1" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + +pure-rand@^6.0.0: + version "6.0.4" + resolved "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz" + integrity sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA== + +qs@6.11.0, qs@^6.11.0: + version "6.11.0" + resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +react-is@^18.0.0: + version "18.2.0" + resolved "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +resolve@^1.20.0: + version "1.22.8" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve.exports@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz" + integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== + +safe-buffer@5.2.1, safe-buffer@^5.0.1: + version "5.2.1" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +semver@^6.3.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.3.8, semver@^7.5.3, semver@^7.5.4: + version "7.5.4" + resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +send@0.18.0: + version "0.18.0" + resolved "https://registry.npmjs.org/send/-/send-0.18.0.tgz" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +set-function-length@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz" + integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== + dependencies: + define-data-property "^1.1.1" + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +sift@16.0.1: + version "16.0.1" + resolved "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz" + integrity sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ== + +signal-exit@^3.0.3, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map-support@0.5.13: + version "0.5.13" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +sparse-bitfield@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz" + integrity sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ== + dependencies: + memory-pager "^1.0.2" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +stack-utils@^2.0.3: + version "2.0.6" + resolved "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz" + integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== + dependencies: + escape-string-regexp "^2.0.0" + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== + dependencies: + char-regex "^1.0.2" + strip-ansi "^6.0.0" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +superagent@^8.0.5: + version "8.1.2" + resolved "https://registry.npmjs.org/superagent/-/superagent-8.1.2.tgz" + integrity sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA== + dependencies: + component-emitter "^1.3.0" + cookiejar "^2.1.4" + debug "^4.3.4" + fast-safe-stringify "^2.1.1" + form-data "^4.0.0" + formidable "^2.1.2" + methods "^1.1.2" + mime "2.6.0" + qs "^6.11.0" + semver "^7.3.8" + +supertest@^6.3.3: + version "6.3.3" + resolved "https://registry.npmjs.org/supertest/-/supertest-6.3.3.tgz" + integrity sha512-EMCG6G8gDu5qEqRQ3JjjPs6+FYT1a7Hv5ApHvtSghmOFJYtsU5S+pSb6Y2EUeCEY3CmEL3mmQ8YWlPOzQomabA== + dependencies: + methods "^1.1.2" + superagent "^8.0.5" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +tr46@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz" + integrity sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA== + dependencies: + punycode "^2.1.1" + +ts-jest@^29.1.1: + version "29.1.1" + resolved "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz" + integrity sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA== + dependencies: + bs-logger "0.x" + fast-json-stable-stringify "2.x" + jest-util "^29.0.0" + json5 "^2.2.3" + lodash.memoize "4.x" + make-error "1.x" + semver "^7.5.3" + yargs-parser "^21.0.1" + +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +"typescript@>=4.3 <6", typescript@^5.0.0: + version "5.3.3" + resolved "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz" + integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== + +undici-types@^5.26.4, undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +update-browserslist-db@^1.0.13: + version "1.0.13" + resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz" + integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +v8-to-istanbul@^9.0.1: + version "9.2.0" + resolved "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz" + integrity sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.12" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^2.0.0" + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +walker@^1.0.8: + version "1.0.8" + resolved "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== + dependencies: + makeerror "1.0.12" + +webidl-conversions@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz" + integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== + +whatwg-url@^11.0.0: + version "11.0.0" + resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz" + integrity sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ== + dependencies: + tr46 "^3.0.0" + webidl-conversions "^7.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +write-file-atomic@^4.0.2: + version "4.0.2" + resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz" + integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== + dependencies: + imurmurhash "^0.1.4" + signal-exit "^3.0.7" + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs@^17.3.1: + version "17.7.2" + resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + +yargs-parser@^21.0.1, yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From a878d6255cc1c15c901db1a0ce8aad0d319b9d9d Mon Sep 17 00:00:00 2001 From: Sugui Date: Sat, 6 Jan 2024 20:46:12 +0100 Subject: [PATCH 101/133] Implemented GET /images endpoint with params --- src/controllers/ImageController.ts | 19 +- src/models/ImageModel.ts | 6 +- src/services/ImageService.ts | 17 +- tests/app.test.ts | 68 +- yarn.lock | 3041 ++++++++++++++++++++++++++++ 5 files changed, 3140 insertions(+), 11 deletions(-) create mode 100644 yarn.lock diff --git a/src/controllers/ImageController.ts b/src/controllers/ImageController.ts index 4b2301e..75097fc 100644 --- a/src/controllers/ImageController.ts +++ b/src/controllers/ImageController.ts @@ -1,6 +1,7 @@ import { Request, Response } from "express"; import imageService from "../services/ImageService"; import mongoose, { mongo } from "mongoose"; +import { Image } from "../models/ImageModel"; class ImageController { async getImageById(req: Request, res: Response) { @@ -20,12 +21,22 @@ class ImageController { } } - async getAllImages(_: Request, res: Response): Promise { + async getAllImages(req: Request, res: Response): Promise { try { - const images = await imageService.findAll(); + if (req.query.status !== undefined && !["consumed", "unavailable", "available"].includes(req.query.status as string)) { + throw TypeError("if present, `status` should have the values `consumed`, `unavailable`, or `available`") + } + const limit = req.query.limit ? Number(req.query.limit) : undefined; + const status = req.query.status ? req.query.status as Image["status"] : undefined; + + const images = await imageService.findAll(limit, status); res.json({ images }); } catch (error) { - res.status(500).json({ error: "Internal Server Error" }); + if (error instanceof TypeError) { + res.status(400).json({ error }); + } else { + res.status(500).json({ error: "Internal Server Error" }); + } } } @@ -47,7 +58,7 @@ class ImageController { res.status(400).json({ error: error.message }); } else { // Return 500 in other case - res.status(500).json({ error: error }); + res.status(500).json({ error }); } } } diff --git a/src/models/ImageModel.ts b/src/models/ImageModel.ts index f2baa49..7c0c021 100644 --- a/src/models/ImageModel.ts +++ b/src/models/ImageModel.ts @@ -1,9 +1,9 @@ import mongoose, { Document } from "mongoose"; export interface Image extends Document { - url: String; - enum: "consumed" | "unavailable" | "available"; - tags?: String[]; + url: string; + status: "consumed" | "unavailable" | "available"; + tags?: string[]; } const ImageSchema = new mongoose.Schema( diff --git a/src/services/ImageService.ts b/src/services/ImageService.ts index 8289ed5..c10c10d 100644 --- a/src/services/ImageService.ts +++ b/src/services/ImageService.ts @@ -5,10 +5,23 @@ class ImageService { const image = await imageModel.findOne({ _id: id }); return image; } - async findAll(): Promise { - const allImages = await imageModel.find(); + + async findAll(limit?: number, status?: Image["status"]): Promise { + const typeError = TypeError("if present, `limit` must be a non-negative integer"); + const filter = status !== undefined ? { status } : {}; + let query = imageModel.find(filter); + if (limit !== undefined) { + if (Number.isInteger(limit)) { + if (limit > 0) query = query.limit(limit); + else if (limit < 0) throw typeError; + } else { + throw typeError; + } + } + const allImages = await query; return allImages; } + async add(image: Image): Promise { const newImage = await imageModel.create(image); return newImage; diff --git a/tests/app.test.ts b/tests/app.test.ts index 91987dd..69061a1 100644 --- a/tests/app.test.ts +++ b/tests/app.test.ts @@ -3,6 +3,8 @@ import request, { Response } from "supertest"; import app, { startApp } from "../src/app"; import imageService from "../src/services/ImageService"; import populateDatabase from "./populateDatabase"; +import { Image } from "../src/models/ImageModel"; +import { faker } from "@faker-js/faker"; const imageServiceOriginal = imageService; @@ -73,7 +75,7 @@ describe("GET /images works properly", async () => { it("should return 500 for an error on the service", async () => { mock.module("../src/services/ImageService", () => ({ default: { - add: () => { + findAll: () => { throw new Error("This is an expected testing error"); }, }, @@ -83,6 +85,68 @@ describe("GET /images works properly", async () => { expect(res.status).toBe(500); }); + + it("should return 400 for an invalid status param value", async () => { + const res = await request(app).get("/images?status=foo"); + expect(res.statusCode).toBe(400); + }); + + it("should return 200 for a request with valid status param", async () => { + const status = faker.helpers.arrayElement(["consumed", "available", "unavailable"]) + const res = await request(app).get(`/images?status=${status}`); + expect(res.statusCode).toBe(200); + }); + + it("should only have the requested status in the images", async () => { + const status = faker.helpers.arrayElement(["consumed", "available", "unavailable"]) + const res = await request(app).get(`/images?status=${status}`); + expect(res.body.images + .map((image: Image) => image.status) + .every((imageStatus: string) => imageStatus === status)).toBeTrue(); + }); + + it("should return 400 for a floating point value in limit value", async () => { + const res = await request(app).get("/images?limit=2.4"); + expect(res.statusCode).toBe(400); + }); + + it("should return 400 for a negative value in limit value", async () => { + const res = await request(app).get("/images?limit=-1"); + expect(res.statusCode).toBe(400); + }); + + it("should return 400 for a NaN limit value", async () => { + const res = await request(app).get("/images?limit=foo"); + expect(res.statusCode).toBe(400); + }); + + it("should return 200 for a request with valid limit param", async () => { + const limit = faker.number.int({ min: 5, max: 50 }); + const res = await request(app).get(`/images?limit=${limit}`); + expect(res.statusCode).toBe(200); + }); + + it("should return 200 for a request with valid limit param", async () => { + const limit = faker.number.int({ min: 5, max: 50 }); + const res = await request(app).get(`/images?limit=${limit}`); + expect(res.body.images.length).toBeLessThanOrEqual(limit); + }); + + it("should return 200 for a request with both valid params", async () => { + const res = await request(app).get("/images?limit=3&status=available"); + expect(res.statusCode).toBe(200); + }); + + it("should return the same ids using limit=0 and using no limit parameter", async () => { + const resLimit0 = await request(app).get("/images?limit=0"); + const resNoLimit = await request(app).get("/images"); + + const ids1 = resNoLimit.body.images.map((image: Image) => image._id); + const ids2 = resLimit0.body.images.map((image: Image) => image._id); + + expect(ids1.length).toBe(ids2.length); + ids1.forEach((id: string) => expect(ids2).toContain(id)); + }) }); describe("POST /images works properly", () => { @@ -178,7 +242,7 @@ describe("POST /images works properly", () => { }); }); -describe("/images/:id works properly", () => { +describe("GET /images/:id works properly", () => { it("should return 200 for existing ids", async () => { const list = await request(app).get("/images"); const id = list.body.images[0]._id; diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..01d8ca0 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,3041 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 +# bun ./bun.lockb --hash: FB1C344BE4E1C170-a59dde1fb7411c09-538A0DE39E28C689-3912799b87d41761 + + +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.23.5": + version "7.23.5" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz" + integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== + dependencies: + "@babel/highlight" "^7.23.4" + chalk "^2.4.2" + +"@babel/compat-data@^7.23.5": + version "7.23.5" + resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz" + integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== + +"@babel/core@>=7.0.0-beta.0 <8", "@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.8.0": + version "7.23.6" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.23.6.tgz" + integrity sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.6" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helpers" "^7.23.6" + "@babel/parser" "^7.23.6" + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.6" + "@babel/types" "^7.23.6" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/generator@^7.23.6", "@babel/generator@^7.7.2": + version "7.23.6" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz" + integrity sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw== + dependencies: + "@babel/types" "^7.23.6" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + +"@babel/helper-compilation-targets@^7.23.6": + version "7.23.6" + resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz" + integrity sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ== + dependencies: + "@babel/compat-data" "^7.23.5" + "@babel/helper-validator-option" "^7.23.5" + browserslist "^4.22.2" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-environment-visitor@^7.22.20": + version "7.22.20" + resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== + +"@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== + dependencies: + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" + +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-imports@^7.22.15": + version "7.22.15" + resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz" + integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== + dependencies: + "@babel/types" "^7.22.15" + +"@babel/helper-module-transforms@^7.23.3": + version "7.23.3" + resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz" + integrity sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.20" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.23.4": + version "7.23.4" + resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz" + integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== + +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + +"@babel/helper-validator-option@^7.23.5": + version "7.23.5" + resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz" + integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== + +"@babel/helpers@^7.23.6": + version "7.23.6" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz" + integrity sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA== + dependencies: + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.6" + "@babel/types" "^7.23.6" + +"@babel/highlight@^7.23.4": + version "7.23.4" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz" + integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.23.6": + version "7.23.6" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz" + integrity sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ== + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.13" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-import-meta@^7.8.3": + version "7.10.4" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@^7.7.2": + version "7.23.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz" + integrity sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": + version "7.10.4" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.10.4" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.14.5" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-typescript@^7.7.2": + version "7.23.3" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz" + integrity sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/template@^7.22.15", "@babel/template@^7.3.3": + version "7.22.15" + resolved "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz" + integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/parser" "^7.22.15" + "@babel/types" "^7.22.15" + +"@babel/traverse@^7.23.6": + version "7.23.6" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz" + integrity sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ== + dependencies: + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.6" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.23.6" + "@babel/types" "^7.23.6" + debug "^4.3.1" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.6", "@babel/types@^7.3.3": + version "7.23.6" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz" + integrity sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg== + dependencies: + "@babel/helper-string-parser" "^7.23.4" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + +"@faker-js/faker@^8.3.1": + version "8.3.1" + resolved "https://registry.npmjs.org/@faker-js/faker/-/faker-8.3.1.tgz" + integrity sha512-FdgpFxY6V6rLZE9mmIBb9hM0xpfvQOSNOLnzolzKwsE1DH+gC7lEKV1p1IbR0lAYyvYd5a4u3qWJzowUkw1bIw== + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2": + version "0.1.3" + resolved "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/console@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz" + integrity sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + slash "^3.0.0" + +"@jest/core@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz" + integrity sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg== + dependencies: + "@jest/console" "^29.7.0" + "@jest/reporters" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + ci-info "^3.2.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^29.7.0" + jest-config "^29.7.0" + jest-haste-map "^29.7.0" + jest-message-util "^29.7.0" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-resolve-dependencies "^29.7.0" + jest-runner "^29.7.0" + jest-runtime "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + jest-watcher "^29.7.0" + micromatch "^4.0.4" + pretty-format "^29.7.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz" + integrity sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw== + dependencies: + "@jest/fake-timers" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + jest-mock "^29.7.0" + +"@jest/expect@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz" + integrity sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ== + dependencies: + expect "^29.7.0" + jest-snapshot "^29.7.0" + +"@jest/expect-utils@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz" + integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA== + dependencies: + jest-get-type "^29.6.3" + +"@jest/fake-timers@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz" + integrity sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ== + dependencies: + "@jest/types" "^29.6.3" + "@sinonjs/fake-timers" "^10.0.2" + "@types/node" "*" + jest-message-util "^29.7.0" + jest-mock "^29.7.0" + jest-util "^29.7.0" + +"@jest/globals@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz" + integrity sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/expect" "^29.7.0" + "@jest/types" "^29.6.3" + jest-mock "^29.7.0" + +"@jest/reporters@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz" + integrity sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@jridgewell/trace-mapping" "^0.3.18" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^6.0.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + jest-worker "^29.7.0" + slash "^3.0.0" + string-length "^4.0.1" + strip-ansi "^6.0.0" + v8-to-istanbul "^9.0.1" + +"@jest/schemas@^29.6.3": + version "29.6.3" + resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz" + integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== + dependencies: + "@sinclair/typebox" "^0.27.8" + +"@jest/source-map@^29.6.3": + version "29.6.3" + resolved "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz" + integrity sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw== + dependencies: + "@jridgewell/trace-mapping" "^0.3.18" + callsites "^3.0.0" + graceful-fs "^4.2.9" + +"@jest/test-result@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz" + integrity sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA== + dependencies: + "@jest/console" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz" + integrity sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw== + dependencies: + "@jest/test-result" "^29.7.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + slash "^3.0.0" + +"@jest/transform@^29.7.0": + version "29.7.0" + resolved "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz" + integrity sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw== + dependencies: + "@babel/core" "^7.11.6" + "@jest/types" "^29.6.3" + "@jridgewell/trace-mapping" "^0.3.18" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^2.0.0" + fast-json-stable-stringify "^2.1.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + jest-regex-util "^29.6.3" + jest-util "^29.7.0" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + write-file-atomic "^4.0.2" + +"@jest/types@^29.0.0", "@jest/types@^29.6.3": + version "29.6.3" + resolved "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz" + integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== + dependencies: + "@jest/schemas" "^29.6.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.4.15" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.20" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz" + integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@mongodb-js/saslprep@^1.1.0": + version "1.1.1" + resolved "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.1.tgz" + integrity sha512-t7c5K033joZZMspnHg/gWPE4kandgc2OxE74aYOtGKfgB9VPuVJPix0H6fhmm2erj5PBJ21mqcx34lpIGtUCsQ== + dependencies: + sparse-bitfield "^3.0.3" + +"@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== + +"@sinonjs/commons@^3.0.0": + version "3.0.0" + resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.0.tgz" + integrity sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^10.0.2": + version "10.3.0" + resolved "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz" + integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA== + dependencies: + "@sinonjs/commons" "^3.0.0" + +"@types/babel__core@^7.1.14": + version "7.20.5" + resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz" + integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== + dependencies: + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.6.8" + resolved "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz" + integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.4" + resolved "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz" + integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": + version "7.20.4" + resolved "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz" + integrity sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA== + dependencies: + "@babel/types" "^7.20.7" + +"@types/body-parser@*": + version "1.19.5" + resolved "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz" + integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.38" + resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz" + integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== + dependencies: + "@types/node" "*" + +"@types/cookiejar@^2.1.5": + version "2.1.5" + resolved "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.5.tgz" + integrity sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q== + +"@types/express@*", "@types/express@^4.17.21": + version "4.17.21" + resolved "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz" + integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.33" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/express-list-endpoints@^6.0.3": + version "6.0.3" + resolved "https://registry.npmjs.org/@types/express-list-endpoints/-/express-list-endpoints-6.0.3.tgz" + integrity sha512-0lZ5pOHtivd8Vx49E5gBQHMTmccMCQTLGjPBsBKHABdC9b55VY86dxvhfMkbJefzaH0YHhgExWOg5WoG2gDIeg== + dependencies: + "@types/express" "*" + +"@types/express-serve-static-core@^4.17.33": + version "4.17.41" + resolved "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz" + integrity sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/send" "*" + +"@types/graceful-fs@^4.1.3": + version "4.1.9" + resolved "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz" + integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ== + dependencies: + "@types/node" "*" + +"@types/http-errors@*": + version "2.0.4" + resolved "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz" + integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": + version "2.0.6" + resolved "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz" + integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== + +"@types/istanbul-lib-report@*": + version "3.0.3" + resolved "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz" + integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.4" + resolved "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz" + integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/jest@^29.5.11": + version "29.5.11" + resolved "https://registry.npmjs.org/@types/jest/-/jest-29.5.11.tgz" + integrity sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ== + dependencies: + expect "^29.0.0" + pretty-format "^29.0.0" + +"@types/jsonwebtoken@^9.0.5": + version "9.0.5" + resolved "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.5.tgz" + integrity sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA== + dependencies: + "@types/node" "*" + +"@types/methods@^1.1.4": + version "1.1.4" + resolved "https://registry.npmjs.org/@types/methods/-/methods-1.1.4.tgz" + integrity sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ== + +"@types/mime@^1": + version "1.3.5" + resolved "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz" + integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== + +"@types/mime@*": + version "3.0.4" + resolved "https://registry.npmjs.org/@types/mime/-/mime-3.0.4.tgz" + integrity sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw== + +"@types/node@*": + version "20.10.4" + resolved "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz" + integrity sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg== + dependencies: + undici-types "~5.26.4" + +"@types/qs@*": + version "6.9.10" + resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz" + integrity sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw== + +"@types/range-parser@*": + version "1.2.7" + resolved "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz" + integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== + +"@types/send@*": + version "0.17.4" + resolved "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz" + integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/serve-static@*": + version "1.15.5" + resolved "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz" + integrity sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ== + dependencies: + "@types/http-errors" "*" + "@types/mime" "*" + "@types/node" "*" + +"@types/stack-utils@^2.0.0": + version "2.0.3" + resolved "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz" + integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== + +"@types/superagent@^8.1.0": + version "8.1.1" + resolved "https://registry.npmjs.org/@types/superagent/-/superagent-8.1.1.tgz" + integrity sha512-YQyEXA4PgCl7EVOoSAS3o0fyPFU6erv5mMixztQYe1bqbWmmn8c+IrqoxjQeZe4MgwXikgcaZPiI/DsbmOVlzA== + dependencies: + "@types/cookiejar" "^2.1.5" + "@types/node" "*" + "@types/methods" "^1.1.4" + +"@types/supertest@^6.0.1": + version "6.0.1" + resolved "https://registry.npmjs.org/@types/supertest/-/supertest-6.0.1.tgz" + integrity sha512-M1xs8grAWC4RisSEQjyQV0FZzXnL3y796540Q/HCdiPcErwKpcAfvsNQFb4xp+5btSWMOZG1YlDWs2z96pdbcw== + dependencies: + "@types/methods" "^1.1.4" + "@types/superagent" "^8.1.0" + +"@types/webidl-conversions@*": + version "7.0.3" + resolved "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz" + integrity sha512-CiJJvcRtIgzadHCYXw7dqEnMNRjhGZlYK05Mj9OyktqV8uVT8fD2BFOB7S1uwBE3Kj2Z+4UyPmFw/Ixgw/LAlA== + +"@types/whatwg-url@^8.2.1": + version "8.2.2" + resolved "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz" + integrity sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA== + dependencies: + "@types/node" "*" + "@types/webidl-conversions" "*" + +"@types/yargs@^17.0.8": + version "17.0.32" + resolved "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz" + integrity sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog== + dependencies: + "@types/yargs-parser" "*" + +"@types/yargs-parser@*": + version "21.0.3" + resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz" + integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== + +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + +ansi-escapes@^4.2.1: + version "4.3.2" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + +anymatch@^3.0.3: + version "3.1.3" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + +asap@^2.0.0: + version "2.0.6" + resolved "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz" + integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +babel-jest@^29.0.0, babel-jest@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz" + integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== + dependencies: + "@jest/transform" "^29.7.0" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^29.6.3" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^29.6.3: + version "29.6.3" + resolved "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz" + integrity sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.1.14" + "@types/babel__traverse" "^7.0.6" + +babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-top-level-await" "^7.8.3" + +babel-preset-jest@^29.6.3: + version "29.6.3" + resolved "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz" + integrity sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA== + dependencies: + babel-plugin-jest-hoist "^29.6.3" + babel-preset-current-node-syntax "^1.0.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +body-parser@1.20.1: + version "1.20.1" + resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +"browserslist@>= 4.21.0", browserslist@^4.22.2: + version "4.22.2" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz" + integrity sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A== + dependencies: + caniuse-lite "^1.0.30001565" + electron-to-chromium "^1.4.601" + node-releases "^2.0.14" + update-browserslist-db "^1.0.13" + +bs-logger@0.x: + version "0.2.6" + resolved "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +bson@^6.2.0: + version "6.2.0" + resolved "https://registry.npmjs.org/bson/-/bson-6.2.0.tgz" + integrity sha512-ID1cI+7bazPDyL9wYy9GaQ8gEEohWvcUl/Yf0dIdutJxnmInEEyCsb4awy/OiBfall7zBA179Pahi3vCdFze3Q== + +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz" + integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +bun-types@latest: + version "1.0.15" + resolved "https://registry.npmjs.org/bun-types/-/bun-types-1.0.15.tgz" + integrity sha512-XkEvWLV1JIhcVIpf2Lu6FXnZUxRUkQVJmgY+VT7os6Tk5X1nkXx11q4Rtu6txsqpDJZfUeZXblnnD59K+6wsVA== + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + +call-bind@^1.0.0: + version "1.0.5" + resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz" + integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== + dependencies: + function-bind "^1.1.2" + get-intrinsic "^1.2.1" + set-function-length "^1.1.1" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-lite@^1.0.30001565: + version "1.0.30001571" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001571.tgz" + integrity sha512-tYq/6MoXhdezDLFZuCO/TKboTzuQ/xR5cFdgXPfDtM7/kchBO3b4VWghE/OAi/DV7tTdhmLjZiZBZi1fA/GheQ== + +chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + +ci-info@^3.2.0: + version "3.9.0" + resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz" + integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== + +cjs-module-lexer@^1.0.0: + version "1.2.3" + resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz" + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== + +collect-v8-coverage@^1.0.0: + version "1.0.2" + resolved "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz" + integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +component-emitter@^1.3.0: + version "1.3.1" + resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz" + integrity sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4: + version "1.0.5" + resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookiejar@^2.1.4: + version "2.1.4" + resolved "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz" + integrity sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw== + +create-jest@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz" + integrity sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q== + dependencies: + "@jest/types" "^29.6.3" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-config "^29.7.0" + jest-util "^29.7.0" + prompts "^2.0.1" + +cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +debug@2.6.9: + version "2.6.9" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@4.x, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +dedent@^1.0.0: + version "1.5.1" + resolved "https://registry.npmjs.org/dedent/-/dedent-1.5.1.tgz" + integrity sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg== + +deepmerge@^4.2.2: + version "4.3.1" + resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + +define-data-property@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz" + integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== + dependencies: + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +depd@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + +dezalgo@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz" + integrity sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig== + dependencies: + asap "^2.0.0" + wrappy "1" + +diff-sequences@^29.6.3: + version "29.6.3" + resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz" + integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== + +ecdsa-sig-formatter@1.0.11: + version "1.0.11" + resolved "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz" + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== + dependencies: + safe-buffer "^5.0.1" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +electron-to-chromium@^1.4.601: + version "1.4.616" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.616.tgz" + integrity sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg== + +emittery@^0.13.1: + version "0.13.1" + resolved "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz" + integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz" + integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== + +expect@^29.0.0, expect@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz" + integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== + dependencies: + "@jest/expect-utils" "^29.7.0" + jest-get-type "^29.6.3" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + +express@^4.18.2: + version "4.18.2" + resolved "https://registry.npmjs.org/express/-/express-4.18.2.tgz" + integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +express-list-endpoints@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/express-list-endpoints/-/express-list-endpoints-6.0.0.tgz" + integrity sha512-1I30bSVego+AU/eSsX/bV2xrOXW5tFhsuXZp7wZd9396bAAxH7KHaAwLXQYra0Aw33xA67HmNiceGf2SOvXaLg== + +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-safe-stringify@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz" + integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== + +fb-watchman@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz" + integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== + dependencies: + bser "2.1.1" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +formidable@^2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz" + integrity sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g== + dependencies: + dezalgo "^1.0.4" + hexoid "^1.0.0" + once "^1.4.0" + qs "^6.11.0" + +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@^2.3.2: + version "2.3.3" + resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +"gensync@^1.0.0-beta.2": + version "1.0.0-beta.2" + resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: + version "1.2.2" + resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz" + integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== + dependencies: + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +glob@^7.1.3, glob@^7.1.4: + version "7.2.3" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-property-descriptors@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz" + integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== + dependencies: + get-intrinsic "^1.2.2" + +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +hasown@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz" + integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== + dependencies: + function-bind "^1.1.2" + +hexoid@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz" + integrity sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g== + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +iconv-lite@0.4.24: + version "0.4.24" + resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-core-module@^2.13.0: + version "2.13.1" + resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== + dependencies: + hasown "^2.0.0" + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.2" + resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz" + integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== + +istanbul-lib-instrument@^5.0.4: + version "5.2.1" + resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz" + integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + +istanbul-lib-instrument@^6.0.0: + version "6.0.1" + resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz" + integrity sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^7.5.4" + +istanbul-lib-report@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz" + integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^4.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.1.3: + version "3.1.6" + resolved "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.6.tgz" + integrity sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jest@^29.0.0, jest@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz" + integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== + dependencies: + "@jest/core" "^29.7.0" + "@jest/types" "^29.6.3" + import-local "^3.0.2" + jest-cli "^29.7.0" + +jest-changed-files@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz" + integrity sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w== + dependencies: + execa "^5.0.0" + jest-util "^29.7.0" + p-limit "^3.1.0" + +jest-circus@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz" + integrity sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/expect" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^1.0.0" + is-generator-fn "^2.0.0" + jest-each "^29.7.0" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-runtime "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + p-limit "^3.1.0" + pretty-format "^29.7.0" + pure-rand "^6.0.0" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-cli@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz" + integrity sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg== + dependencies: + "@jest/core" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" + chalk "^4.0.0" + create-jest "^29.7.0" + exit "^0.1.2" + import-local "^3.0.2" + jest-config "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + yargs "^17.3.1" + +jest-config@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz" + integrity sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ== + dependencies: + "@babel/core" "^7.11.6" + "@jest/test-sequencer" "^29.7.0" + "@jest/types" "^29.6.3" + babel-jest "^29.7.0" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-circus "^29.7.0" + jest-environment-node "^29.7.0" + jest-get-type "^29.6.3" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-runner "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^29.7.0" + slash "^3.0.0" + strip-json-comments "^3.1.1" + +jest-diff@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz" + integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== + dependencies: + chalk "^4.0.0" + diff-sequences "^29.6.3" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + +jest-docblock@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz" + integrity sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g== + dependencies: + detect-newline "^3.0.0" + +jest-each@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz" + integrity sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ== + dependencies: + "@jest/types" "^29.6.3" + chalk "^4.0.0" + jest-get-type "^29.6.3" + jest-util "^29.7.0" + pretty-format "^29.7.0" + +jest-environment-node@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz" + integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + jest-mock "^29.7.0" + jest-util "^29.7.0" + +jest-get-type@^29.6.3: + version "29.6.3" + resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz" + integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== + +jest-haste-map@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz" + integrity sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA== + dependencies: + "@jest/types" "^29.6.3" + "@types/graceful-fs" "^4.1.3" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^29.6.3" + jest-util "^29.7.0" + jest-worker "^29.7.0" + micromatch "^4.0.4" + walker "^1.0.8" + optionalDependencies: + fsevents "^2.3.2" + +jest-leak-detector@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz" + integrity sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw== + dependencies: + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + +jest-matcher-utils@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz" + integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== + dependencies: + chalk "^4.0.0" + jest-diff "^29.7.0" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + +jest-message-util@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz" + integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^29.6.3" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^29.7.0" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-mock@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz" + integrity sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + jest-util "^29.7.0" + +jest-pnp-resolver@^1.2.2: + version "1.2.3" + resolved "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz" + integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== + +jest-regex-util@^29.6.3: + version "29.6.3" + resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz" + integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg== + +jest-resolve@*, jest-resolve@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz" + integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA== + dependencies: + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + jest-pnp-resolver "^1.2.2" + jest-util "^29.7.0" + jest-validate "^29.7.0" + resolve "^1.20.0" + resolve.exports "^2.0.0" + slash "^3.0.0" + +jest-resolve-dependencies@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz" + integrity sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA== + dependencies: + jest-regex-util "^29.6.3" + jest-snapshot "^29.7.0" + +jest-runner@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz" + integrity sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ== + dependencies: + "@jest/console" "^29.7.0" + "@jest/environment" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.13.1" + graceful-fs "^4.2.9" + jest-docblock "^29.7.0" + jest-environment-node "^29.7.0" + jest-haste-map "^29.7.0" + jest-leak-detector "^29.7.0" + jest-message-util "^29.7.0" + jest-resolve "^29.7.0" + jest-runtime "^29.7.0" + jest-util "^29.7.0" + jest-watcher "^29.7.0" + jest-worker "^29.7.0" + p-limit "^3.1.0" + source-map-support "0.5.13" + +jest-runtime@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz" + integrity sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" + "@jest/globals" "^29.7.0" + "@jest/source-map" "^29.6.3" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + jest-message-util "^29.7.0" + jest-mock "^29.7.0" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + slash "^3.0.0" + strip-bom "^4.0.0" + +jest-snapshot@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz" + integrity sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw== + dependencies: + "@babel/core" "^7.11.6" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-jsx" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/types" "^7.3.3" + "@jest/expect-utils" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^29.7.0" + graceful-fs "^4.2.9" + jest-diff "^29.7.0" + jest-get-type "^29.6.3" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + natural-compare "^1.4.0" + pretty-format "^29.7.0" + semver "^7.5.3" + +jest-util@^29.0.0, jest-util@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz" + integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-validate@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz" + integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw== + dependencies: + "@jest/types" "^29.6.3" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^29.6.3" + leven "^3.1.0" + pretty-format "^29.7.0" + +jest-watcher@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz" + integrity sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g== + dependencies: + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.13.1" + jest-util "^29.7.0" + string-length "^4.0.1" + +jest-worker@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz" + integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw== + dependencies: + "@types/node" "*" + jest-util "^29.7.0" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json5@^2.2.3: + version "2.2.3" + resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +jsonwebtoken@^9.0.2: + version "9.0.2" + resolved "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz" + integrity sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ== + dependencies: + jws "^3.2.2" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + semver "^7.5.4" + +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz" + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jws@^3.2.2: + version "3.2.2" + resolved "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz" + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== + dependencies: + jwa "^1.4.1" + safe-buffer "^5.0.1" + +kareem@2.5.1: + version "2.5.1" + resolved "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz" + integrity sha512-7jFxRVm+jD+rkq3kY0iZDJfsO2/t4BBPeEb2qKn2lR/9KhuksYk5hxzfRYWMPV8P/x2d0kHD306YyWLzjjH+uA== + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz" + integrity sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w== + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz" + integrity sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg== + +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz" + integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz" + integrity sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw== + +lodash.isplainobject@^4.0.6: + version "4.0.6" + resolved "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz" + integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz" + integrity sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw== + +lodash.memoize@4.x: + version "4.1.2" + resolved "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz" + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== + +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz" + integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +make-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz" + integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== + dependencies: + semver "^7.5.3" + +make-error@1.x: + version "1.3.6" + resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + +memory-pager@^1.0.2: + version "1.5.0" + resolved "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz" + integrity sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg== + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +methods@^1.1.2, methods@~1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mime@1.6.0: + version "1.6.0" + resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + +mime@2.6.0: + version "2.6.0" + resolved "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimatch@^3.0.4, minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +mongodb@6.2.0: + version "6.2.0" + resolved "https://registry.npmjs.org/mongodb/-/mongodb-6.2.0.tgz" + integrity sha512-d7OSuGjGWDZ5usZPqfvb36laQ9CPhnWkAGHT61x5P95p/8nMVeH8asloMwW6GcYFeB0Vj4CB/1wOTDG2RA9BFA== + dependencies: + "@mongodb-js/saslprep" "^1.1.0" + bson "^6.2.0" + mongodb-connection-string-url "^2.6.0" + +mongodb-connection-string-url@^2.6.0: + version "2.6.0" + resolved "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz" + integrity sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ== + dependencies: + "@types/whatwg-url" "^8.2.1" + whatwg-url "^11.0.0" + +mongoose@^8.0.3: + version "8.0.3" + resolved "https://registry.npmjs.org/mongoose/-/mongoose-8.0.3.tgz" + integrity sha512-LJRT0yP4TW14HT4r2RkxqyvoTylMSzWpl5QOeVHTnRggCLQSpkoBdgbUtORFq/mSL2o9cLCPJz+6uzFj25qbHw== + dependencies: + bson "^6.2.0" + kareem "2.5.1" + mongodb "6.2.0" + mpath "0.9.0" + mquery "5.0.0" + ms "2.1.3" + sift "16.0.1" + +mpath@0.9.0: + version "0.9.0" + resolved "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz" + integrity sha512-ikJRQTk8hw5DEoFVxHG1Gn9T/xcjtdnOKIU1JTmGjZZlg9LST2mBLmcX3/ICIbgJydT2GOc15RnNy5mHmzfSew== + +mquery@5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/mquery/-/mquery-5.0.0.tgz" + integrity sha512-iQMncpmEK8R8ncT8HJGsGc9Dsp8xcgYMVSbs5jgnm1lFHTZqMJTUWTDx1LBO8+mK3tPNZWFLBghQEIOULSTHZg== + dependencies: + debug "4.x" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz" + integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== + +node-releases@^2.0.14: + version "2.0.14" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz" + integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +object-inspect@^1.9.0: + version "1.13.1" + resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz" + integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +once@^1.3.0, once@^1.4.0: + version "1.4.0" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pirates@^4.0.4: + version "4.0.6" + resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +pretty-format@^29.0.0, pretty-format@^29.7.0: + version "29.7.0" + resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz" + integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== + dependencies: + "@jest/schemas" "^29.6.3" + ansi-styles "^5.0.0" + react-is "^18.0.0" + +prompts@^2.0.1: + version "2.4.2" + resolved "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + +punycode@^2.1.1: + version "2.3.1" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + +pure-rand@^6.0.0: + version "6.0.4" + resolved "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz" + integrity sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA== + +qs@6.11.0, qs@^6.11.0: + version "6.11.0" + resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +react-is@^18.0.0: + version "18.2.0" + resolved "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +resolve@^1.20.0: + version "1.22.8" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve.exports@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz" + integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== + +safe-buffer@5.2.1, safe-buffer@^5.0.1: + version "5.2.1" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +semver@^6.3.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.3.8, semver@^7.5.3, semver@^7.5.4: + version "7.5.4" + resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +send@0.18.0: + version "0.18.0" + resolved "https://registry.npmjs.org/send/-/send-0.18.0.tgz" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +set-function-length@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz" + integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== + dependencies: + define-data-property "^1.1.1" + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + +sift@16.0.1: + version "16.0.1" + resolved "https://registry.npmjs.org/sift/-/sift-16.0.1.tgz" + integrity sha512-Wv6BjQ5zbhW7VFefWusVP33T/EM0vYikCaQ2qR8yULbsilAT8/wQaXvuQ3ptGLpoKx+lihJE3y2UTgKDyyNHZQ== + +signal-exit@^3.0.3, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +source-map@^0.6.0, source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map-support@0.5.13: + version "0.5.13" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +sparse-bitfield@^3.0.3: + version "3.0.3" + resolved "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz" + integrity sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ== + dependencies: + memory-pager "^1.0.2" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +stack-utils@^2.0.3: + version "2.0.6" + resolved "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz" + integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== + dependencies: + escape-string-regexp "^2.0.0" + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== + dependencies: + char-regex "^1.0.2" + strip-ansi "^6.0.0" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +superagent@^8.0.5: + version "8.1.2" + resolved "https://registry.npmjs.org/superagent/-/superagent-8.1.2.tgz" + integrity sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA== + dependencies: + component-emitter "^1.3.0" + cookiejar "^2.1.4" + debug "^4.3.4" + fast-safe-stringify "^2.1.1" + form-data "^4.0.0" + formidable "^2.1.2" + methods "^1.1.2" + mime "2.6.0" + qs "^6.11.0" + semver "^7.3.8" + +supertest@^6.3.3: + version "6.3.3" + resolved "https://registry.npmjs.org/supertest/-/supertest-6.3.3.tgz" + integrity sha512-EMCG6G8gDu5qEqRQ3JjjPs6+FYT1a7Hv5ApHvtSghmOFJYtsU5S+pSb6Y2EUeCEY3CmEL3mmQ8YWlPOzQomabA== + dependencies: + methods "^1.1.2" + superagent "^8.0.5" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +tr46@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz" + integrity sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA== + dependencies: + punycode "^2.1.1" + +ts-jest@^29.1.1: + version "29.1.1" + resolved "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz" + integrity sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA== + dependencies: + bs-logger "0.x" + fast-json-stable-stringify "2.x" + jest-util "^29.0.0" + json5 "^2.2.3" + lodash.memoize "4.x" + make-error "1.x" + semver "^7.5.3" + yargs-parser "^21.0.1" + +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +"typescript@>=4.3 <6", typescript@^5.0.0: + version "5.3.3" + resolved "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz" + integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== + +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + +update-browserslist-db@^1.0.13: + version "1.0.13" + resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz" + integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + +v8-to-istanbul@^9.0.1: + version "9.2.0" + resolved "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz" + integrity sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.12" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^2.0.0" + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +walker@^1.0.8: + version "1.0.8" + resolved "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== + dependencies: + makeerror "1.0.12" + +webidl-conversions@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz" + integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== + +whatwg-url@^11.0.0: + version "11.0.0" + resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz" + integrity sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ== + dependencies: + tr46 "^3.0.0" + webidl-conversions "^7.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +write-file-atomic@^4.0.2: + version "4.0.2" + resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz" + integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== + dependencies: + imurmurhash "^0.1.4" + signal-exit "^3.0.7" + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yargs@^17.3.1: + version "17.7.2" + resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + +yargs-parser@^21.0.1, yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From e263f1eaca888092fe9ed8196bd7d92956a5d2df Mon Sep 17 00:00:00 2001 From: Sugui Date: Sat, 6 Jan 2024 20:49:42 +0100 Subject: [PATCH 102/133] yarn.lock --- yarn.lock | 87 ++++++++++++++++++++++++------------------------------- 1 file changed, 38 insertions(+), 49 deletions(-) diff --git a/yarn.lock b/yarn.lock index 1cf8075..01d8ca0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1,6 +1,6 @@ # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. # yarn lockfile v1 -# bun ./bun.lockb --hash: 738A3B3B61512E75-26d27a9609e246ac-33059F282FFA6348-27fd5707ca8843fa +# bun ./bun.lockb --hash: FB1C344BE4E1C170-a59dde1fb7411c09-538A0DE39E28C689-3912799b87d41761 "@ampproject/remapping@^2.2.0": @@ -25,19 +25,19 @@ integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== "@babel/core@>=7.0.0-beta.0 <8", "@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.8.0": - version "7.23.7" - resolved "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz" - integrity sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw== + version "7.23.6" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.23.6.tgz" + integrity sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw== dependencies: "@ampproject/remapping" "^2.2.0" "@babel/code-frame" "^7.23.5" "@babel/generator" "^7.23.6" "@babel/helper-compilation-targets" "^7.23.6" "@babel/helper-module-transforms" "^7.23.3" - "@babel/helpers" "^7.23.7" + "@babel/helpers" "^7.23.6" "@babel/parser" "^7.23.6" "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.7" + "@babel/traverse" "^7.23.6" "@babel/types" "^7.23.6" convert-source-map "^2.0.0" debug "^4.1.0" @@ -138,13 +138,13 @@ resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz" integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== -"@babel/helpers@^7.23.7": - version "7.23.7" - resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.7.tgz" - integrity sha512-6AMnjCoC8wjqBzDHkuqpa7jAKwvMo4dC+lr/TFBz+ucfulO1XMpDnwWPGBNwClOKZ8h6xn5N81W/R5OrcKtCbQ== +"@babel/helpers@^7.23.6": + version "7.23.6" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz" + integrity sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA== dependencies: "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.7" + "@babel/traverse" "^7.23.6" "@babel/types" "^7.23.6" "@babel/highlight@^7.23.4": @@ -268,10 +268,10 @@ "@babel/parser" "^7.22.15" "@babel/types" "^7.22.15" -"@babel/traverse@^7.23.7": - version "7.23.7" - resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz" - integrity sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg== +"@babel/traverse@^7.23.6": + version "7.23.6" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz" + integrity sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ== dependencies: "@babel/code-frame" "^7.23.5" "@babel/generator" "^7.23.6" @@ -596,9 +596,9 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.20.5" - resolved "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz" - integrity sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ== + version "7.20.4" + resolved "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz" + integrity sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA== dependencies: "@babel/types" "^7.20.7" @@ -711,16 +711,16 @@ integrity sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw== "@types/node@*": - version "20.10.6" - resolved "https://registry.npmjs.org/@types/node/-/node-20.10.6.tgz" - integrity sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw== + version "20.10.4" + resolved "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz" + integrity sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg== dependencies: undici-types "~5.26.4" "@types/qs@*": - version "6.9.11" - resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz" - integrity sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ== + version "6.9.10" + resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz" + integrity sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw== "@types/range-parser@*": version "1.2.7" @@ -759,9 +759,9 @@ "@types/methods" "^1.1.4" "@types/supertest@^6.0.1": - version "6.0.2" - resolved "https://registry.npmjs.org/@types/supertest/-/supertest-6.0.2.tgz" - integrity sha512-137ypx2lk/wTQbW6An6safu9hXmajAifU/s7szAHLN/FeIm5w7yR0Wkl9fdJMRSHwOn4HLAI0DaB2TOORuhPDg== + version "6.0.1" + resolved "https://registry.npmjs.org/@types/supertest/-/supertest-6.0.1.tgz" + integrity sha512-M1xs8grAWC4RisSEQjyQV0FZzXnL3y796540Q/HCdiPcErwKpcAfvsNQFb4xp+5btSWMOZG1YlDWs2z96pdbcw== dependencies: "@types/methods" "^1.1.4" "@types/superagent" "^8.1.0" @@ -779,13 +779,6 @@ "@types/node" "*" "@types/webidl-conversions" "*" -"@types/ws@*": - version "8.5.10" - resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz" - integrity sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A== - dependencies: - "@types/node" "*" - "@types/yargs@^17.0.8": version "17.0.32" resolved "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz" @@ -867,7 +860,7 @@ asynckit@^0.4.0: resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== -babel-jest@^29.7.0: +babel-jest@^29.0.0, babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz" integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== @@ -1005,13 +998,9 @@ buffer-from@^1.0.0: integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== bun-types@latest: - version "1.0.21" - resolved "https://registry.npmjs.org/bun-types/-/bun-types-1.0.21.tgz" - integrity sha512-Ugagjf+XZUXDvxDRa3EnhLeMzm2g8ZYFleBF55Ac3GZSzPqdMLAdK9kvZB6M1H4nAFvrEHdV2PHqkzIoNs+3wQ== - dependencies: - "@types/node" "*" - "@types/ws" "*" - undici-types "^5.26.4" + version "1.0.15" + resolved "https://registry.npmjs.org/bun-types/-/bun-types-1.0.15.tgz" + integrity sha512-XkEvWLV1JIhcVIpf2Lu6FXnZUxRUkQVJmgY+VT7os6Tk5X1nkXx11q4Rtu6txsqpDJZfUeZXblnnD59K+6wsVA== bytes@3.1.2: version "3.1.2" @@ -1043,9 +1032,9 @@ camelcase@^6.2.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001565: - version "1.0.30001574" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001574.tgz" - integrity sha512-BtYEK4r/iHt/txm81KBudCUcTy7t+s9emrIaHqjYurQ10x71zJ5VQ9x1dYPcz/b+pKSp4y/v1xSI67A+LzpNyg== + version "1.0.30001571" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001571.tgz" + integrity sha512-tYq/6MoXhdezDLFZuCO/TKboTzuQ/xR5cFdgXPfDtM7/kchBO3b4VWghE/OAi/DV7tTdhmLjZiZBZi1fA/GheQ== chalk@^2.4.2: version "2.4.2" @@ -1272,9 +1261,9 @@ ee-first@1.1.1: integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== electron-to-chromium@^1.4.601: - version "1.4.623" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.623.tgz" - integrity sha512-lKoz10iCYlP1WtRYdh5MvocQPWVRoI7ysp6qf18bmeBgR8abE6+I2CsfyNKztRDZvhdWc+krKT6wS7Neg8sw3A== + version "1.4.616" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.616.tgz" + integrity sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg== emittery@^0.13.1: version "0.13.1" @@ -2927,7 +2916,7 @@ type-is@~1.6.18: resolved "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz" integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== -undici-types@^5.26.4, undici-types@~5.26.4: +undici-types@~5.26.4: version "5.26.5" resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== From 7aceafff7bc6e12b6c281482929ee586c0626dda Mon Sep 17 00:00:00 2001 From: Alie Date: Sat, 6 Jan 2024 21:24:12 +0100 Subject: [PATCH 103/133] fmt --- src/controllers/ImageController.ts | 15 ++++-- src/services/ImageService.ts | 4 +- tests/app.test.ts | 46 +++++++++------- tests/populateDatabase.ts | 39 ++++++++++---- yarn.lock | 87 +++++++++++++++++------------- 5 files changed, 120 insertions(+), 71 deletions(-) diff --git a/src/controllers/ImageController.ts b/src/controllers/ImageController.ts index d1958c2..267d40d 100644 --- a/src/controllers/ImageController.ts +++ b/src/controllers/ImageController.ts @@ -51,11 +51,20 @@ class ImageController { async getAllImages(req: Request, res: Response): Promise { try { - if (req.query.status !== undefined && !["consumed", "unavailable", "available"].includes(req.query.status as string)) { - throw TypeError("if present, `status` should have the values `consumed`, `unavailable`, or `available`") + if ( + req.query.status !== undefined && + !["consumed", "unavailable", "available"].includes( + req.query.status as string + ) + ) { + throw TypeError( + "if present, `status` should have the values `consumed`, `unavailable`, or `available`" + ); } const limit = req.query.limit ? Number(req.query.limit) : undefined; - const status = req.query.status ? req.query.status as Image["status"] : undefined; + const status = req.query.status + ? (req.query.status as Image["status"]) + : undefined; const images = await imageService.findAll(limit, status); res.json({ images }); diff --git a/src/services/ImageService.ts b/src/services/ImageService.ts index bff9273..c75e471 100644 --- a/src/services/ImageService.ts +++ b/src/services/ImageService.ts @@ -11,7 +11,9 @@ class ImageService { } async findAll(limit?: number, status?: Image["status"]): Promise { - const typeError = TypeError("if present, `limit` must be a non-negative integer"); + const typeError = TypeError( + "if present, `limit` must be a non-negative integer" + ); const filter = status !== undefined ? { status } : {}; let query = imageModel.find(filter); if (limit !== undefined) { diff --git a/tests/app.test.ts b/tests/app.test.ts index 1b1c2d0..189b844 100644 --- a/tests/app.test.ts +++ b/tests/app.test.ts @@ -92,17 +92,27 @@ describe("GET /images works properly", async () => { }); it("should return 200 for a request with valid status param", async () => { - const status = faker.helpers.arrayElement(["consumed", "available", "unavailable"]) + const status = faker.helpers.arrayElement([ + "consumed", + "available", + "unavailable", + ]); const res = await request(app).get(`/images?status=${status}`); expect(res.statusCode).toBe(200); }); it("should only have the requested status in the images", async () => { - const status = faker.helpers.arrayElement(["consumed", "available", "unavailable"]) + const status = faker.helpers.arrayElement([ + "consumed", + "available", + "unavailable", + ]); const res = await request(app).get(`/images?status=${status}`); - expect(res.body.images - .map((image: Image) => image.status) - .every((imageStatus: string) => imageStatus === status)).toBeTrue(); + expect( + res.body.images + .map((image: Image) => image.status) + .every((imageStatus: string) => imageStatus === status) + ).toBeTrue(); }); it("should return 400 for a floating point value in limit value", async () => { @@ -146,7 +156,7 @@ describe("GET /images works properly", async () => { expect(ids1.length).toBe(ids2.length); ids1.forEach((id: string) => expect(ids2).toContain(id)); - }) + }); }); describe("POST /images works properly", () => { @@ -356,20 +366,20 @@ describe("PUT /images/ works properly", () => { it("should have its changes be reflected onto the DB", async () => { const image = await request(app) - .post("/images") - .set("authorization", `Bearer ${token}`) - .send({ - url: "https://test.url.com/5", - status: "available", - tags: ["2girls", "touhou"], - }); + .post("/images") + .set("authorization", `Bearer ${token}`) + .send({ + url: "https://test.url.com/5", + status: "available", + tags: ["2girls", "touhou"], + }); const id = image.body.image._id; await request(app) - .put(`/images/${id}`) - .set("authorization", `Bearer ${token}`) - .send({ status: "consumed" }); - + .put(`/images/${id}`) + .set("authorization", `Bearer ${token}`) + .send({ status: "consumed" }); + const res = await request(app).get(`/images/${id}`); expect(res.body.image).toHaveProperty("status", "consumed"); - }) + }); }); diff --git a/tests/populateDatabase.ts b/tests/populateDatabase.ts index 89e604b..2b280c3 100644 --- a/tests/populateDatabase.ts +++ b/tests/populateDatabase.ts @@ -1,20 +1,37 @@ import authModel from "../src/models/AuthModel"; import imageModel, { Image } from "../src/models/ImageModel"; -import { faker } from '@faker-js/faker'; +import { faker } from "@faker-js/faker"; export default async function () { - const images = faker.helpers.multiple(() => ({ - url: faker.helpers.unique(faker.internet.url), - status: faker.helpers.arrayElement(["available", "unavailable", "consumed"]), - tags: faker.helpers.arrayElements([ - "2girls", "sleeping", "touhou", - "pokemon", "closed_eyes", "yume_nikki", - "waifu", "computer", "party", "yuru_camp" - ], { min: 0, max: 5 }), - }), {count: {min: 5, max:50}}); + const images = faker.helpers.multiple( + () => ({ + url: faker.helpers.unique(faker.internet.url), + status: faker.helpers.arrayElement([ + "available", + "unavailable", + "consumed", + ]), + tags: faker.helpers.arrayElements( + [ + "2girls", + "sleeping", + "touhou", + "pokemon", + "closed_eyes", + "yume_nikki", + "waifu", + "computer", + "party", + "yuru_camp", + ], + { min: 0, max: 5 } + ), + }), + { count: { min: 5, max: 50 } } + ); // Wait until all images are inserted - await Promise.allSettled(images.map(image => imageModel.create(image))); + await Promise.allSettled(images.map((image) => imageModel.create(image))); await authModel.create({ app: "tester", diff --git a/yarn.lock b/yarn.lock index 01d8ca0..1cf8075 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1,6 +1,6 @@ # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. # yarn lockfile v1 -# bun ./bun.lockb --hash: FB1C344BE4E1C170-a59dde1fb7411c09-538A0DE39E28C689-3912799b87d41761 +# bun ./bun.lockb --hash: 738A3B3B61512E75-26d27a9609e246ac-33059F282FFA6348-27fd5707ca8843fa "@ampproject/remapping@^2.2.0": @@ -25,19 +25,19 @@ integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== "@babel/core@>=7.0.0-beta.0 <8", "@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.8.0": - version "7.23.6" - resolved "https://registry.npmjs.org/@babel/core/-/core-7.23.6.tgz" - integrity sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw== + version "7.23.7" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz" + integrity sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw== dependencies: "@ampproject/remapping" "^2.2.0" "@babel/code-frame" "^7.23.5" "@babel/generator" "^7.23.6" "@babel/helper-compilation-targets" "^7.23.6" "@babel/helper-module-transforms" "^7.23.3" - "@babel/helpers" "^7.23.6" + "@babel/helpers" "^7.23.7" "@babel/parser" "^7.23.6" "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.6" + "@babel/traverse" "^7.23.7" "@babel/types" "^7.23.6" convert-source-map "^2.0.0" debug "^4.1.0" @@ -138,13 +138,13 @@ resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz" integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== -"@babel/helpers@^7.23.6": - version "7.23.6" - resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz" - integrity sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA== +"@babel/helpers@^7.23.7": + version "7.23.7" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.7.tgz" + integrity sha512-6AMnjCoC8wjqBzDHkuqpa7jAKwvMo4dC+lr/TFBz+ucfulO1XMpDnwWPGBNwClOKZ8h6xn5N81W/R5OrcKtCbQ== dependencies: "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.6" + "@babel/traverse" "^7.23.7" "@babel/types" "^7.23.6" "@babel/highlight@^7.23.4": @@ -268,10 +268,10 @@ "@babel/parser" "^7.22.15" "@babel/types" "^7.22.15" -"@babel/traverse@^7.23.6": - version "7.23.6" - resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz" - integrity sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ== +"@babel/traverse@^7.23.7": + version "7.23.7" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz" + integrity sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg== dependencies: "@babel/code-frame" "^7.23.5" "@babel/generator" "^7.23.6" @@ -596,9 +596,9 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.20.4" - resolved "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz" - integrity sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA== + version "7.20.5" + resolved "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz" + integrity sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ== dependencies: "@babel/types" "^7.20.7" @@ -711,16 +711,16 @@ integrity sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw== "@types/node@*": - version "20.10.4" - resolved "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz" - integrity sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg== + version "20.10.6" + resolved "https://registry.npmjs.org/@types/node/-/node-20.10.6.tgz" + integrity sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw== dependencies: undici-types "~5.26.4" "@types/qs@*": - version "6.9.10" - resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz" - integrity sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw== + version "6.9.11" + resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz" + integrity sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ== "@types/range-parser@*": version "1.2.7" @@ -759,9 +759,9 @@ "@types/methods" "^1.1.4" "@types/supertest@^6.0.1": - version "6.0.1" - resolved "https://registry.npmjs.org/@types/supertest/-/supertest-6.0.1.tgz" - integrity sha512-M1xs8grAWC4RisSEQjyQV0FZzXnL3y796540Q/HCdiPcErwKpcAfvsNQFb4xp+5btSWMOZG1YlDWs2z96pdbcw== + version "6.0.2" + resolved "https://registry.npmjs.org/@types/supertest/-/supertest-6.0.2.tgz" + integrity sha512-137ypx2lk/wTQbW6An6safu9hXmajAifU/s7szAHLN/FeIm5w7yR0Wkl9fdJMRSHwOn4HLAI0DaB2TOORuhPDg== dependencies: "@types/methods" "^1.1.4" "@types/superagent" "^8.1.0" @@ -779,6 +779,13 @@ "@types/node" "*" "@types/webidl-conversions" "*" +"@types/ws@*": + version "8.5.10" + resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz" + integrity sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A== + dependencies: + "@types/node" "*" + "@types/yargs@^17.0.8": version "17.0.32" resolved "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz" @@ -860,7 +867,7 @@ asynckit@^0.4.0: resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== -babel-jest@^29.0.0, babel-jest@^29.7.0: +babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz" integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== @@ -998,9 +1005,13 @@ buffer-from@^1.0.0: integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== bun-types@latest: - version "1.0.15" - resolved "https://registry.npmjs.org/bun-types/-/bun-types-1.0.15.tgz" - integrity sha512-XkEvWLV1JIhcVIpf2Lu6FXnZUxRUkQVJmgY+VT7os6Tk5X1nkXx11q4Rtu6txsqpDJZfUeZXblnnD59K+6wsVA== + version "1.0.21" + resolved "https://registry.npmjs.org/bun-types/-/bun-types-1.0.21.tgz" + integrity sha512-Ugagjf+XZUXDvxDRa3EnhLeMzm2g8ZYFleBF55Ac3GZSzPqdMLAdK9kvZB6M1H4nAFvrEHdV2PHqkzIoNs+3wQ== + dependencies: + "@types/node" "*" + "@types/ws" "*" + undici-types "^5.26.4" bytes@3.1.2: version "3.1.2" @@ -1032,9 +1043,9 @@ camelcase@^6.2.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001565: - version "1.0.30001571" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001571.tgz" - integrity sha512-tYq/6MoXhdezDLFZuCO/TKboTzuQ/xR5cFdgXPfDtM7/kchBO3b4VWghE/OAi/DV7tTdhmLjZiZBZi1fA/GheQ== + version "1.0.30001574" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001574.tgz" + integrity sha512-BtYEK4r/iHt/txm81KBudCUcTy7t+s9emrIaHqjYurQ10x71zJ5VQ9x1dYPcz/b+pKSp4y/v1xSI67A+LzpNyg== chalk@^2.4.2: version "2.4.2" @@ -1261,9 +1272,9 @@ ee-first@1.1.1: integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== electron-to-chromium@^1.4.601: - version "1.4.616" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.616.tgz" - integrity sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg== + version "1.4.623" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.623.tgz" + integrity sha512-lKoz10iCYlP1WtRYdh5MvocQPWVRoI7ysp6qf18bmeBgR8abE6+I2CsfyNKztRDZvhdWc+krKT6wS7Neg8sw3A== emittery@^0.13.1: version "0.13.1" @@ -2916,7 +2927,7 @@ type-is@~1.6.18: resolved "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz" integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== -undici-types@~5.26.4: +undici-types@^5.26.4, undici-types@~5.26.4: version "5.26.5" resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== From b3b11616bffd5e630763c140ea6d6e8b128f47cb Mon Sep 17 00:00:00 2001 From: Sugui Date: Sun, 7 Jan 2024 12:33:37 +0100 Subject: [PATCH 104/133] Removed deprecated faker.helpers.unique function, using enforce-unique instead --- package.json | 1 + tests/populateDatabase.ts | 38 ++++++++++++-------------------------- yarn.lock | 7 ++++++- 3 files changed, 19 insertions(+), 27 deletions(-) diff --git a/package.json b/package.json index 9e10900..1ca452e 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "@types/jsonwebtoken": "^9.0.5", "@types/supertest": "^6.0.1", "bun-types": "latest", + "enforce-unique": "^1.2.0", "jest": "^29.7.0", "supertest": "^6.3.3", "ts-jest": "^29.1.1" diff --git a/tests/populateDatabase.ts b/tests/populateDatabase.ts index 2b280c3..041f830 100644 --- a/tests/populateDatabase.ts +++ b/tests/populateDatabase.ts @@ -1,34 +1,20 @@ import authModel from "../src/models/AuthModel"; import imageModel, { Image } from "../src/models/ImageModel"; import { faker } from "@faker-js/faker"; +import { EnforceUniqueError, UniqueEnforcer } from 'enforce-unique'; + +const uniqueEnforcer = new UniqueEnforcer(); export default async function () { - const images = faker.helpers.multiple( - () => ({ - url: faker.helpers.unique(faker.internet.url), - status: faker.helpers.arrayElement([ - "available", - "unavailable", - "consumed", - ]), - tags: faker.helpers.arrayElements( - [ - "2girls", - "sleeping", - "touhou", - "pokemon", - "closed_eyes", - "yume_nikki", - "waifu", - "computer", - "party", - "yuru_camp", - ], - { min: 0, max: 5 } - ), - }), - { count: { min: 5, max: 50 } } - ); + const images = faker.helpers.multiple(() => ({ + url: uniqueEnforcer.enforce(faker.internet.url), + status: faker.helpers.arrayElement(["available", "unavailable", "consumed"]), + tags: faker.helpers.arrayElements([ + "2girls", "sleeping", "touhou", + "pokemon", "closed_eyes", "yume_nikki", + "waifu", "computer", "party", "yuru_camp" + ], { min: 0, max: 5 }), + }), {count: {min: 5, max:50}}); // Wait until all images are inserted await Promise.allSettled(images.map((image) => imageModel.create(image))); diff --git a/yarn.lock b/yarn.lock index 1cf8075..fd8bf2f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1,6 +1,6 @@ # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. # yarn lockfile v1 -# bun ./bun.lockb --hash: 738A3B3B61512E75-26d27a9609e246ac-33059F282FFA6348-27fd5707ca8843fa +# bun ./bun.lockb --hash: 3F45CED80FCAB4BB-3395ac5a537bfe37-601C6F1D91E66F40-076ab920e8127532 "@ampproject/remapping@^2.2.0": @@ -1291,6 +1291,11 @@ encodeurl@~1.0.2: resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== +enforce-unique@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/enforce-unique/-/enforce-unique-1.2.0.tgz" + integrity sha512-ZBusLJB8QQhKMGNOlwARgov+s38rwPbhcifGlhEHqnGHcA8CCSEgbLujdABtpWwZyYnude4t5fviuEmSuV8Hig== + error-ex@^1.3.1: version "1.3.2" resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" From 7689cb28a3d3fa7f48349cff01e5d88e2c8ef639 Mon Sep 17 00:00:00 2001 From: Sugui Date: Sun, 7 Jan 2024 12:37:03 +0100 Subject: [PATCH 105/133] Shortened and detailed the test on "/" endpoint --- tests/app.test.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/app.test.ts b/tests/app.test.ts index 189b844..d7c78f7 100644 --- a/tests/app.test.ts +++ b/tests/app.test.ts @@ -52,11 +52,8 @@ describe("/login works as instended", async () => { describe("GET / shows all of the endpoints", async () => { const res = await request(app).get("/"); - it("should be", async () => { + it("should have the endpoints in the `endpoints` property, as an array", async () => { expect(res.body).toHaveProperty("endpoints"); - }); - - it("should be an array", () => { expect(Array.isArray(res.body.endpoints)).toBeTrue(); }); }); From f5c472899cb7058840a550d67d06231342deeacf Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 7 Jan 2024 12:54:46 +0100 Subject: [PATCH 106/133] push build action --- .gitea/workflows/build.yaml | 54 +++++++++++++++++++++++++++++++++++++ yarn.lock | 2 +- 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 .gitea/workflows/build.yaml diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml new file mode 100644 index 0000000..7bf7879 --- /dev/null +++ b/.gitea/workflows/build.yaml @@ -0,0 +1,54 @@ +name: Test via test action and then build image +on: + push: + branches: + - main + - develop + +jobs: + unit-test: + steps: + - name: Run test job + uses: ./.gitea/workflow/test.yaml + build: + container: + image: node:16-buster-slim + needs: unit-test + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + # list of Docker images to use as base name for tags + images: | + fedi-image-bot/bot-api + git.fai.st/fedi-image-bot/bot-api + # generate Docker tags based on the following events/attributes + tags: | + type=schedule + type=ref,event=branch + type=ref,event=pr + type=sha + - name: Set up QEMU + # Add support for more platforms with QEMU (optional) + # https://github.com/docker/setup-qemu-action + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Login to fai.st docker registry + uses: docker/login-action@v3 + with: + registry: git.fai.st + username: ${{ secrets.DOCKER_USER }} + password: ${{ secrets.DOCKER_PASS }} + - name: Build and push + uses: docker/build-push-action@v5 + with: + platforms: linux/amd64,linux/arm64 + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=registry,ref=fedi-image-bot/bot-api:latest + cache-to: type=inline \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index fd8bf2f..c99fdb5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1,6 +1,6 @@ # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. # yarn lockfile v1 -# bun ./bun.lockb --hash: 3F45CED80FCAB4BB-3395ac5a537bfe37-601C6F1D91E66F40-076ab920e8127532 +# bun ./bun.lockb --hash: 33E2AFF8D14D8AA5-eebd7db9b471377f-95D45A5384DAAEBC-8f83c3f6d7ba1359 "@ampproject/remapping@^2.2.0": From d12866bbb5b18df75a7428d5c18d6539f172a061 Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 7 Jan 2024 12:58:32 +0100 Subject: [PATCH 107/133] typo --- .gitea/workflows/build.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 7bf7879..081bda5 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -7,9 +7,11 @@ on: jobs: unit-test: + container: + image: docker:dind steps: - name: Run test job - uses: ./.gitea/workflow/test.yaml + uses: ./.gitea/workflows/test.yaml build: container: image: node:16-buster-slim From 9a758c5410e0774fa22293bbd06bd65f31edecf2 Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 7 Jan 2024 12:59:42 +0100 Subject: [PATCH 108/133] seems i need to checkout --- .gitea/workflows/build.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 081bda5..eff2fc8 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -10,6 +10,8 @@ jobs: container: image: docker:dind steps: + - name: Checkout + uses: actions/checkout@v4 - name: Run test job uses: ./.gitea/workflows/test.yaml build: From 4bf1fb5ac23efb25e7eb74cadbe918281d495741 Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 7 Jan 2024 13:01:46 +0100 Subject: [PATCH 109/133] using the act runner --- .gitea/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index eff2fc8..8e3a3dd 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -8,7 +8,7 @@ on: jobs: unit-test: container: - image: docker:dind + image: node:16-buster-slim steps: - name: Checkout uses: actions/checkout@v4 From b75bda4bc3082f7250b3e8c11ea21c556cdbd64d Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 7 Jan 2024 13:07:29 +0100 Subject: [PATCH 110/133] seems i need to specify runs.using --- .gitea/workflows/test.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 2b656bd..50392be 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -1,6 +1,10 @@ name: Unit Tests with docker compose on: [pull_request] +runs: + using: + composite + jobs: unit-test: container: From 12da042a77118b912984cead05f8b67763cbaaa1 Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 7 Jan 2024 13:09:25 +0100 Subject: [PATCH 111/133] change act --- .gitea/workflows/build.yaml | 12 ++++++------ .gitea/workflows/test.yaml | 4 ---- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 8e3a3dd..808bb52 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -8,15 +8,15 @@ on: jobs: unit-test: container: - image: node:16-buster-slim + image: catthehacker/ubuntu:act-22.04 steps: - name: Checkout uses: actions/checkout@v4 - - name: Run test job + - name: Run test job uses: ./.gitea/workflows/test.yaml build: container: - image: node:16-buster-slim + image: catthehacker/ubuntu:act-22.04 needs: unit-test steps: - name: Checkout @@ -28,13 +28,13 @@ jobs: # list of Docker images to use as base name for tags images: | fedi-image-bot/bot-api - git.fai.st/fedi-image-bot/bot-api + git.fai.st/fedi-image-bot/bot-api # generate Docker tags based on the following events/attributes tags: | type=schedule type=ref,event=branch type=ref,event=pr - type=sha + type=sha - name: Set up QEMU # Add support for more platforms with QEMU (optional) # https://github.com/docker/setup-qemu-action @@ -55,4 +55,4 @@ jobs: tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=registry,ref=fedi-image-bot/bot-api:latest - cache-to: type=inline \ No newline at end of file + cache-to: type=inline diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 50392be..2b656bd 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -1,10 +1,6 @@ name: Unit Tests with docker compose on: [pull_request] -runs: - using: - composite - jobs: unit-test: container: From 47c6127cb8635088c9c58012037f628c2048b991 Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 7 Jan 2024 13:12:19 +0100 Subject: [PATCH 112/133] Use alder version --- .gitea/workflows/build.yaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 808bb52..6dbac5e 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -8,19 +8,19 @@ on: jobs: unit-test: container: - image: catthehacker/ubuntu:act-22.04 + image: node:16-bullseye-slim steps: - name: Checkout - uses: actions/checkout@v4 - - name: Run test job + uses: actions/checkout@v3 + - name: Run test job uses: ./.gitea/workflows/test.yaml build: container: - image: catthehacker/ubuntu:act-22.04 + image: node:16-bullseye-slim needs: unit-test steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v3 - name: Docker meta id: meta uses: docker/metadata-action@v5 @@ -28,13 +28,13 @@ jobs: # list of Docker images to use as base name for tags images: | fedi-image-bot/bot-api - git.fai.st/fedi-image-bot/bot-api + git.fai.st/fedi-image-bot/bot-api # generate Docker tags based on the following events/attributes tags: | type=schedule type=ref,event=branch type=ref,event=pr - type=sha + type=sha - name: Set up QEMU # Add support for more platforms with QEMU (optional) # https://github.com/docker/setup-qemu-action @@ -55,4 +55,4 @@ jobs: tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=registry,ref=fedi-image-bot/bot-api:latest - cache-to: type=inline + cache-to: type=inline \ No newline at end of file From 1f67f0c9e380e3d5a52e0b57ba7ef90a271dc189 Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 7 Jan 2024 13:15:08 +0100 Subject: [PATCH 113/133] act is useless --- .gitea/workflows/build.yaml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 6dbac5e..21e52a2 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -8,17 +8,21 @@ on: jobs: unit-test: container: - image: node:16-bullseye-slim + image: docker:dind steps: + - name: Installing necessary packages + run: apk add nodejs git curl bash - name: Checkout uses: actions/checkout@v3 - name: Run test job uses: ./.gitea/workflows/test.yaml build: container: - image: node:16-bullseye-slim + image: docker:dind needs: unit-test steps: + - name: Installing necessary packages + run: apk add nodejs git curl bash - name: Checkout uses: actions/checkout@v3 - name: Docker meta From 1e3889d9b9af005598dd21f18c788b2203221a52 Mon Sep 17 00:00:00 2001 From: Sugui Date: Sun, 7 Jan 2024 13:23:58 +0100 Subject: [PATCH 114/133] Added compression for responses --- package.json | 2 + src/app.ts | 2 + yarn.lock | 133 +++++++++++++++++++++++++++++++-------------------- 3 files changed, 86 insertions(+), 51 deletions(-) diff --git a/package.json b/package.json index 1ca452e..3eacec4 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,8 @@ "test": "docker compose down -v && docker compose run bot-api bun test" }, "dependencies": { + "@types/compression": "^1.7.5", + "compression": "^1.7.4", "express": "^4.18.2", "express-list-endpoints": "^6.0.0", "jsonwebtoken": "^9.0.2", diff --git a/src/app.ts b/src/app.ts index e76640e..e7b49fb 100644 --- a/src/app.ts +++ b/src/app.ts @@ -3,10 +3,12 @@ import listEndpoints from "express-list-endpoints"; import imageController from "./controllers/ImageController"; import authControler from "./controllers/AuthControler"; import mongoose from "mongoose"; +import compression from "compression"; export const app = express(); app.use(express.json()); +app.use(compression()); app.get("/", (_, res) => { const endpoints = listEndpoints(app); diff --git a/yarn.lock b/yarn.lock index c99fdb5..f27c39d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1,6 +1,6 @@ # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. # yarn lockfile v1 -# bun ./bun.lockb --hash: 33E2AFF8D14D8AA5-eebd7db9b471377f-95D45A5384DAAEBC-8f83c3f6d7ba1359 +# bun ./bun.lockb --hash: 574898C6F46E031A-7d2c19a7b27d428f-9E2F96E55504E97E-1d2b140cdcb49104 "@ampproject/remapping@^2.2.0": @@ -25,19 +25,19 @@ integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== "@babel/core@>=7.0.0-beta.0 <8", "@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.8.0": - version "7.23.7" - resolved "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz" - integrity sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw== + version "7.23.6" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.23.6.tgz" + integrity sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw== dependencies: "@ampproject/remapping" "^2.2.0" "@babel/code-frame" "^7.23.5" "@babel/generator" "^7.23.6" "@babel/helper-compilation-targets" "^7.23.6" "@babel/helper-module-transforms" "^7.23.3" - "@babel/helpers" "^7.23.7" + "@babel/helpers" "^7.23.6" "@babel/parser" "^7.23.6" "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.7" + "@babel/traverse" "^7.23.6" "@babel/types" "^7.23.6" convert-source-map "^2.0.0" debug "^4.1.0" @@ -138,13 +138,13 @@ resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz" integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== -"@babel/helpers@^7.23.7": - version "7.23.7" - resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.7.tgz" - integrity sha512-6AMnjCoC8wjqBzDHkuqpa7jAKwvMo4dC+lr/TFBz+ucfulO1XMpDnwWPGBNwClOKZ8h6xn5N81W/R5OrcKtCbQ== +"@babel/helpers@^7.23.6": + version "7.23.6" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz" + integrity sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA== dependencies: "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.7" + "@babel/traverse" "^7.23.6" "@babel/types" "^7.23.6" "@babel/highlight@^7.23.4": @@ -268,10 +268,10 @@ "@babel/parser" "^7.22.15" "@babel/types" "^7.22.15" -"@babel/traverse@^7.23.7": - version "7.23.7" - resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz" - integrity sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg== +"@babel/traverse@^7.23.6": + version "7.23.6" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz" + integrity sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ== dependencies: "@babel/code-frame" "^7.23.5" "@babel/generator" "^7.23.6" @@ -596,9 +596,9 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.20.5" - resolved "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz" - integrity sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ== + version "7.20.4" + resolved "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz" + integrity sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA== dependencies: "@babel/types" "^7.20.7" @@ -610,6 +610,13 @@ "@types/connect" "*" "@types/node" "*" +"@types/compression@^1.7.5": + version "1.7.5" + resolved "https://registry.npmjs.org/@types/compression/-/compression-1.7.5.tgz" + integrity sha512-AAQvK5pxMpaT+nDvhHrsBhLSYG5yQdtkaJE1WYieSNY2mVFKAgmU4ks65rkZD5oqnGCFLyQpUr1CqI4DmUMyDg== + dependencies: + "@types/express" "*" + "@types/connect@*": version "3.4.38" resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz" @@ -711,16 +718,16 @@ integrity sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw== "@types/node@*": - version "20.10.6" - resolved "https://registry.npmjs.org/@types/node/-/node-20.10.6.tgz" - integrity sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw== + version "20.10.4" + resolved "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz" + integrity sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg== dependencies: undici-types "~5.26.4" "@types/qs@*": - version "6.9.11" - resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz" - integrity sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ== + version "6.9.10" + resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz" + integrity sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw== "@types/range-parser@*": version "1.2.7" @@ -759,9 +766,9 @@ "@types/methods" "^1.1.4" "@types/supertest@^6.0.1": - version "6.0.2" - resolved "https://registry.npmjs.org/@types/supertest/-/supertest-6.0.2.tgz" - integrity sha512-137ypx2lk/wTQbW6An6safu9hXmajAifU/s7szAHLN/FeIm5w7yR0Wkl9fdJMRSHwOn4HLAI0DaB2TOORuhPDg== + version "6.0.1" + resolved "https://registry.npmjs.org/@types/supertest/-/supertest-6.0.1.tgz" + integrity sha512-M1xs8grAWC4RisSEQjyQV0FZzXnL3y796540Q/HCdiPcErwKpcAfvsNQFb4xp+5btSWMOZG1YlDWs2z96pdbcw== dependencies: "@types/methods" "^1.1.4" "@types/superagent" "^8.1.0" @@ -779,13 +786,6 @@ "@types/node" "*" "@types/webidl-conversions" "*" -"@types/ws@*": - version "8.5.10" - resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz" - integrity sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A== - dependencies: - "@types/node" "*" - "@types/yargs@^17.0.8": version "17.0.32" resolved "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz" @@ -798,7 +798,7 @@ resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz" integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== -accepts@~1.3.8: +accepts@~1.3.5, accepts@~1.3.8: version "1.3.8" resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== @@ -867,7 +867,7 @@ asynckit@^0.4.0: resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== -babel-jest@^29.7.0: +babel-jest@^29.0.0, babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz" integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== @@ -1005,13 +1005,14 @@ buffer-from@^1.0.0: integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== bun-types@latest: - version "1.0.21" - resolved "https://registry.npmjs.org/bun-types/-/bun-types-1.0.21.tgz" - integrity sha512-Ugagjf+XZUXDvxDRa3EnhLeMzm2g8ZYFleBF55Ac3GZSzPqdMLAdK9kvZB6M1H4nAFvrEHdV2PHqkzIoNs+3wQ== - dependencies: - "@types/node" "*" - "@types/ws" "*" - undici-types "^5.26.4" + version "1.0.15" + resolved "https://registry.npmjs.org/bun-types/-/bun-types-1.0.15.tgz" + integrity sha512-XkEvWLV1JIhcVIpf2Lu6FXnZUxRUkQVJmgY+VT7os6Tk5X1nkXx11q4Rtu6txsqpDJZfUeZXblnnD59K+6wsVA== + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz" + integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== bytes@3.1.2: version "3.1.2" @@ -1043,9 +1044,9 @@ camelcase@^6.2.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001565: - version "1.0.30001574" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001574.tgz" - integrity sha512-BtYEK4r/iHt/txm81KBudCUcTy7t+s9emrIaHqjYurQ10x71zJ5VQ9x1dYPcz/b+pKSp4y/v1xSI67A+LzpNyg== + version "1.0.30001571" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001571.tgz" + integrity sha512-tYq/6MoXhdezDLFZuCO/TKboTzuQ/xR5cFdgXPfDtM7/kchBO3b4VWghE/OAi/DV7tTdhmLjZiZBZi1fA/GheQ== chalk@^2.4.2: version "2.4.2" @@ -1134,6 +1135,26 @@ component-emitter@^1.3.0: resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz" integrity sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ== +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + concat-map@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" @@ -1272,9 +1293,9 @@ ee-first@1.1.1: integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== electron-to-chromium@^1.4.601: - version "1.4.623" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.623.tgz" - integrity sha512-lKoz10iCYlP1WtRYdh5MvocQPWVRoI7ysp6qf18bmeBgR8abE6+I2CsfyNKztRDZvhdWc+krKT6wS7Neg8sw3A== + version "1.4.616" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.616.tgz" + integrity sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg== emittery@^0.13.1: version "0.13.1" @@ -2304,7 +2325,7 @@ mime@2.6.0: resolved "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz" integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== -mime-db@1.52.0: +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": version "1.52.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== @@ -2429,6 +2450,11 @@ on-finished@2.4.1: dependencies: ee-first "1.1.1" +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + once@^1.3.0, once@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" @@ -2624,6 +2650,11 @@ resolve.exports@^2.0.0: resolved "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz" integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== +safe-buffer@5.1.2: + version "5.1.2" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + safe-buffer@5.2.1, safe-buffer@^5.0.1: version "5.2.1" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" @@ -2932,7 +2963,7 @@ type-is@~1.6.18: resolved "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz" integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== -undici-types@^5.26.4, undici-types@~5.26.4: +undici-types@~5.26.4: version "5.26.5" resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== From 5917aa0fd8d06a5109bb73826e50724d3ac4f3c3 Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 7 Jan 2024 13:24:53 +0100 Subject: [PATCH 115/133] just copy paste because seems imposible otherwise --- .gitea/workflows/build.yaml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 21e52a2..b5f58e4 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -9,13 +9,21 @@ jobs: unit-test: container: image: docker:dind + volumes: + - /usr/local/share/.cache/yarn:/usr/local/share/.cache/yarn + - /var/lib/docker/image:/var/lib/docker/image + - /var/lib/docker/overlay2:/var/lib/docker/overlay2 steps: + - name: Starting docker daemon + run: docker-init -- dockerd --host=unix:///var/run/docker.sock & - name: Installing necessary packages - run: apk add nodejs git curl bash - - name: Checkout + run: apk add yarn git curl bash + - name: Check out repository code uses: actions/checkout@v3 - - name: Run test job - uses: ./.gitea/workflows/test.yaml + - name: Install project dependencies + run: yarn install --frozen-lockfile --ignore-scripts + - name: Run docker-compose + run: docker compose down -v && docker compose run bot-api bun test build: container: image: docker:dind From 198fcd0b02f1ea9ca1e5e5ab607256b453cacc2c Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 7 Jan 2024 13:32:01 +0100 Subject: [PATCH 116/133] use oficial github action isntead of forgejo since its not on forgejo --- .gitea/workflows/build.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index b5f58e4..fb3cab0 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -1,4 +1,4 @@ -name: Test via test action and then build image +name: Test and build image on: push: branches: @@ -35,7 +35,7 @@ jobs: uses: actions/checkout@v3 - name: Docker meta id: meta - uses: docker/metadata-action@v5 + uses: https://github.com/docker/metadata-action@v5 with: # list of Docker images to use as base name for tags images: | From 847400a7b4f5f77711d3a596fd82cea9f4f160ce Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 7 Jan 2024 13:35:30 +0100 Subject: [PATCH 117/133] lover versions --- .gitea/workflows/build.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index fb3cab0..195c1cf 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -35,7 +35,7 @@ jobs: uses: actions/checkout@v3 - name: Docker meta id: meta - uses: https://github.com/docker/metadata-action@v5 + uses: https://github.com/docker/metadata-action@v4 with: # list of Docker images to use as base name for tags images: | @@ -50,17 +50,17 @@ jobs: - name: Set up QEMU # Add support for more platforms with QEMU (optional) # https://github.com/docker/setup-qemu-action - uses: docker/setup-qemu-action@v3 + uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v2 - name: Login to fai.st docker registry - uses: docker/login-action@v3 + uses: docker/login-action@v2 with: registry: git.fai.st username: ${{ secrets.DOCKER_USER }} password: ${{ secrets.DOCKER_PASS }} - name: Build and push - uses: docker/build-push-action@v5 + uses: docker/build-push-action@v4 with: platforms: linux/amd64,linux/arm64 push: true From a3f342b168bbeced5d5d951ce668e398f0ae061c Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 7 Jan 2024 13:39:53 +0100 Subject: [PATCH 118/133] I need the dockers --- .gitea/workflows/build.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 195c1cf..07edd88 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -29,6 +29,8 @@ jobs: image: docker:dind needs: unit-test steps: + - name: Starting docker daemon + run: docker-init -- dockerd --host=unix:///var/run/docker.sock & - name: Installing necessary packages run: apk add nodejs git curl bash - name: Checkout From 2c79a2ebfd5dd41df0a35c159a96871677fc1e34 Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 7 Jan 2024 14:00:39 +0100 Subject: [PATCH 119/133] v3 --- .gitea/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 07edd88..7fab82a 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -56,7 +56,7 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Login to fai.st docker registry - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: registry: git.fai.st username: ${{ secrets.DOCKER_USER }} From 6979e5451ec8275372587ef50f4ba583443c968d Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 7 Jan 2024 14:04:42 +0100 Subject: [PATCH 120/133] just login manually instead of using action --- .gitea/workflows/build.yaml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 7fab82a..079e565 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -56,11 +56,7 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Login to fai.st docker registry - uses: docker/login-action@v3 - with: - registry: git.fai.st - username: ${{ secrets.DOCKER_USER }} - password: ${{ secrets.DOCKER_PASS }} + run: docker login git.fai.st -u ${{ secrets.DOCKER_USER }} -p ${{ secrets.DOCKER_PASS }} - name: Build and push uses: docker/build-push-action@v4 with: From b258d4cdc49067b4affa3ac4cd1a547b5d53801f Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 7 Jan 2024 14:14:56 +0100 Subject: [PATCH 121/133] use local checked out repo --- .gitea/workflows/build.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 079e565..c5a1662 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -61,6 +61,7 @@ jobs: uses: docker/build-push-action@v4 with: platforms: linux/amd64,linux/arm64 + context: . push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} From 88ca6bc77044625e33ec39b0c7eb3fc6f41a3729 Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 7 Jan 2024 14:15:37 +0100 Subject: [PATCH 122/133] use cache --- .gitea/workflows/build.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index c5a1662..1bc106c 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -27,6 +27,10 @@ jobs: build: container: image: docker:dind + volumes: + - /data/.cache/act:/data/.cache/act + - /var/lib/docker/image:/var/lib/docker/image + - /var/lib/docker/overlay2:/var/lib/docker/overlay2 needs: unit-test steps: - name: Starting docker daemon From c75e92427f20e794adad47b25f28820a15aad8e2 Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 7 Jan 2024 14:32:12 +0100 Subject: [PATCH 123/133] seems to work on the host but fails on the next step so i fixed that one --- .gitea/workflows/build.yaml | 6 +++++- Dockerfile | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index 1bc106c..a8c3b75 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -60,7 +60,11 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Login to fai.st docker registry - run: docker login git.fai.st -u ${{ secrets.DOCKER_USER }} -p ${{ secrets.DOCKER_PASS }} + uses: docker/login-action@v2 + with: + registry: git.fai.st + username: ${{ secrets.DOCKER_USER }} + password: ${{ secrets.DOCKER_PASS }} - name: Build and push uses: docker/build-push-action@v4 with: diff --git a/Dockerfile b/Dockerfile index 2314c7c..cb090b3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,7 +11,7 @@ FROM base AS install # install with --production (exclude devDependencies) RUN mkdir -p /temp/prod -COPY package.json bun.lockb /temp/prod/ +COPY package.json yarn.lock /temp/prod/ RUN cd /temp/prod && bun install --production # Copy production dependencies and source code into final image From 5d705482f94713445937db11fc63c8ce36484ecf Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 7 Jan 2024 14:55:41 +0100 Subject: [PATCH 124/133] chare build cache --- .gitea/workflows/build.yaml | 2 ++ .gitea/workflows/test.yaml | 1 + 2 files changed, 3 insertions(+) diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml index a8c3b75..2a2ea63 100644 --- a/.gitea/workflows/build.yaml +++ b/.gitea/workflows/build.yaml @@ -13,6 +13,7 @@ jobs: - /usr/local/share/.cache/yarn:/usr/local/share/.cache/yarn - /var/lib/docker/image:/var/lib/docker/image - /var/lib/docker/overlay2:/var/lib/docker/overlay2 + - /var/lib/docker/buildkit:/var/lib/docker/buildkit steps: - name: Starting docker daemon run: docker-init -- dockerd --host=unix:///var/run/docker.sock & @@ -31,6 +32,7 @@ jobs: - /data/.cache/act:/data/.cache/act - /var/lib/docker/image:/var/lib/docker/image - /var/lib/docker/overlay2:/var/lib/docker/overlay2 + - /var/lib/docker/buildkit:/var/lib/docker/buildkit needs: unit-test steps: - name: Starting docker daemon diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 2b656bd..0bc60e6 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -9,6 +9,7 @@ jobs: - /usr/local/share/.cache/yarn:/usr/local/share/.cache/yarn - /var/lib/docker/image:/var/lib/docker/image - /var/lib/docker/overlay2:/var/lib/docker/overlay2 + - /var/lib/docker/buildkit:/var/lib/docker/buildkit steps: - name: Starting docker daemon run: docker-init -- dockerd --host=unix:///var/run/docker.sock & From f0c19e39f185ff9c76c392808809f9ddc954c35d Mon Sep 17 00:00:00 2001 From: Sugui Date: Tue, 9 Jan 2024 17:15:56 +0100 Subject: [PATCH 125/133] Fixed typo --- tests/app.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/app.test.ts b/tests/app.test.ts index d7c78f7..aa959e6 100644 --- a/tests/app.test.ts +++ b/tests/app.test.ts @@ -27,7 +27,7 @@ afterEach(() => { })); }); -describe("/login works as instended", async () => { +describe("/login works as intended", async () => { let correctRespose: Response; beforeAll(async () => { correctRespose = await request(app) From 7a607e129ceb8c7fac5b9e283b9f2d4522d485bf Mon Sep 17 00:00:00 2001 From: Alie Date: Tue, 9 Jan 2024 19:59:51 +0100 Subject: [PATCH 126/133] delete build yaml and roll back buiuld cache sharing --- .gitea/workflows/build.yaml | 79 ------------------------------------- .gitea/workflows/test.yaml | 8 +++- 2 files changed, 6 insertions(+), 81 deletions(-) delete mode 100644 .gitea/workflows/build.yaml diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml deleted file mode 100644 index 2a2ea63..0000000 --- a/.gitea/workflows/build.yaml +++ /dev/null @@ -1,79 +0,0 @@ -name: Test and build image -on: - push: - branches: - - main - - develop - -jobs: - unit-test: - container: - image: docker:dind - volumes: - - /usr/local/share/.cache/yarn:/usr/local/share/.cache/yarn - - /var/lib/docker/image:/var/lib/docker/image - - /var/lib/docker/overlay2:/var/lib/docker/overlay2 - - /var/lib/docker/buildkit:/var/lib/docker/buildkit - steps: - - name: Starting docker daemon - run: docker-init -- dockerd --host=unix:///var/run/docker.sock & - - name: Installing necessary packages - run: apk add yarn git curl bash - - name: Check out repository code - uses: actions/checkout@v3 - - name: Install project dependencies - run: yarn install --frozen-lockfile --ignore-scripts - - name: Run docker-compose - run: docker compose down -v && docker compose run bot-api bun test - build: - container: - image: docker:dind - volumes: - - /data/.cache/act:/data/.cache/act - - /var/lib/docker/image:/var/lib/docker/image - - /var/lib/docker/overlay2:/var/lib/docker/overlay2 - - /var/lib/docker/buildkit:/var/lib/docker/buildkit - needs: unit-test - steps: - - name: Starting docker daemon - run: docker-init -- dockerd --host=unix:///var/run/docker.sock & - - name: Installing necessary packages - run: apk add nodejs git curl bash - - name: Checkout - uses: actions/checkout@v3 - - name: Docker meta - id: meta - uses: https://github.com/docker/metadata-action@v4 - with: - # list of Docker images to use as base name for tags - images: | - fedi-image-bot/bot-api - git.fai.st/fedi-image-bot/bot-api - # generate Docker tags based on the following events/attributes - tags: | - type=schedule - type=ref,event=branch - type=ref,event=pr - type=sha - - name: Set up QEMU - # Add support for more platforms with QEMU (optional) - # https://github.com/docker/setup-qemu-action - uses: docker/setup-qemu-action@v2 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - name: Login to fai.st docker registry - uses: docker/login-action@v2 - with: - registry: git.fai.st - username: ${{ secrets.DOCKER_USER }} - password: ${{ secrets.DOCKER_PASS }} - - name: Build and push - uses: docker/build-push-action@v4 - with: - platforms: linux/amd64,linux/arm64 - context: . - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - cache-from: type=registry,ref=fedi-image-bot/bot-api:latest - cache-to: type=inline \ No newline at end of file diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/test.yaml index 0bc60e6..cc76118 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/test.yaml @@ -1,5 +1,10 @@ name: Unit Tests with docker compose -on: [pull_request] +on: + pull_request: + push: + branches: + - main + - develop jobs: unit-test: @@ -9,7 +14,6 @@ jobs: - /usr/local/share/.cache/yarn:/usr/local/share/.cache/yarn - /var/lib/docker/image:/var/lib/docker/image - /var/lib/docker/overlay2:/var/lib/docker/overlay2 - - /var/lib/docker/buildkit:/var/lib/docker/buildkit steps: - name: Starting docker daemon run: docker-init -- dockerd --host=unix:///var/run/docker.sock & From 59b59030b559576e92309f28e98612f160775a56 Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 12 Jan 2024 16:13:02 +0100 Subject: [PATCH 127/133] added winston logger and log important functions such as auth --- package.json | 3 +- src/app.ts | 5 +- src/controllers/AuthControler.ts | 25 +-- src/logger.ts | 17 ++ yarn.lock | 261 ++++++++++++++++++++++++++----- 5 files changed, 255 insertions(+), 56 deletions(-) create mode 100644 src/logger.ts diff --git a/package.json b/package.json index 3eacec4..51ef3eb 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "express": "^4.18.2", "express-list-endpoints": "^6.0.0", "jsonwebtoken": "^9.0.2", - "mongoose": "^8.0.3" + "mongoose": "^8.0.3", + "winston": "^3.11.0" } } diff --git a/src/app.ts b/src/app.ts index e7b49fb..6107852 100644 --- a/src/app.ts +++ b/src/app.ts @@ -4,6 +4,7 @@ import imageController from "./controllers/ImageController"; import authControler from "./controllers/AuthControler"; import mongoose from "mongoose"; import compression from "compression"; +import logger from "./logger"; export const app = express(); @@ -35,10 +36,10 @@ export const startApp = async () => { }); mongoose.set("runValidators", true); app.listen(port, () => - console.log(`Express server listening on port ${port}`) + logger.info(`Express server listening on port ${port}`) ); } catch (error) { - console.error(error); + logger.error(error); process.exit(1); } }; diff --git a/src/controllers/AuthControler.ts b/src/controllers/AuthControler.ts index 335e11a..80cda4c 100644 --- a/src/controllers/AuthControler.ts +++ b/src/controllers/AuthControler.ts @@ -1,6 +1,7 @@ -import jwt from "jsonwebtoken"; +import jwt, { JwtPayload } from "jsonwebtoken"; import AuthService from "../services/AuthService"; import { Request, Response, NextFunction } from "express"; +import logger from "../logger"; const authTokenSecret = process.env.JWTSECRET || "badsecret"; @@ -13,18 +14,15 @@ class AuthControler { const authenticated = await AuthService.find(app, secret); if (authenticated) { - console.log("Authenticated app", authenticated.app); + logger.info("Authenticated app", authenticated.app); // Generate an access token - const accessToken = jwt.sign( - { app: authenticated.app }, - authTokenSecret, - { expiresIn: "1h" } - ); - - res.json({ - token: accessToken, + const token = jwt.sign({ app: authenticated.app }, authTokenSecret, { + expiresIn: "1h", }); + + res.json({ token }); } else { + logger.warn("Authentication attempt for", app); res.status(403).send("Credentials incorrect"); } } @@ -34,10 +32,15 @@ class AuthControler { if (authHeader) { const token = authHeader.split(" ")[1]; - jwt.verify(token, authTokenSecret, (err, _) => { + jwt.verify(token, authTokenSecret, (err, app) => { if (err) { return res.status(403).json("Invalid token provided"); } + logger.info( + `Authorization for ${req.method} ${req.url} provided to app ${ + (app as JwtPayload).app + } ` + ); next(); }); } else { diff --git a/src/logger.ts b/src/logger.ts new file mode 100644 index 0000000..fe55880 --- /dev/null +++ b/src/logger.ts @@ -0,0 +1,17 @@ +import winston, { format } from "winston"; + +const logger = winston.createLogger({ + format: format.combine( + format.timestamp(), + format.align(), + format.colorize({ all: true }), + format.printf((info) => `${info.timestamp} ${info.level}:${info.message}`) + ), +}); + +const files = new winston.transports.File({ filename: "/tmp/express.log" }); +const console = new winston.transports.Console(); + +logger.clear().add(files).add(console); + +export default logger; diff --git a/yarn.lock b/yarn.lock index f27c39d..3293ba7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1,6 +1,6 @@ # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. # yarn lockfile v1 -# bun ./bun.lockb --hash: 574898C6F46E031A-7d2c19a7b27d428f-9E2F96E55504E97E-1d2b140cdcb49104 +# bun ./bun.lockb --hash: 9B0DB2A6DDF32440-fedbc92538df07cc-E7A3C1DB0A83DF66-732fbcf575fe4b52 "@ampproject/remapping@^2.2.0": @@ -25,19 +25,19 @@ integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== "@babel/core@>=7.0.0-beta.0 <8", "@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.8.0": - version "7.23.6" - resolved "https://registry.npmjs.org/@babel/core/-/core-7.23.6.tgz" - integrity sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw== + version "7.23.7" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz" + integrity sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw== dependencies: "@ampproject/remapping" "^2.2.0" "@babel/code-frame" "^7.23.5" "@babel/generator" "^7.23.6" "@babel/helper-compilation-targets" "^7.23.6" "@babel/helper-module-transforms" "^7.23.3" - "@babel/helpers" "^7.23.6" + "@babel/helpers" "^7.23.7" "@babel/parser" "^7.23.6" "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.6" + "@babel/traverse" "^7.23.7" "@babel/types" "^7.23.6" convert-source-map "^2.0.0" debug "^4.1.0" @@ -138,13 +138,13 @@ resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz" integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== -"@babel/helpers@^7.23.6": - version "7.23.6" - resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.6.tgz" - integrity sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA== +"@babel/helpers@^7.23.7": + version "7.23.7" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.7.tgz" + integrity sha512-6AMnjCoC8wjqBzDHkuqpa7jAKwvMo4dC+lr/TFBz+ucfulO1XMpDnwWPGBNwClOKZ8h6xn5N81W/R5OrcKtCbQ== dependencies: "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.6" + "@babel/traverse" "^7.23.7" "@babel/types" "^7.23.6" "@babel/highlight@^7.23.4": @@ -268,10 +268,10 @@ "@babel/parser" "^7.22.15" "@babel/types" "^7.22.15" -"@babel/traverse@^7.23.6": - version "7.23.6" - resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz" - integrity sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ== +"@babel/traverse@^7.23.7": + version "7.23.7" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz" + integrity sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg== dependencies: "@babel/code-frame" "^7.23.5" "@babel/generator" "^7.23.6" @@ -298,6 +298,20 @@ resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@colors/colors@1.6.0", "@colors/colors@^1.6.0": + version "1.6.0" + resolved "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz" + integrity sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA== + +"@dabh/diagnostics@^2.0.2": + version "2.0.3" + resolved "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz" + integrity sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA== + dependencies: + colorspace "1.1.x" + enabled "2.0.x" + kuler "^2.0.0" + "@faker-js/faker@^8.3.1": version "8.3.1" resolved "https://registry.npmjs.org/@faker-js/faker/-/faker-8.3.1.tgz" @@ -596,9 +610,9 @@ "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.20.4" - resolved "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.4.tgz" - integrity sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA== + version "7.20.5" + resolved "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz" + integrity sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ== dependencies: "@babel/types" "^7.20.7" @@ -718,16 +732,16 @@ integrity sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw== "@types/node@*": - version "20.10.4" - resolved "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz" - integrity sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg== + version "20.10.6" + resolved "https://registry.npmjs.org/@types/node/-/node-20.10.6.tgz" + integrity sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw== dependencies: undici-types "~5.26.4" "@types/qs@*": - version "6.9.10" - resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.10.tgz" - integrity sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw== + version "6.9.11" + resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.11.tgz" + integrity sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ== "@types/range-parser@*": version "1.2.7" @@ -766,13 +780,18 @@ "@types/methods" "^1.1.4" "@types/supertest@^6.0.1": - version "6.0.1" - resolved "https://registry.npmjs.org/@types/supertest/-/supertest-6.0.1.tgz" - integrity sha512-M1xs8grAWC4RisSEQjyQV0FZzXnL3y796540Q/HCdiPcErwKpcAfvsNQFb4xp+5btSWMOZG1YlDWs2z96pdbcw== + version "6.0.2" + resolved "https://registry.npmjs.org/@types/supertest/-/supertest-6.0.2.tgz" + integrity sha512-137ypx2lk/wTQbW6An6safu9hXmajAifU/s7szAHLN/FeIm5w7yR0Wkl9fdJMRSHwOn4HLAI0DaB2TOORuhPDg== dependencies: "@types/methods" "^1.1.4" "@types/superagent" "^8.1.0" +"@types/triple-beam@^1.3.2": + version "1.3.5" + resolved "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz" + integrity sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw== + "@types/webidl-conversions@*": version "7.0.3" resolved "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.3.tgz" @@ -786,6 +805,13 @@ "@types/node" "*" "@types/webidl-conversions" "*" +"@types/ws@*": + version "8.5.10" + resolved "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz" + integrity sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A== + dependencies: + "@types/node" "*" + "@types/yargs@^17.0.8": version "17.0.32" resolved "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz" @@ -862,12 +888,17 @@ asap@^2.0.0: resolved "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz" integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== +async@^3.2.3: + version "3.2.5" + resolved "https://registry.npmjs.org/async/-/async-3.2.5.tgz" + integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== -babel-jest@^29.0.0, babel-jest@^29.7.0: +babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz" integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== @@ -1005,9 +1036,13 @@ buffer-from@^1.0.0: integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== bun-types@latest: - version "1.0.15" - resolved "https://registry.npmjs.org/bun-types/-/bun-types-1.0.15.tgz" - integrity sha512-XkEvWLV1JIhcVIpf2Lu6FXnZUxRUkQVJmgY+VT7os6Tk5X1nkXx11q4Rtu6txsqpDJZfUeZXblnnD59K+6wsVA== + version "1.0.21" + resolved "https://registry.npmjs.org/bun-types/-/bun-types-1.0.21.tgz" + integrity sha512-Ugagjf+XZUXDvxDRa3EnhLeMzm2g8ZYFleBF55Ac3GZSzPqdMLAdK9kvZB6M1H4nAFvrEHdV2PHqkzIoNs+3wQ== + dependencies: + "@types/node" "*" + "@types/ws" "*" + undici-types "^5.26.4" bytes@3.0.0: version "3.0.0" @@ -1044,9 +1079,9 @@ camelcase@^6.2.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001565: - version "1.0.30001571" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001571.tgz" - integrity sha512-tYq/6MoXhdezDLFZuCO/TKboTzuQ/xR5cFdgXPfDtM7/kchBO3b4VWghE/OAi/DV7tTdhmLjZiZBZi1fA/GheQ== + version "1.0.30001574" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001574.tgz" + integrity sha512-BtYEK4r/iHt/txm81KBudCUcTy7t+s9emrIaHqjYurQ10x71zJ5VQ9x1dYPcz/b+pKSp4y/v1xSI67A+LzpNyg== chalk@^2.4.2: version "2.4.2" @@ -1099,7 +1134,15 @@ collect-v8-coverage@^1.0.0: resolved "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz" integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== -color-convert@^1.9.0: +color@^3.1.3: + version "3.2.1" + resolved "https://registry.npmjs.org/color/-/color-3.2.1.tgz" + integrity sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA== + dependencies: + color-convert "^1.9.3" + color-string "^1.6.0" + +color-convert@^1.9.0, color-convert@^1.9.3: version "1.9.3" resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== @@ -1118,11 +1161,27 @@ color-name@1.1.3: resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== -color-name@~1.1.4: +color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-string@^1.6.0: + version "1.9.1" + resolved "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz" + integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +colorspace@1.1.x: + version "1.1.4" + resolved "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz" + integrity sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w== + dependencies: + color "^3.1.3" + text-hex "1.0.x" + combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" @@ -1293,9 +1352,9 @@ ee-first@1.1.1: integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== electron-to-chromium@^1.4.601: - version "1.4.616" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.616.tgz" - integrity sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg== + version "1.4.623" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.623.tgz" + integrity sha512-lKoz10iCYlP1WtRYdh5MvocQPWVRoI7ysp6qf18bmeBgR8abE6+I2CsfyNKztRDZvhdWc+krKT6wS7Neg8sw3A== emittery@^0.13.1: version "0.13.1" @@ -1307,6 +1366,11 @@ emoji-regex@^8.0.0: resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +enabled@2.0.x: + version "2.0.0" + resolved "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz" + integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ== + encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz" @@ -1444,6 +1508,11 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" +fecha@^4.2.0: + version "4.2.3" + resolved "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz" + integrity sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw== + fill-range@^7.0.1: version "7.0.1" resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" @@ -1472,6 +1541,11 @@ find-up@^4.0.0, find-up@^4.1.0: locate-path "^5.0.0" path-exists "^4.0.0" +fn.name@1.x.x: + version "1.1.0" + resolved "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz" + integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== + form-data@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz" @@ -1663,7 +1737,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4: +inherits@2, inherits@2.0.4, inherits@^2.0.3: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -1678,6 +1752,11 @@ is-arrayish@^0.2.1: resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + is-core-module@^2.13.0: version "2.13.1" resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz" @@ -2192,6 +2271,11 @@ kleur@^3.0.3: resolved "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== +kuler@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz" + integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== + leven@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz" @@ -2249,6 +2333,18 @@ lodash.once@^4.0.0: resolved "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz" integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== +logform@^2.3.2, logform@^2.4.0: + version "2.6.0" + resolved "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz" + integrity sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ== + dependencies: + "@colors/colors" "1.6.0" + "@types/triple-beam" "^1.3.2" + fecha "^4.2.0" + ms "^2.1.1" + safe-stable-stringify "^2.3.1" + triple-beam "^1.3.0" + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" @@ -2462,6 +2558,13 @@ once@^1.3.0, once@^1.4.0: dependencies: wrappy "1" +one-time@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz" + integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g== + dependencies: + fn.name "1.x.x" + onetime@^5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" @@ -2619,6 +2722,15 @@ react-is@^18.0.0: resolved "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== +readable-stream@^3.4.0, readable-stream@^3.6.0: + version "3.6.2" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" @@ -2655,11 +2767,16 @@ safe-buffer@5.1.2: resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.2.1, safe-buffer@^5.0.1: +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-stable-stringify@^2.3.1: + version "2.4.3" + resolved "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz" + integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== + "safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" @@ -2752,6 +2869,13 @@ signal-exit@^3.0.3, signal-exit@^3.0.7: resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz" + integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg== + dependencies: + is-arrayish "^0.3.1" + sisteransi@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz" @@ -2787,6 +2911,11 @@ sprintf-js@~1.0.2: resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== +stack-trace@0.0.x: + version "0.0.10" + resolved "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz" + integrity sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg== + stack-utils@^2.0.3: version "2.0.6" resolved "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz" @@ -2816,6 +2945,13 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" @@ -2897,6 +3033,11 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" +text-hex@1.0.x: + version "1.0.0" + resolved "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz" + integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== + tmpl@1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz" @@ -2926,6 +3067,11 @@ tr46@^3.0.0: dependencies: punycode "^2.1.1" +triple-beam@^1.3.0: + version "1.4.1" + resolved "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz" + integrity sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg== + ts-jest@^29.1.1: version "29.1.1" resolved "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.1.tgz" @@ -2963,7 +3109,7 @@ type-is@~1.6.18: resolved "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz" integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== -undici-types@~5.26.4: +undici-types@^5.26.4, undici-types@~5.26.4: version "5.26.5" resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== @@ -2981,6 +3127,11 @@ update-browserslist-db@^1.0.13: escalade "^3.1.1" picocolors "^1.0.0" +util-deprecate@^1.0.1: + version "1.0.2" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + utils-merge@1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" @@ -3027,6 +3178,32 @@ which@^2.0.1: dependencies: isexe "^2.0.0" +winston@^3.11.0: + version "3.11.0" + resolved "https://registry.npmjs.org/winston/-/winston-3.11.0.tgz" + integrity sha512-L3yR6/MzZAOl0DsysUXHVjOwv8mKZ71TrA/41EIduGpOOV5LQVodqN+QdQ6BS6PJ/RdIshZhq84P/fStEZkk7g== + dependencies: + "@dabh/diagnostics" "^2.0.2" + "@colors/colors" "^1.6.0" + async "^3.2.3" + is-stream "^2.0.0" + logform "^2.4.0" + one-time "^1.0.0" + readable-stream "^3.4.0" + safe-stable-stringify "^2.3.1" + stack-trace "0.0.x" + triple-beam "^1.3.0" + winston-transport "^4.5.0" + +winston-transport@^4.5.0: + version "4.6.0" + resolved "https://registry.npmjs.org/winston-transport/-/winston-transport-4.6.0.tgz" + integrity sha512-wbBA9PbPAHxKiygo7ub7BYRiKxms0tpfU2ljtWzb3SjRjv5yl6Ozuy/TkXf00HTAt+Uylo3gSkNwzc4ME0wiIg== + dependencies: + logform "^2.3.2" + readable-stream "^3.6.0" + triple-beam "^1.3.0" + wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" From b19dea31d5be040d228aa57bfdb6ab3db8323a37 Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 12 Jan 2024 16:14:29 +0100 Subject: [PATCH 128/133] fmt --- tests/populateDatabase.ts | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/tests/populateDatabase.ts b/tests/populateDatabase.ts index 041f830..ab21f45 100644 --- a/tests/populateDatabase.ts +++ b/tests/populateDatabase.ts @@ -1,20 +1,37 @@ import authModel from "../src/models/AuthModel"; -import imageModel, { Image } from "../src/models/ImageModel"; +import imageModel from "../src/models/ImageModel"; import { faker } from "@faker-js/faker"; -import { EnforceUniqueError, UniqueEnforcer } from 'enforce-unique'; +import { UniqueEnforcer } from "enforce-unique"; const uniqueEnforcer = new UniqueEnforcer(); export default async function () { - const images = faker.helpers.multiple(() => ({ - url: uniqueEnforcer.enforce(faker.internet.url), - status: faker.helpers.arrayElement(["available", "unavailable", "consumed"]), - tags: faker.helpers.arrayElements([ - "2girls", "sleeping", "touhou", - "pokemon", "closed_eyes", "yume_nikki", - "waifu", "computer", "party", "yuru_camp" - ], { min: 0, max: 5 }), - }), {count: {min: 5, max:50}}); + const images = faker.helpers.multiple( + () => ({ + url: uniqueEnforcer.enforce(faker.internet.url), + status: faker.helpers.arrayElement([ + "available", + "unavailable", + "consumed", + ]), + tags: faker.helpers.arrayElements( + [ + "2girls", + "sleeping", + "touhou", + "pokemon", + "closed_eyes", + "yume_nikki", + "waifu", + "computer", + "party", + "yuru_camp", + ], + { min: 0, max: 5 } + ), + }), + { count: { min: 5, max: 50 } } + ); // Wait until all images are inserted await Promise.allSettled(images.map((image) => imageModel.create(image))); From 81373528c050844bfd50898a772bf954b6ddffa2 Mon Sep 17 00:00:00 2001 From: Suguivy Date: Fri, 12 Jan 2024 15:38:04 +0000 Subject: [PATCH 129/133] Documenting endpoints --- README.md | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 62f16e5..c2006ec 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,16 @@ Allows to get a list of image documents. - `status`: an optional parameter, which accepts the values `consumed`, `available` and `unavailable`. It filters the documents that have only the `status` attribute equal to that indicated in the parameter's value. If the parameter is missing, no filter will be applied to the document. #### Example -- `GET /images?limit=5&status=available`: will return 5 documents that have the `available` value in their `status` attribute. +- `GET /images?limit=5&status=available` will return 5 documents that have the `available` value in their `status` attribute. + +### GET `/images/` +Allows to get an image document. + +#### Params +- `id`: the id of the document to be modified. + +#### Example +`GET /images/61f7e48f0c651345677b7775` will get the document referenced by the `id` param. ### PUT `/images/` Modifies an existing image document. The request must provide a JSON-formatted body, with one or more valid document attributes. The existing document attributes will be replaced with the provided new ones. @@ -23,10 +32,20 @@ Modifies an existing image document. The request must provide a JSON-formatted b - `id`: the id of the document to be modified. #### Example -- `PUT /images/61f7e48f0c651345677b7775` with body `{ "status": "consumed" }`: will modify the document referenced by the `id` param, changing their `status` value to `consumed`. +- `PUT /images/61f7e48f0c651345677b7775` with body `{ "status": "consumed" }` will modify the document referenced by the `id` param, changing their `status` value to `consumed`. ### POST `/images` +Allows to insert a new image document. + +#### Example +`POST /images` with body `{ "url": "https://my-images.com/foo.jpg", "status": "available", "tags": ["foo", "bar"] }` will insert the image passed on the request body into the database. + ### POST `/login` +Generates an access token to use in future requests to authenticated endpoints if a valid App and Secret are provided. + +#### Example +`POST /login` with body `{ "app": "example", "secret": "badsecret" }` will return `{ "token": "x.y.z" }` "x.y.z" being a JWT token to use on further requests if the App and Secret are valid. + ## Installation To install dependencies: @@ -41,6 +60,7 @@ bun run dev ``` For testing, remember: + ```bash bun run test ``` From ad37f9d72bbf4ff8834e3da73997420fdb44f080 Mon Sep 17 00:00:00 2001 From: Alie Date: Fri, 12 Jan 2024 17:18:51 +0100 Subject: [PATCH 130/133] add things to dockerignore --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 1822831..edd7ad4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,7 @@ node_modules/ bun.lockb +.vscode +.env +.editorconfig +.idea +coverage* \ No newline at end of file From a05c801236d24ebdb15d5858e1e995ec8992bc0b Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 14 Jan 2024 13:56:46 +0000 Subject: [PATCH 131/133] build (#26) Reviewed-on: https://git.fai.st/fedi-image-bot/bot-api/pulls/26 Co-authored-by: Alie Co-committed-by: Alie --- .gitea/workflows/{test.yaml => 01_test.yaml} | 7 +-- .gitea/workflows/02_build.yaml | 49 ++++++++++++++++ .gitignore | 2 +- Dockerfile | 17 ++++-- package.json | 2 +- src/index.ts | 2 +- yarn.lock | 59 +++++++++++--------- 7 files changed, 96 insertions(+), 42 deletions(-) rename .gitea/workflows/{test.yaml => 01_test.yaml} (90%) create mode 100644 .gitea/workflows/02_build.yaml diff --git a/.gitea/workflows/test.yaml b/.gitea/workflows/01_test.yaml similarity index 90% rename from .gitea/workflows/test.yaml rename to .gitea/workflows/01_test.yaml index cc76118..bc53a23 100644 --- a/.gitea/workflows/test.yaml +++ b/.gitea/workflows/01_test.yaml @@ -1,10 +1,5 @@ name: Unit Tests with docker compose -on: - pull_request: - push: - branches: - - main - - develop +on: [push, pull_request] jobs: unit-test: diff --git a/.gitea/workflows/02_build.yaml b/.gitea/workflows/02_build.yaml new file mode 100644 index 0000000..108e093 --- /dev/null +++ b/.gitea/workflows/02_build.yaml @@ -0,0 +1,49 @@ +name: Build image +on: + push: + branches: + - main + - build +jobs: + build: + container: + image: docker:dind + volumes: + - /data/.cache/act:/data/.cache/act + - /var/lib/docker/image:/var/lib/docker/image + - /var/lib/docker/overlay2:/var/lib/docker/overlay2 + steps: + - name: Starting docker daemon + run: docker-init -- dockerd --host=unix:///var/run/docker.sock & + - name: Installing necessary packages + run: apk add nodejs git curl bash + - name: Checkout + uses: actions/checkout@v3 + - name: Docker meta + id: meta + uses: https://github.com/docker/metadata-action@v4 + with: + # list of Docker images to use as base name for tags + images: | + git.fai.st/fedi-image-bot/bot-api + # generate Docker tags based on the following events/attributes + tags: | + type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }} + type=ref,event=branch + type=sha + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - name: Login to fai.st docker registry + uses: docker/login-action@v2 + with: + registry: git.fai.st + username: ${{ secrets.DOCKER_USER }} + password: ${{ secrets.DOCKER_PASS }} + - name: Build and push + uses: docker/build-push-action@v4 + with: + platforms: linux/amd64,linux/arm64 + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.gitignore b/.gitignore index edd7ad4..f16c346 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,4 @@ bun.lockb .env .editorconfig .idea -coverage* \ No newline at end of file +coverage* diff --git a/Dockerfile b/Dockerfile index cb090b3..ebd13cb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,23 +5,28 @@ FROM oven/bun:1 as base WORKDIR /usr/src/app +# Generate new bun lock +FROM base as lock +RUN mkdir -p /temp/lock +COPY package.json /temp/lock +RUN cd /temp/lock && bun install + # install dependencies into temp folder # this will cache them and speed up future builds FROM base AS install - # install with --production (exclude devDependencies) RUN mkdir -p /temp/prod -COPY package.json yarn.lock /temp/prod/ -RUN cd /temp/prod && bun install --production +COPY --from=lock /temp/lock/package.json /temp/lock/bun.lockb /temp/prod/ +RUN cd /temp/prod && bun install --production --frozen-lockfile # Copy production dependencies and source code into final image FROM base AS release COPY --from=install /temp/prod/node_modules node_modules -COPY --from=install /usr/src/app/src ./src -COPY --from=install /usr/src/app/package.json . +COPY --from=install /temp/prod/package.json . +COPY ./src ./src # run the app USER bun -ENV NODE_ENV=production +ENV NODE_ENV production EXPOSE 8080/tcp CMD ["bun", "run", "start"] diff --git a/package.json b/package.json index 51ef3eb..e36feb8 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "enforce-unique": "^1.2.0", "jest": "^29.7.0", "supertest": "^6.3.3", + "@types/compression": "^1.7.5", "ts-jest": "^29.1.1" }, "peerDependencies": { @@ -25,7 +26,6 @@ "test": "docker compose down -v && docker compose run bot-api bun test" }, "dependencies": { - "@types/compression": "^1.7.5", "compression": "^1.7.4", "express": "^4.18.2", "express-list-endpoints": "^6.0.0", diff --git a/src/index.ts b/src/index.ts index b431ebd..1fc84e5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,3 @@ -import populateDatabase from "../tests/populateDatabase"; import { startApp } from "./app"; await startApp(); @@ -7,6 +6,7 @@ await startApp(); try { // Not insert test data into production if (process.env.NODE_ENV != "production") { + const populateDatabase = require("../tests/populateDatabase"); await populateDatabase(); } } catch {} diff --git a/yarn.lock b/yarn.lock index 3293ba7..84daa2c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1,6 +1,6 @@ # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. # yarn lockfile v1 -# bun ./bun.lockb --hash: 9B0DB2A6DDF32440-fedbc92538df07cc-E7A3C1DB0A83DF66-732fbcf575fe4b52 +# bun ./bun.lockb --hash: 0566846CEF9BC37B-67668f8ef100cf47-BD54633F277319ED-f974ac5408e619f6 "@ampproject/remapping@^2.2.0": @@ -24,7 +24,7 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz" integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== -"@babel/core@>=7.0.0-beta.0 <8", "@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.8.0": +"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.8.0": version "7.23.7" resolved "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz" integrity sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw== @@ -139,9 +139,9 @@ integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== "@babel/helpers@^7.23.7": - version "7.23.7" - resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.7.tgz" - integrity sha512-6AMnjCoC8wjqBzDHkuqpa7jAKwvMo4dC+lr/TFBz+ucfulO1XMpDnwWPGBNwClOKZ8h6xn5N81W/R5OrcKtCbQ== + version "7.23.8" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.8.tgz" + integrity sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ== dependencies: "@babel/template" "^7.22.15" "@babel/traverse" "^7.23.7" @@ -550,17 +550,17 @@ integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== "@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.20" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz" - integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== + version "0.3.21" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.21.tgz" + integrity sha512-SRfKmRe1KvYnxjEMtxEr+J4HIeMX5YBg/qhRHpxEIGjhX1rshcHlnFUE9K0GazhVKWM7B+nARSkV8LuvJdJ5/g== dependencies: "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" "@mongodb-js/saslprep@^1.1.0": - version "1.1.1" - resolved "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.1.tgz" - integrity sha512-t7c5K033joZZMspnHg/gWPE4kandgc2OxE74aYOtGKfgB9VPuVJPix0H6fhmm2erj5PBJ21mqcx34lpIGtUCsQ== + version "1.1.3" + resolved "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.1.3.tgz" + integrity sha512-SyCxhJfmK6MoLNV5SbDpNdUy9SDv5H7y9/9rl3KpnwgTHWuNNMc87zWqbcIZXNWY+aUjxLGLEcvHoLagG4tWCg== dependencies: sparse-bitfield "^3.0.3" @@ -732,9 +732,9 @@ integrity sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw== "@types/node@*": - version "20.10.6" - resolved "https://registry.npmjs.org/@types/node/-/node-20.10.6.tgz" - integrity sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw== + version "20.11.0" + resolved "https://registry.npmjs.org/@types/node/-/node-20.11.0.tgz" + integrity sha512-o9bjXmDNcF7GbM4CNQpmi+TutCgap/K3w1JyKgxAjqx41zp9qlIAVFi0IhCNsJcXolEqLWhbFbEeL0PvYm4pcQ== dependencies: undici-types "~5.26.4" @@ -1036,9 +1036,9 @@ buffer-from@^1.0.0: integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== bun-types@latest: - version "1.0.21" - resolved "https://registry.npmjs.org/bun-types/-/bun-types-1.0.21.tgz" - integrity sha512-Ugagjf+XZUXDvxDRa3EnhLeMzm2g8ZYFleBF55Ac3GZSzPqdMLAdK9kvZB6M1H4nAFvrEHdV2PHqkzIoNs+3wQ== + version "1.0.22" + resolved "https://registry.npmjs.org/bun-types/-/bun-types-1.0.22.tgz" + integrity sha512-JxmXAx6cXb37+rMsn30WRXlz9lbPFR9rQE78hNSoy5wJ8m/nUktkmHpo7xZb/YKDds23ifxWLjDtyni9MeXLgw== dependencies: "@types/node" "*" "@types/ws" "*" @@ -1079,9 +1079,9 @@ camelcase@^6.2.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001565: - version "1.0.30001574" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001574.tgz" - integrity sha512-BtYEK4r/iHt/txm81KBudCUcTy7t+s9emrIaHqjYurQ10x71zJ5VQ9x1dYPcz/b+pKSp4y/v1xSI67A+LzpNyg== + version "1.0.30001576" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001576.tgz" + integrity sha512-ff5BdakGe2P3SQsMsiqmt1Lc8221NR1VzHj5jXN5vBny9A6fpze94HiVV/n7XRosOlsShJcvMv5mdnpjOGCEgg== chalk@^2.4.2: version "2.4.2" @@ -1352,9 +1352,9 @@ ee-first@1.1.1: integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== electron-to-chromium@^1.4.601: - version "1.4.623" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.623.tgz" - integrity sha512-lKoz10iCYlP1WtRYdh5MvocQPWVRoI7ysp6qf18bmeBgR8abE6+I2CsfyNKztRDZvhdWc+krKT6wS7Neg8sw3A== + version "1.4.630" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.630.tgz" + integrity sha512-osHqhtjojpCsACVnuD11xO5g9xaCyw7Qqn/C2KParkMv42i8jrJJgx3g7mkHfpxwhy9MnOJr8+pKOdZ7qzgizg== emittery@^0.13.1: version "0.13.1" @@ -2463,9 +2463,9 @@ mongodb-connection-string-url@^2.6.0: whatwg-url "^11.0.0" mongoose@^8.0.3: - version "8.0.3" - resolved "https://registry.npmjs.org/mongoose/-/mongoose-8.0.3.tgz" - integrity sha512-LJRT0yP4TW14HT4r2RkxqyvoTylMSzWpl5QOeVHTnRggCLQSpkoBdgbUtORFq/mSL2o9cLCPJz+6uzFj25qbHw== + version "8.0.4" + resolved "https://registry.npmjs.org/mongoose/-/mongoose-8.0.4.tgz" + integrity sha512-wN9qvdevX3+922VnLT7CpaZRT3jmVCBOK2QMHMGeScQxDRnFMPpkuI9StEPpZo/3x8t+kbzH7F8RMPsyNwyM4w== dependencies: bson "^6.2.0" kareem "2.5.1" @@ -3109,11 +3109,16 @@ type-is@~1.6.18: resolved "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz" integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== -undici-types@^5.26.4, undici-types@~5.26.4: +undici-types@~5.26.4: version "5.26.5" resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== +undici-types@^5.26.4: + version "5.28.2" + resolved "https://registry.npmjs.org/undici-types/-/undici-types-5.28.2.tgz" + integrity sha512-W71OLwDqzIO0d3k07qg1xc7d4cX8SsSwuCO4bQ4V7ITwduXXie/lcImofabP5VV+NvuvSe8ovKvHVJcizVc1JA== + unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" From 543081bf3413e040aaca758367a5d4ee0df6da8c Mon Sep 17 00:00:00 2001 From: Alie Date: Sun, 14 Jan 2024 20:45:27 +0100 Subject: [PATCH 132/133] Merge branch 'build' --- .gitea/workflows/02_build.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/02_build.yaml b/.gitea/workflows/02_build.yaml index 108e093..5292d58 100644 --- a/.gitea/workflows/02_build.yaml +++ b/.gitea/workflows/02_build.yaml @@ -4,6 +4,9 @@ on: branches: - main - build + tags: + - v* + jobs: build: container: @@ -30,7 +33,7 @@ jobs: tags: | type=raw,value=latest,enable=${{ github.ref == format('refs/heads/{0}', 'main') }} type=ref,event=branch - type=sha + type=semver,pattern={{raw}} - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Login to fai.st docker registry From 90cf36b1e8f467ee267cc171837db297a2787714 Mon Sep 17 00:00:00 2001 From: Sugui Date: Mon, 15 Apr 2024 18:36:35 +0200 Subject: [PATCH 133/133] Fix to gracefully stop bun --- compose.yaml | 5 ++--- package.json | 3 +-- src/app.ts | 8 +++++++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/compose.yaml b/compose.yaml index 30088de..d8bf85f 100644 --- a/compose.yaml +++ b/compose.yaml @@ -1,5 +1,3 @@ -version: "3" - services: mongodb: image: mongo:bionic @@ -16,7 +14,8 @@ services: bot-api: image: oven/bun:1 container_name: bot-api - command: bun run docker-dev + entrypoint: /bin/bash -c + command: ["bun --hot run src/index.ts"] working_dir: /usr/src/app ports: - "8080:8080" diff --git a/package.json b/package.json index e36feb8..4983e60 100644 --- a/package.json +++ b/package.json @@ -21,9 +21,8 @@ }, "scripts": { "start": "bun run src/index.ts", - "docker-dev": "bun --hot run src/index.ts", "dev": "docker compose down -v && docker compose up", - "test": "docker compose down -v && docker compose run bot-api bun test" + "test": "docker compose down -v && docker compose run bot-api 'bun test'" }, "dependencies": { "compression": "^1.7.4", diff --git a/src/app.ts b/src/app.ts index 6107852..fc376bf 100644 --- a/src/app.ts +++ b/src/app.ts @@ -35,9 +35,15 @@ export const startApp = async () => { pass: mongo_pass, }); mongoose.set("runValidators", true); - app.listen(port, () => + const server = app.listen(port, () => logger.info(`Express server listening on port ${port}`) ); + process.on("SIGTERM", () => { + server.close(() => { + logger.info('Server closed'); + process.exit(0); + }); + }); } catch (error) { logger.error(error); process.exit(1);