From 323fc396f79eb0a7e31a0d7d7e953f42e53190c8 Mon Sep 17 00:00:00 2001 From: Stephan <57194608+stephan418@users.noreply.github.com> Date: Mon, 3 Jan 2022 15:52:23 +0100 Subject: [PATCH 01/15] Add express.static() to serve semi-static files + Should be user-updateable in the future --- .gitignore | 3 +++ src/Routes/media.routes.ts | 8 ++++++++ src/app.ts | 5 +++++ 3 files changed, 16 insertions(+) create mode 100644 src/Routes/media.routes.ts diff --git a/.gitignore b/.gitignore index f3b78d7..57680b8 100644 --- a/.gitignore +++ b/.gitignore @@ -111,3 +111,6 @@ host/ # Ignore flags INITIALIZED + +# Ignore runtime files +media/ diff --git a/src/Routes/media.routes.ts b/src/Routes/media.routes.ts new file mode 100644 index 0000000..d67c9cc --- /dev/null +++ b/src/Routes/media.routes.ts @@ -0,0 +1,8 @@ +import express from "express"; + +const router = express.Router(); + +// Media storage with express static (Should only handle GET and HEAD request methods) +router.use("/", express.static("media", { redirect: false })); + +export default router; diff --git a/src/app.ts b/src/app.ts index 39dcc0f..5f36efe 100644 --- a/src/app.ts +++ b/src/app.ts @@ -11,6 +11,7 @@ import roleSchemaRouter from "./Routes/role_schema.routes"; import defaultErrorHandler from "./Middleware/error/handler"; import logger from "./Middleware/error/logger"; import debugLogger from "./Middleware/debug/logger"; +import mediaRouter from "./Routes/media.routes"; // Set up async error handling require("express-async-errors"); @@ -51,6 +52,7 @@ async function main() { app.use("/api/admins", adminRouter); +<<<<<<< HEAD app.use("/api/organisations", organisationRouter); app.use("/api/groups", groupRouter); @@ -61,6 +63,9 @@ async function main() { // Error handling app.use(defaultErrorHandler); // Not working +======= + app.use("/api/media", mediaRouter); +>>>>>>> Add express.static() to serve semi-static files app.listen(process.env.PORT, () => { logger.info(`Listening on port ${process.env.PORT}`); From bb4f4babcedcc4e10cb18df0d90d58c673ecbd6a Mon Sep 17 00:00:00 2001 From: Stephan <57194608+stephan418@users.noreply.github.com> Date: Mon, 3 Jan 2022 22:33:49 +0100 Subject: [PATCH 02/15] Add controller and routes to upload images + Checks for valid image formats + Limits file size + Requires authentication + Disabled for now --- package.json | 4 + src/Controllers/media.controller.ts | 109 ++++++++++++++++++++++++++++ src/Routes/media.routes.ts | 5 ++ src/app.ts | 7 +- 4 files changed, 122 insertions(+), 3 deletions(-) create mode 100644 src/Controllers/media.controller.ts diff --git a/package.json b/package.json index d247c39..9d69e55 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "dependencies": { "@prisma/client": "^3.3.0", "@types/handlebars": "^4.1.0", + "@types/express-fileupload": "^1.2.1", "@types/jsonwebtoken": "^8.5.5", "@types/mjml": "^4.7.0", "@types/node": "^16.10.3", @@ -31,6 +32,9 @@ "express": "^4.17.1", "handlebars": "^4.7.7", "express-async-errors": "^3.1.1", + "express-fileupload": "^1.2.1", + "file-type": "^16.5.3", + "is-svg": "^4.3.2", "jsonwebtoken": "^8.5.1", "mjml": "^4.11.0", "nanoid": "^3.3.3", diff --git a/src/Controllers/media.controller.ts b/src/Controllers/media.controller.ts new file mode 100644 index 0000000..97b246b --- /dev/null +++ b/src/Controllers/media.controller.ts @@ -0,0 +1,109 @@ +import { Request, Response } from "express"; +import fs from "fs"; +import isSvg from "is-svg"; +import { fromBuffer as fileTypeFromBuffer } from "file-type"; + +export const uploadImage = async (req: Request, res: Response) => { + if (!req.auth?.isAuthenticated) { + return res.status(500).json({ + type: "failure", + payload: { + message: "The server was not able to validate your credentials; Please try again later", + }, + }); + } + + if (!(req.auth.permission_level === "ELEVATED")) { + return res.status(403).json({ + type: "error", + payload: { + message: "You do not have sufficient permissions to use this feature", + required_level: "ELEVATED", + }, + }); + } + + if (!req.files || !("file" in req.files)) { + return res.json({ + type: "error", + payload: { + message: "The format of the data was not valid", + schema: { + multipart: { + file: "binary file", + }, + }, + }, + }); + } + + const file = req.files.file; + + if (Array.isArray(file)) { + return res.status(500).json({ + type: "failure", + payload: { + message: "Invalid application state", + }, + }); + } + + if (file.size > 1024 * 1024) { + // Maybe resize (express-fileupload seems to support this) + return res.status(413).json({ + type: "error", + payload: { + message: "The uploaded image is too large", + max_size: "1 MB", + }, + }); + } + + const fileIsSvg = isSvg(file.data); + const fileType = await fileTypeFromBuffer(file.data); // Could be optimized + + if (!(fileType && ["image/jpeg", "image/png"].includes(fileType.mime))) { + if (!fileIsSvg) + return res.status(415).json({ + type: "error", + payload: { + message: + "The uploaded image does not satisfy the MIME type constraints (Only image/jpeg, image/png and SVG files are accepted)", + }, + }); + } + + const fileName = file.md5 + (fileIsSvg ? ".svg" : "." + fileType?.ext); + + if (fs.existsSync("media/" + fileName)) { + return res.status(409).json({ + type: "error", + payload: { + message: "The uploaded file already exists", + }, + _links: [ + { + rel: "self", + type: "GET", + href: "/api/media/" + fileName, + }, + ], + }); + } + + file.mv("media/" + fileName, console.error); + + return res.status(201).json({ + type: "success", + payload: { + message: "The file was uploaded and created on the server", + }, + _links: [ + { + rel: "self", + type: "GET", + href: "/api/media/" + fileName, + }, + ], + }); +}; diff --git a/src/Routes/media.routes.ts b/src/Routes/media.routes.ts index d67c9cc..e58b490 100644 --- a/src/Routes/media.routes.ts +++ b/src/Routes/media.routes.ts @@ -1,7 +1,12 @@ import express from "express"; +import fileUpload from "express-fileupload"; +import { requireAuthentication } from "../Middleware/auth/auth"; +import { uploadImage } from "../Controllers/media.controller"; const router = express.Router(); +router.post("/", requireAuthentication, fileUpload(), uploadImage); + // Media storage with express static (Should only handle GET and HEAD request methods) router.use("/", express.static("media", { redirect: false })); diff --git a/src/app.ts b/src/app.ts index 5f36efe..95bbc8b 100644 --- a/src/app.ts +++ b/src/app.ts @@ -52,7 +52,6 @@ async function main() { app.use("/api/admins", adminRouter); -<<<<<<< HEAD app.use("/api/organisations", organisationRouter); app.use("/api/groups", groupRouter); @@ -63,9 +62,11 @@ async function main() { // Error handling app.use(defaultErrorHandler); // Not working -======= + app.use("/api/media", mediaRouter); ->>>>>>> Add express.static() to serve semi-static files + + // Disable the media router for now + // app.use("/api/media", mediaRouter); app.listen(process.env.PORT, () => { logger.info(`Listening on port ${process.env.PORT}`); From 13d6f881eaab21307b859df72992d59e41f343bf Mon Sep 17 00:00:00 2001 From: Stephan <57194608+stephan418@users.noreply.github.com> Date: Mon, 3 Jan 2022 23:00:48 +0100 Subject: [PATCH 03/15] Extract shared error code + Create new functions for generating errors --- src/Controllers/common.ts | 15 +++++++ src/Controllers/media.controller.ts | 64 ++++++++--------------------- 2 files changed, 32 insertions(+), 47 deletions(-) diff --git a/src/Controllers/common.ts b/src/Controllers/common.ts index ad2dc49..0b97e88 100644 --- a/src/Controllers/common.ts +++ b/src/Controllers/common.ts @@ -3,6 +3,21 @@ import { PrismaClientKnownRequestError, PrismaClientUnknownRequestError } from " import { Request, Response } from "express"; import prisma from "../lib/prisma"; +interface StringIndexedObject { + [k: string]: any; +} + +export function createError(message: string, payload: StringIndexedObject = {}, links: StringIndexedObject = {}) { + return { + type: "error", + payload: { + message: message, + ...payload, + }, + _links: links, + }; +} + export enum DataType { STRING = "string", NUMBER = "number", diff --git a/src/Controllers/media.controller.ts b/src/Controllers/media.controller.ts index 97b246b..c19314c 100644 --- a/src/Controllers/media.controller.ts +++ b/src/Controllers/media.controller.ts @@ -2,25 +2,19 @@ import { Request, Response } from "express"; import fs from "fs"; import isSvg from "is-svg"; import { fromBuffer as fileTypeFromBuffer } from "file-type"; +import { AUTH_ERROR, createError, createInsufficientPermissionsError } from "./common"; + +function createMediaLinks(fileName: string) { + return [{ rel: "self", type: "GET", href: `/api/media/${fileName}` }]; +} export const uploadImage = async (req: Request, res: Response) => { if (!req.auth?.isAuthenticated) { - return res.status(500).json({ - type: "failure", - payload: { - message: "The server was not able to validate your credentials; Please try again later", - }, - }); + return res.status(500).json(AUTH_ERROR); } if (!(req.auth.permission_level === "ELEVATED")) { - return res.status(403).json({ - type: "error", - payload: { - message: "You do not have sufficient permissions to use this feature", - required_level: "ELEVATED", - }, - }); + return res.status(403).json(createInsufficientPermissionsError()); } if (!req.files || !("file" in req.files)) { @@ -50,13 +44,7 @@ export const uploadImage = async (req: Request, res: Response) => { if (file.size > 1024 * 1024) { // Maybe resize (express-fileupload seems to support this) - return res.status(413).json({ - type: "error", - payload: { - message: "The uploaded image is too large", - max_size: "1 MB", - }, - }); + return res.status(413).json(createError("The uploaded image is too large", { max_size: "1 MB" })); } const fileIsSvg = isSvg(file.data); @@ -64,31 +52,19 @@ export const uploadImage = async (req: Request, res: Response) => { if (!(fileType && ["image/jpeg", "image/png"].includes(fileType.mime))) { if (!fileIsSvg) - return res.status(415).json({ - type: "error", - payload: { - message: - "The uploaded image does not satisfy the MIME type constraints (Only image/jpeg, image/png and SVG files are accepted)", - }, - }); + return res + .status(415) + .json( + createError( + "The uploaded image does not satisfy the MIME type constraints (Only image/jpeg, image/png and SVG files are accepted)" + ) + ); } const fileName = file.md5 + (fileIsSvg ? ".svg" : "." + fileType?.ext); if (fs.existsSync("media/" + fileName)) { - return res.status(409).json({ - type: "error", - payload: { - message: "The uploaded file already exists", - }, - _links: [ - { - rel: "self", - type: "GET", - href: "/api/media/" + fileName, - }, - ], - }); + return res.status(409).json(createError("The uploaded file already exists", {}, createMediaLinks(fileName))); } file.mv("media/" + fileName, console.error); @@ -98,12 +74,6 @@ export const uploadImage = async (req: Request, res: Response) => { payload: { message: "The file was uploaded and created on the server", }, - _links: [ - { - rel: "self", - type: "GET", - href: "/api/media/" + fileName, - }, - ], + _links: createMediaLinks(fileName), }); }; From bded472d05ce04a84ff31da7021c5f98d60c37ae Mon Sep 17 00:00:00 2001 From: Laurin <60652077+Flexla54@users.noreply.github.com> Date: Fri, 13 May 2022 13:21:16 +0200 Subject: [PATCH 04/15] Added basic implementation of media --- prisma/schema.prisma | 20 ++--- src/Controllers/discipline.controller.ts | 58 +++++++++++++++ src/Controllers/event.controller.ts | 69 ++++++++++++++++- src/Controllers/media.controller.ts | 91 ++++++++++++++++++++++- src/Controllers/role_schema.controller.ts | 58 +++++++++++++++ src/Routes/discipline.routes.ts | 8 ++ src/Routes/event.routes.ts | 7 +- src/Routes/media.routes.ts | 6 +- src/Routes/role_schema.routes.ts | 9 +++ 9 files changed, 307 insertions(+), 19 deletions(-) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index e5bb5f0..9557922 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -10,11 +10,12 @@ generator client { } model Event { - id Int @id @default(autoincrement()) // Primary key - pid String @unique @default(dbgenerated("gen_random_uuid()")) @db.Uuid // Public key - date DateTime - name String - description String + id Int @id @default(autoincrement()) // Primary key + pid String @unique @default(dbgenerated("gen_random_uuid()")) @db.Uuid // Public key + date DateTime + name String + briefDescription String + fullDescription String? disciplines Discipline[] organisations Organisation[] @@ -119,13 +120,12 @@ model Group { model Media { id Int @id @default(autoincrement()) - pid String @unique @default(dbgenerated("gen_random_uuid()")) @db.Uuid + pid String @unique description String - location String @unique - event Event[] - discipline Discipline[] - role RoleSchema[] + events Event[] + disciplines Discipline[] + roles RoleSchema[] } enum AdminLevel { diff --git a/src/Controllers/discipline.controller.ts b/src/Controllers/discipline.controller.ts index 93431ae..d6451bb 100644 --- a/src/Controllers/discipline.controller.ts +++ b/src/Controllers/discipline.controller.ts @@ -187,3 +187,61 @@ export const deleteDiscipline = async (req: Request throw e; } }; + +interface visualParams { + disciplinePid: string; +} + +interface visualBody { + mediaPid: string; +} + +export const addVisual = async (req: Request, res: Response) => { + if (req.auth?.permission_level != "ELEVATED"){ + res.status(403).json(createInsufficientPermissionsError()); + } + + const { disciplinePid } = req.params; + + const discipline = await prisma.discipline.update({ + where: { pid: disciplinePid }, + data: { + visual: { connect: { pid: req.body.mediaPid } } + } + }); + + if (!discipline) { + throw new NotFoundError("discipline", disciplinePid); + } + + return res.status(200).json({ + type: "success", + payload: { discipline } + }) +}; + +export const deleteVisual = async (req: Request, res: Response) => { + if (req.auth?.permission_level != "ELEVATED"){ + res.status(403).json(createInsufficientPermissionsError()); + } + + const { disciplinePid } = req.params; + + try { + await prisma.discipline.update({ + where: { + pid: disciplinePid, + }, + data: { + visual: { disconnect: { pid: req.body.mediaPid } } + } + }); + return res.status(204).end(); + } catch (e) { + if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") { + throw new NotFoundError("discipline", disciplinePid); + } + + throw e; + } +}; diff --git a/src/Controllers/event.controller.ts b/src/Controllers/event.controller.ts index 99378fa..6e9ba7c 100644 --- a/src/Controllers/event.controller.ts +++ b/src/Controllers/event.controller.ts @@ -2,13 +2,15 @@ import { Prisma } from "@prisma/client"; import { PrismaClientKnownRequestError } from "@prisma/client/runtime"; import { Request, Response } from "express"; import prisma from "../lib/prisma"; +import NotFoundError from "../Middleware/error/NotFoundError"; import { createInsufficientPermissionsError, DataType, generateError, generateInvalidBodyError } from "./common"; export const getAllEvents = async (req: Request, res: Response) => { const events = await prisma.event.findMany({ select: { name: true, - description: true, + briefDescription: true, + fullDescription: true, date: true, pid: true, id: false, @@ -41,7 +43,8 @@ export const getEvent = async (req: Request, res: Response) => { }, select: { name: true, - description: true, + briefDescription: true, + fullDescription: true, date: true, pid: true, id: false, @@ -102,14 +105,14 @@ export const addEvent = async (req: Request, res: Response) => { data: { name: req.body.name, date: req.body.date, - description: req.body.description, + briefDescription: req.body.description, }, select: { name: true, date: true, pid: true, id: false, - description: true, + briefDescription: true, }, }); @@ -145,3 +148,61 @@ export const deleteEvent = (req: Request, res: Response) throw e; } }; + +interface visualParams { + eventPid: string; +} + +interface visualBody { + mediaPid: string; +} + +export const addVisual = async (req: Request, res: Response) => { + if (req.auth?.permission_level != "ELEVATED"){ + res.status(403).json(createInsufficientPermissionsError()); + } + + const { eventPid } = req.params; + + const event = await prisma.event.update({ + where: { pid: eventPid }, + data: { + visual: { connect: { pid: req.body.mediaPid } } + } + }); + + if (!event) { + throw new NotFoundError("event", eventPid); + } + + return res.status(200).json({ + type: "success", + payload: { event } + }) +}; + +export const deleteVisual = async (req: Request, res: Response) => { + if (req.auth?.permission_level != "ELEVATED"){ + res.status(403).json(createInsufficientPermissionsError()); + } + + const { eventPid } = req.params; + + try { + await prisma.event.update({ + where: { + pid: eventPid, + }, + data: { + visual: { disconnect: { pid: req.body.mediaPid } } + } + }); + return res.status(204).end(); + } catch (e) { + if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") { + throw new NotFoundError("discipline", eventPid); + } + + throw e; + } +}; diff --git a/src/Controllers/media.controller.ts b/src/Controllers/media.controller.ts index c19314c..2083ef2 100644 --- a/src/Controllers/media.controller.ts +++ b/src/Controllers/media.controller.ts @@ -1,8 +1,16 @@ -import { Request, Response } from "express"; +import { Request, response, Response } from "express"; import fs from "fs"; import isSvg from "is-svg"; import { fromBuffer as fileTypeFromBuffer } from "file-type"; import { AUTH_ERROR, createError, createInsufficientPermissionsError } from "./common"; +import { Prisma } from "@prisma/client"; +import prisma from "../lib/prisma"; +import NotFoundError from "../Middleware/error/NotFoundError"; +import { PrismaClientKnownRequestError } from "@prisma/client/runtime"; +import { generateInvalidBodyError, DataType, } from "./common"; +import { type } from "os"; +import {unlink} from "fs/promises" + function createMediaLinks(fileName: string) { return [{ rel: "self", type: "GET", href: `/api/media/${fileName}` }]; @@ -31,6 +39,14 @@ export const uploadImage = async (req: Request, res: Response) => { }); } + if ( typeof req.body.description !== "string") { + return res.status(400).json( + generateInvalidBodyError({ + description: DataType.STRING + }) + ); + } + const file = req.files.file; if (Array.isArray(file)) { @@ -69,11 +85,80 @@ export const uploadImage = async (req: Request, res: Response) => { file.mv("media/" + fileName, console.error); + //generate record + const media = await prisma.media.create({ + data: { + pid: fileName, + description: req.body.description, + }, + select: { + pid: true, + description: true, + } + }) + return res.status(201).json({ type: "success", + payload: { media } + }) +}; + +export const getAllMedia = async (req: Request, res: Response) => { + const medias = await prisma.media.findMany({ + select: { + description: true, + events: true, + disciplines: true, + roles: true, + pid: true, + id: false, + }, + }); + + res.status(200).json({ + type: "success", payload: { - message: "The file was uploaded and created on the server", + medias, }, - _links: createMediaLinks(fileName), }); }; + +interface CreateMediaBody { + description?: string; + location?: string; + + events?: string[]; + disciplines?: string[]; + roles?: string[]; +} + +interface MediaParams { + eventPid?: string; + disciplinePid?: string; + rolePid?: string; +} + +export const deleteMedia = async (req: Request, res: Response) => { + if (req.auth?.permission_level != "ELEVATED"){ + res.status(403).json(createInsufficientPermissionsError()); + } + + const { pid } = req.params; + + const location = "media/" + pid; + + if (fs.existsSync(location)) { + await unlink(location); + } + + try { + await prisma.discipline.delete({ where: { pid }}); + return res.status(204).end(); + } catch (e) { + if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") { + throw new NotFoundError("discipline", pid); + } + + throw e; + } +}; \ No newline at end of file diff --git a/src/Controllers/role_schema.controller.ts b/src/Controllers/role_schema.controller.ts index ca73554..2f03949 100644 --- a/src/Controllers/role_schema.controller.ts +++ b/src/Controllers/role_schema.controller.ts @@ -123,3 +123,61 @@ export const createRoleSchema = async ( throw e; } }; + +interface visualParams { + schemaPid: string; +} + +interface visualBody { + mediaPid: string; +} + +export const addVisual = async (req: Request, res: Response) => { + if (req.auth?.permission_level != "ELEVATED"){ + res.status(403).json(createInsufficientPermissionsError()); + } + + const { schemaPid } = req.params; + + const schema = await prisma.roleSchema.update({ + where: { pid: schemaPid }, + data: { + visual: { connect: { pid: req.body.mediaPid } } + } + }); + + if (!schema) { + throw new NotFoundError("role_schema", schemaPid); + } + + return res.status(200).json({ + type: "success", + payload: { schema } + }) +}; + +export const deleteVisual = async (req: Request, res: Response) => { + if (req.auth?.permission_level != "ELEVATED"){ + res.status(403).json(createInsufficientPermissionsError()); + } + + const { schemaPid } = req.params; + + try { + await prisma.roleSchema.update({ + where: { + pid: schemaPid, + }, + data: { + visual: { disconnect: { pid: req.body.mediaPid } } + } + }); + return res.status(204).end(); + } catch (e) { + if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") { + throw new NotFoundError("role_schema", schemaPid); + } + + throw e; + } +}; diff --git a/src/Routes/discipline.routes.ts b/src/Routes/discipline.routes.ts index 08aec30..acc2d76 100644 --- a/src/Routes/discipline.routes.ts +++ b/src/Routes/discipline.routes.ts @@ -1,8 +1,10 @@ import express from "express"; import eventRouter from "./event.routes"; import { + addVisual, createDiscipline, deleteDiscipline, + deleteVisual, getAllDisciplines, getDiscipline, } from "../Controllers/discipline.controller"; @@ -11,9 +13,15 @@ import { requireAuthentication } from "../Middleware/auth/auth"; const router = express.Router(); router.get("/", getAllDisciplines); // TODO: Optional auth + router.get("/:pid", getDiscipline); + router.delete<"/:pid", { pid: string }>("/:pid", requireAuthentication, deleteDiscipline); +router.post<"/:disciplinePid/images", {disciplinePid: string}>("/:disciplinePid/images", requireAuthentication, addVisual); + +router.delete<"/:disciplinePid/images/:pid", {disciplinePid: string, pid: string}>("/:disciplinePid/images/:pid", requireAuthentication, deleteVisual); + eventRouter.post("/:eventPid/disciplines", requireAuthentication, createDiscipline); export default router; diff --git a/src/Routes/event.routes.ts b/src/Routes/event.routes.ts index 2ce9e38..290816d 100644 --- a/src/Routes/event.routes.ts +++ b/src/Routes/event.routes.ts @@ -1,5 +1,6 @@ import Express from "express"; -import { addEvent, getAllEvents, getEvent } from "../Controllers/event.controller"; +import { string } from "zod"; +import { addEvent, addVisual, deleteVisual, getAllEvents, getEvent } from "../Controllers/event.controller"; import { requireAuthentication } from "../Middleware/auth/auth"; const router = Express.Router(); @@ -9,4 +10,8 @@ router.get("/:eventId", getEvent); router.post("/", requireAuthentication, addEvent); +router.post<"/:eventPid/images", {eventPid: string}>("/:eventPid/images", requireAuthentication, addVisual); + +router.delete<"/:eventPid/images/:pid", {eventPid: string, pid: string}>("/:eventPid/images/:pid", requireAuthentication, deleteVisual); + export default router; diff --git a/src/Routes/media.routes.ts b/src/Routes/media.routes.ts index e58b490..9d781e5 100644 --- a/src/Routes/media.routes.ts +++ b/src/Routes/media.routes.ts @@ -1,7 +1,7 @@ import express from "express"; import fileUpload from "express-fileupload"; import { requireAuthentication } from "../Middleware/auth/auth"; -import { uploadImage } from "../Controllers/media.controller"; +import { deleteMedia, getAllMedia, uploadImage } from "../Controllers/media.controller"; const router = express.Router(); @@ -10,4 +10,8 @@ router.post("/", requireAuthentication, fileUpload(), uploadImage); // Media storage with express static (Should only handle GET and HEAD request methods) router.use("/", express.static("media", { redirect: false })); +router.get("/:pid", getAllMedia); + +router.delete("/:pid", requireAuthentication, deleteMedia); + export default router; diff --git a/src/Routes/role_schema.routes.ts b/src/Routes/role_schema.routes.ts index ea3c938..0ec3f67 100644 --- a/src/Routes/role_schema.routes.ts +++ b/src/Routes/role_schema.routes.ts @@ -1,7 +1,9 @@ import express from "express"; import disciplineRouter from "./discipline.routes"; import { + addVisual, createRoleSchema, + deleteVisual, getAllRoleSchemas, getAllRoleSchemasWithParam, getRoleSchema, @@ -11,9 +13,16 @@ import { requireAuthentication } from "../Middleware/auth/auth"; const router = express.Router(); router.get("/", getAllRoleSchemas); + router.get("/:pid", getRoleSchema); disciplineRouter.get("/:disciplinePid/role-schemas", getAllRoleSchemasWithParam); + disciplineRouter.post("/:disciplinePid/role-schemas", requireAuthentication, createRoleSchema); +router.post<"/:schemaPid/images", {schemaPid: string}>("/:schemaPid/images", requireAuthentication, addVisual); + +router.delete<"/:schemaPid/images/:pid", {schemaPid: string, pid: string}>("/:schemaPid/images/:pid", requireAuthentication, deleteVisual); + + export default router; From 196604599b7d7bd752e3bf5739bbe60483b77b99 Mon Sep 17 00:00:00 2001 From: Stephan <57194608+stephan418@users.noreply.github.com> Date: Sun, 15 May 2022 11:46:53 +0200 Subject: [PATCH 05/15] FIX: **quickly** fix all errors in the media system --- Dockerfile | 2 + src/Controllers/media.controller.ts | 62 ++++++++++++++++++----------- src/Routes/media.routes.ts | 8 ++-- src/app.ts | 6 +-- 4 files changed, 47 insertions(+), 31 deletions(-) diff --git a/Dockerfile b/Dockerfile index d4a542d..6fd1450 100644 --- a/Dockerfile +++ b/Dockerfile @@ -11,6 +11,8 @@ COPY package.json package-lock.json /app/ # Change directory into the container WORKDIR /app +RUN mkdir /app/media + # Install dependencies RUN npm i -g typescript RUN npm i diff --git a/src/Controllers/media.controller.ts b/src/Controllers/media.controller.ts index 2083ef2..a1d86dc 100644 --- a/src/Controllers/media.controller.ts +++ b/src/Controllers/media.controller.ts @@ -7,10 +7,12 @@ import { Prisma } from "@prisma/client"; import prisma from "../lib/prisma"; import NotFoundError from "../Middleware/error/NotFoundError"; import { PrismaClientKnownRequestError } from "@prisma/client/runtime"; -import { generateInvalidBodyError, DataType, } from "./common"; +import { generateInvalidBodyError, DataType } from "./common"; import { type } from "os"; -import {unlink} from "fs/promises" +import { unlink } from "fs/promises"; +import ForwardableError from "../Middleware/error/ForwardableError"; +require("express-async-errors"); function createMediaLinks(fileName: string) { return [{ rel: "self", type: "GET", href: `/api/media/${fileName}` }]; @@ -25,6 +27,11 @@ export const uploadImage = async (req: Request, res: Response) => { return res.status(403).json(createInsufficientPermissionsError()); } + // REVIEW: This is only a **quick** fix (As the body is multipart form data, it cannot be used like this) + // @ts-ignore + req.body.description = "Sample image"; + console.log(req.body); + if (!req.files || !("file" in req.files)) { return res.json({ type: "error", @@ -39,10 +46,10 @@ export const uploadImage = async (req: Request, res: Response) => { }); } - if ( typeof req.body.description !== "string") { + if (typeof req.body.description !== "string") { return res.status(400).json( generateInvalidBodyError({ - description: DataType.STRING + description: DataType.STRING, }) ); } @@ -83,24 +90,30 @@ export const uploadImage = async (req: Request, res: Response) => { return res.status(409).json(createError("The uploaded file already exists", {}, createMediaLinks(fileName))); } - file.mv("media/" + fileName, console.error); + file.mv("/app/media/" + fileName, console.error); - //generate record - const media = await prisma.media.create({ - data: { - pid: fileName, - description: req.body.description, - }, - select: { - pid: true, - description: true, + try { + //generate record + const media = await prisma.media.create({ + data: { + pid: fileName, + description: req.body.description, + }, + select: { + pid: true, + description: true, + }, + }); + + return res.status(201).json({ + type: "success", + payload: { media }, + }); + } catch (e) { + if (e instanceof PrismaClientKnownRequestError && e.code === "P2002") { + throw new ForwardableError(409, `The image with the the hash and extenstion ${fileName} already exists!`); } - }) - - return res.status(201).json({ - type: "success", - payload: { media } - }) + } }; export const getAllMedia = async (req: Request, res: Response) => { @@ -139,7 +152,7 @@ interface MediaParams { } export const deleteMedia = async (req: Request, res: Response) => { - if (req.auth?.permission_level != "ELEVATED"){ + if (req.auth?.permission_level != "ELEVATED") { res.status(403).json(createInsufficientPermissionsError()); } @@ -149,16 +162,17 @@ export const deleteMedia = async (req: Request, res: Response) => { if (fs.existsSync(location)) { await unlink(location); + 1; } try { - await prisma.discipline.delete({ where: { pid }}); + await prisma.media.delete({ where: { pid } }); return res.status(204).end(); } catch (e) { if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") { - throw new NotFoundError("discipline", pid); + throw new NotFoundError("media", pid); } throw e; } -}; \ No newline at end of file +}; diff --git a/src/Routes/media.routes.ts b/src/Routes/media.routes.ts index 9d781e5..9c9fa7b 100644 --- a/src/Routes/media.routes.ts +++ b/src/Routes/media.routes.ts @@ -5,12 +5,12 @@ import { deleteMedia, getAllMedia, uploadImage } from "../Controllers/media.cont const router = express.Router(); +// Media storage with express static (Should only handle GET and HEAD request methods) +router.use("/", express.static("/app/media", { redirect: false })); + router.post("/", requireAuthentication, fileUpload(), uploadImage); -// Media storage with express static (Should only handle GET and HEAD request methods) -router.use("/", express.static("media", { redirect: false })); - -router.get("/:pid", getAllMedia); +router.get("/", requireAuthentication, getAllMedia); // Reading all files should be a senstive operation router.delete("/:pid", requireAuthentication, deleteMedia); diff --git a/src/app.ts b/src/app.ts index 95bbc8b..ae0c0ec 100644 --- a/src/app.ts +++ b/src/app.ts @@ -60,11 +60,11 @@ async function main() { app.use("/api/role-schemas", roleSchemaRouter); - // Error handling - app.use(defaultErrorHandler); // Not working - app.use("/api/media", mediaRouter); + // Error handling + app.use(defaultErrorHandler); // This has to be the LAST ROUTE + // Disable the media router for now // app.use("/api/media", mediaRouter); From 734acbab382677ac4cdce38becdb72585458a3cb Mon Sep 17 00:00:00 2001 From: Stephan <57194608+stephan418@users.noreply.github.com> Date: Sun, 15 May 2022 12:04:27 +0200 Subject: [PATCH 06/15] Fix and comment code for linking media --- src/Controllers/discipline.controller.ts | 2 +- src/Controllers/event.controller.ts | 10 +++++++++- src/Controllers/media.controller.ts | 10 ++++------ src/Controllers/role_schema.controller.ts | 2 +- src/Routes/event.routes.ts | 8 ++++++-- 5 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/Controllers/discipline.controller.ts b/src/Controllers/discipline.controller.ts index d6451bb..73ce9d1 100644 --- a/src/Controllers/discipline.controller.ts +++ b/src/Controllers/discipline.controller.ts @@ -216,7 +216,7 @@ export const addVisual = async (req: Request, res: return res.status(200).json({ type: "success", - payload: { discipline } + payload: { } }) }; diff --git a/src/Controllers/event.controller.ts b/src/Controllers/event.controller.ts index 6e9ba7c..b46424d 100644 --- a/src/Controllers/event.controller.ts +++ b/src/Controllers/event.controller.ts @@ -11,6 +11,7 @@ export const getAllEvents = async (req: Request, res: Response) => { name: true, briefDescription: true, fullDescription: true, + visual: {select: {pid: true, description: true}}, date: true, pid: true, id: false, @@ -48,6 +49,7 @@ export const getEvent = async (req: Request, res: Response) => { date: true, pid: true, id: false, + visual: {select: {pid: true, description: true}} }, }); @@ -149,6 +151,8 @@ export const deleteEvent = (req: Request, res: Response) } }; +// REVIEW: This code **will** need to be de-duplicated + interface visualParams { eventPid: string; } @@ -163,6 +167,10 @@ export const addVisual = async (req: Request, res: } const { eventPid } = req.params; + + if (typeof req.body.mediaPid !== "string") { + res.status(400).json(generateInvalidBodyError({mediaPid: DataType.STRING})); + } const event = await prisma.event.update({ where: { pid: eventPid }, @@ -177,7 +185,7 @@ export const addVisual = async (req: Request, res: return res.status(200).json({ type: "success", - payload: { event } + payload: { } }) }; diff --git a/src/Controllers/media.controller.ts b/src/Controllers/media.controller.ts index a1d86dc..b575b41 100644 --- a/src/Controllers/media.controller.ts +++ b/src/Controllers/media.controller.ts @@ -86,12 +86,6 @@ export const uploadImage = async (req: Request, res: Response) => { const fileName = file.md5 + (fileIsSvg ? ".svg" : "." + fileType?.ext); - if (fs.existsSync("media/" + fileName)) { - return res.status(409).json(createError("The uploaded file already exists", {}, createMediaLinks(fileName))); - } - - file.mv("/app/media/" + fileName, console.error); - try { //generate record const media = await prisma.media.create({ @@ -114,6 +108,10 @@ export const uploadImage = async (req: Request, res: Response) => { throw new ForwardableError(409, `The image with the the hash and extenstion ${fileName} already exists!`); } } + + if (!fs.existsSync("media/" + fileName)) { + file.mv("/app/media/" + fileName, console.error); + } }; export const getAllMedia = async (req: Request, res: Response) => { diff --git a/src/Controllers/role_schema.controller.ts b/src/Controllers/role_schema.controller.ts index 2f03949..8c94265 100644 --- a/src/Controllers/role_schema.controller.ts +++ b/src/Controllers/role_schema.controller.ts @@ -152,7 +152,7 @@ export const addVisual = async (req: Request, res: return res.status(200).json({ type: "success", - payload: { schema } + payload: { } }) }; diff --git a/src/Routes/event.routes.ts b/src/Routes/event.routes.ts index 290816d..efc9137 100644 --- a/src/Routes/event.routes.ts +++ b/src/Routes/event.routes.ts @@ -10,8 +10,12 @@ router.get("/:eventId", getEvent); router.post("/", requireAuthentication, addEvent); -router.post<"/:eventPid/images", {eventPid: string}>("/:eventPid/images", requireAuthentication, addVisual); +router.post<"/:eventPid/media", { eventPid: string }>("/:eventPid/media", requireAuthentication, addVisual); -router.delete<"/:eventPid/images/:pid", {eventPid: string, pid: string}>("/:eventPid/images/:pid", requireAuthentication, deleteVisual); +router.delete<"/:eventPid/media/:pid", { eventPid: string; pid: string }>( + "/:eventPid/media/:pid", + requireAuthentication, + deleteVisual +); export default router; From b1c1e53a2dc8d5a8e5c6d8b483a0b006294adbc2 Mon Sep 17 00:00:00 2001 From: Stephan <57194608+stephan418@users.noreply.github.com> Date: Sun, 15 May 2022 12:07:07 +0200 Subject: [PATCH 07/15] Add fulldescription --- src/Controllers/event.controller.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Controllers/event.controller.ts b/src/Controllers/event.controller.ts index b46424d..7befc07 100644 --- a/src/Controllers/event.controller.ts +++ b/src/Controllers/event.controller.ts @@ -92,7 +92,8 @@ export const addEvent = async (req: Request, res: Response) => { if ( typeof req.body.name !== "string" || typeof req.body.date !== "string" || - typeof req.body.description !== "string" + typeof req.body.description !== "string" || + req.body.fullDescription && req.body.fullDescription !== "string" ) { generateInvalidBodyError({ name: DataType.STRING, @@ -115,6 +116,7 @@ export const addEvent = async (req: Request, res: Response) => { pid: true, id: false, briefDescription: true, + fullDescription: true, }, }); From f4288d7319121714895fa419796aafd7cbac6a5d Mon Sep 17 00:00:00 2001 From: Stephan <57194608+stephan418@users.noreply.github.com> Date: Mon, 16 May 2022 14:35:55 +0200 Subject: [PATCH 08/15] Fix dev.sh script (Now respects port) --- dev.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev.sh b/dev.sh index 000ccf3..7067090 100755 --- a/dev.sh +++ b/dev.sh @@ -51,6 +51,8 @@ if [ "$RECREATE" = true ]; then -e DATABASE_PASSWORD=server \ -e DATABASE_URL="postgresql://server:server@postgres:5432/management?schema=public" \ -e NODE_ENV="development" \ + -e PORT="${D_PORT}" \ + -p "${D_PORT}":"${D_PORT}" \ --entrypoint "/app/scripts/docker-entrypoint.dev.sh" \ node fi From a16126a1db305bfb41fc7e1abe5e6f58a32c832c Mon Sep 17 00:00:00 2001 From: Stephan <57194608+stephan418@users.noreply.github.com> Date: Mon, 16 May 2022 14:36:21 +0200 Subject: [PATCH 09/15] Fix media + Create media directory on dev start + Create media file on POST --- scripts/docker-entrypoint.dev.sh | 1 + src/Controllers/media.controller.ts | 9 ++++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/docker-entrypoint.dev.sh b/scripts/docker-entrypoint.dev.sh index f71097b..f483bd8 100755 --- a/scripts/docker-entrypoint.dev.sh +++ b/scripts/docker-entrypoint.dev.sh @@ -4,6 +4,7 @@ if ! test -f INITIALIZED; then touch INITIALIZED cd /app + mkdir media npm i -g ts-node nodemon npm i diff --git a/src/Controllers/media.controller.ts b/src/Controllers/media.controller.ts index b575b41..950686f 100644 --- a/src/Controllers/media.controller.ts +++ b/src/Controllers/media.controller.ts @@ -30,7 +30,6 @@ export const uploadImage = async (req: Request, res: Response) => { // REVIEW: This is only a **quick** fix (As the body is multipart form data, it cannot be used like this) // @ts-ignore req.body.description = "Sample image"; - console.log(req.body); if (!req.files || !("file" in req.files)) { return res.json({ @@ -99,6 +98,10 @@ export const uploadImage = async (req: Request, res: Response) => { }, }); + if (!fs.existsSync("media/" + fileName)) { + file.mv("media/" + fileName, console.error); + } + return res.status(201).json({ type: "success", payload: { media }, @@ -108,10 +111,6 @@ export const uploadImage = async (req: Request, res: Response) => { throw new ForwardableError(409, `The image with the the hash and extenstion ${fileName} already exists!`); } } - - if (!fs.existsSync("media/" + fileName)) { - file.mv("/app/media/" + fileName, console.error); - } }; export const getAllMedia = async (req: Request, res: Response) => { From c393508a063e02d8cd5dc56cd21ce954f9882d38 Mon Sep 17 00:00:00 2001 From: Stephan <57194608+stephan418@users.noreply.github.com> Date: Mon, 16 May 2022 15:15:58 +0200 Subject: [PATCH 10/15] Add functionality to add metadata to media --- src/Controllers/media.controller.ts | 39 ++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/Controllers/media.controller.ts b/src/Controllers/media.controller.ts index 950686f..3a713e8 100644 --- a/src/Controllers/media.controller.ts +++ b/src/Controllers/media.controller.ts @@ -11,6 +11,7 @@ import { generateInvalidBodyError, DataType } from "./common"; import { type } from "os"; import { unlink } from "fs/promises"; import ForwardableError from "../Middleware/error/ForwardableError"; +import SchemaError from "../Middleware/error/SchemaError"; require("express-async-errors"); @@ -27,9 +28,29 @@ export const uploadImage = async (req: Request, res: Response) => { return res.status(403).json(createInsufficientPermissionsError()); } - // REVIEW: This is only a **quick** fix (As the body is multipart form data, it cannot be used like this) - // @ts-ignore - req.body.description = "Sample image"; + let description = "Sample images"; + + const meta = req.body.meta; + + if (meta) { + try { + const { description: desc } = JSON.parse(meta); + + if (typeof desc === "string") description = desc; + } catch (e) { + if (e instanceof SyntaxError) { + return res.status(400).json({ + type: "error", + payload: { + message: "'meta' could not be parsed", + schema: { mutlipart: { file: "binary file", meta: { ["description?"]: "string" } } }, + }, + }); + } + + throw e; + } + } if (!req.files || !("file" in req.files)) { return res.json({ @@ -45,14 +66,6 @@ export const uploadImage = async (req: Request, res: Response) => { }); } - if (typeof req.body.description !== "string") { - return res.status(400).json( - generateInvalidBodyError({ - description: DataType.STRING, - }) - ); - } - const file = req.files.file; if (Array.isArray(file)) { @@ -90,7 +103,7 @@ export const uploadImage = async (req: Request, res: Response) => { const media = await prisma.media.create({ data: { pid: fileName, - description: req.body.description, + description: description, }, select: { pid: true, @@ -110,6 +123,8 @@ export const uploadImage = async (req: Request, res: Response) => { if (e instanceof PrismaClientKnownRequestError && e.code === "P2002") { throw new ForwardableError(409, `The image with the the hash and extenstion ${fileName} already exists!`); } + + throw e; } }; From bdfc15eab44424e3dd2dabab75c9995d1815948b Mon Sep 17 00:00:00 2001 From: Stephan <57194608+stephan418@users.noreply.github.com> Date: Mon, 16 May 2022 15:16:51 +0200 Subject: [PATCH 11/15] Add functionality to get media meta + Remove unused code + Fix misspelling + Fix error handling to handle errors with no status code --- src/Controllers/media.controller.ts | 28 +++++++++++++++------------- src/Middleware/error/handler.ts | 2 +- src/Routes/media.routes.ts | 3 ++- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/Controllers/media.controller.ts b/src/Controllers/media.controller.ts index 3a713e8..e9e5303 100644 --- a/src/Controllers/media.controller.ts +++ b/src/Controllers/media.controller.ts @@ -143,25 +143,27 @@ export const getAllMedia = async (req: Request, res: Response) => { res.status(200).json({ type: "success", payload: { - medias, + media: medias, }, }); }; -interface CreateMediaBody { - description?: string; - location?: string; +export const getMediaMeta = async (req: Request, res: Response) => { + const pid = req.params.pid; - events?: string[]; - disciplines?: string[]; - roles?: string[]; -} + const meta = await prisma.media.findUnique({ where: { pid }, select: { pid: true, description: true } }); -interface MediaParams { - eventPid?: string; - disciplinePid?: string; - rolePid?: string; -} + if (!meta) { + throw new NotFoundError("media", pid); + } + + return res.status(200).json({ + type: "success", + payload: { + meta, + }, + }); +}; export const deleteMedia = async (req: Request, res: Response) => { if (req.auth?.permission_level != "ELEVATED") { diff --git a/src/Middleware/error/handler.ts b/src/Middleware/error/handler.ts index fbfe846..e462ddf 100644 --- a/src/Middleware/error/handler.ts +++ b/src/Middleware/error/handler.ts @@ -67,7 +67,7 @@ export default function defaultErrorHandler(err: any, req: Request, res: Respons logger.error("--- Unhandled error ---"); logger.error(err); - return res.status(err.status).json({ + return res.status(err.status || 500).json({ type: "error", payload: { message: err.message, diff --git a/src/Routes/media.routes.ts b/src/Routes/media.routes.ts index 9c9fa7b..cd53682 100644 --- a/src/Routes/media.routes.ts +++ b/src/Routes/media.routes.ts @@ -1,7 +1,7 @@ import express from "express"; import fileUpload from "express-fileupload"; import { requireAuthentication } from "../Middleware/auth/auth"; -import { deleteMedia, getAllMedia, uploadImage } from "../Controllers/media.controller"; +import { deleteMedia, getAllMedia, getMediaMeta, uploadImage } from "../Controllers/media.controller"; const router = express.Router(); @@ -11,6 +11,7 @@ router.use("/", express.static("/app/media", { redirect: false })); router.post("/", requireAuthentication, fileUpload(), uploadImage); router.get("/", requireAuthentication, getAllMedia); // Reading all files should be a senstive operation +router.get("/:pid/meta", getMediaMeta); router.delete("/:pid", requireAuthentication, deleteMedia); From 75d416c62e32b8daaddd75869b4950a94c7e4c5c Mon Sep 17 00:00:00 2001 From: Laurin <60652077+Flexla54@users.noreply.github.com> Date: Tue, 17 May 2022 08:14:51 +0200 Subject: [PATCH 12/15] Fix random number --- src/Controllers/media.controller.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Controllers/media.controller.ts b/src/Controllers/media.controller.ts index e9e5303..94dedef 100644 --- a/src/Controllers/media.controller.ts +++ b/src/Controllers/media.controller.ts @@ -176,7 +176,6 @@ export const deleteMedia = async (req: Request, res: Response) => { if (fs.existsSync(location)) { await unlink(location); - 1; } try { From cb1eb1e31704b32ea6234dfd3ecfb345297f7c99 Mon Sep 17 00:00:00 2001 From: Laurin <60652077+Flexla54@users.noreply.github.com> Date: Tue, 17 May 2022 10:09:27 +0200 Subject: [PATCH 13/15] bug fixes in Discipline, Roleschema, Event & Media --- package-lock.json | 2685 ++++++++++++++++++++- src/Controllers/discipline.controller.ts | 6 +- src/Controllers/event.controller.ts | 36 +- src/Controllers/media.controller.ts | 6 +- src/Controllers/role_schema.controller.ts | 6 +- src/Routes/event.routes.ts | 4 +- src/Routes/media.routes.ts | 4 + 7 files changed, 2623 insertions(+), 124 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9948b4b..fb8ed8f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,16 +10,28 @@ "license": "ISC", "dependencies": { "@prisma/client": "^3.3.0", + "@types/express-fileupload": "^1.2.1", + "@types/handlebars": "^4.1.0", "@types/jsonwebtoken": "^8.5.5", + "@types/mjml": "^4.7.0", "@types/node": "^16.10.3", "@types/nodemailer": "^6.4.4", "@types/redis": "^2.8.32", "argon2": "^0.28.2", "dotenv": "^10.0.0", "express": "^4.17.1", + "express-async-errors": "^3.1.1", + "express-fileupload": "^1.2.1", + "file-type": "^16.5.3", + "handlebars": "^4.7.7", + "is-svg": "^4.3.2", "jsonwebtoken": "^8.5.1", + "mjml": "^4.11.0", + "nanoid": "^3.3.3", "nodemailer": "^6.7.0", - "redis": "^3.1.2" + "redis": "^3.1.2", + "winston": "^3.7.2", + "zod": "^3.14.4" }, "devDependencies": { "@types/chai": "^4.2.22", @@ -36,6 +48,25 @@ "typescript": "^4.4.3" } }, + "node_modules/@babel/runtime": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz", + "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==", + "dependencies": { + "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/@cspotcode/source-map-consumer": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", @@ -57,6 +88,16 @@ "node": ">=12" } }, + "node_modules/@dabh/diagnostics": { + "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" + } + }, "node_modules/@mapbox/node-pre-gyp": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.8.tgz", @@ -116,6 +157,11 @@ "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-3.3.0-30.33838b0f78f1fe9052cf9a00e9761c9dc097a63c.tgz", "integrity": "sha512-g21xPYq0zHoJ/xUkNxIf5Hle0oiDyelZHU8gwq7J3RNVrccjbUZ28S99KT4yUabV8SQQRNSnR0QMLGMv9Eqs/A==" }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" + }, "node_modules/@tsconfig/node10": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", @@ -144,12 +190,19 @@ "version": "1.19.1", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.1.tgz", "integrity": "sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg==", - "dev": true, "dependencies": { "@types/connect": "*", "@types/node": "*" } }, + "node_modules/@types/busboy": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@types/busboy/-/busboy-0.3.2.tgz", + "integrity": "sha512-iEvdm9Z9KdSs/ozuh1Z7ZsXrOl8F4M/CLMXPZHr3QuJ4d6Bjn+HBMC5EMKpwpAo8oi8iK9GZfFoHaIMrrZgwVw==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/chai": { "version": "4.2.22", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.22.tgz", @@ -179,7 +232,6 @@ "version": "3.4.35", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dev": true, "dependencies": { "@types/node": "*" } @@ -194,7 +246,6 @@ "version": "4.17.13", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", - "dev": true, "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.18", @@ -202,17 +253,34 @@ "@types/serve-static": "*" } }, + "node_modules/@types/express-fileupload": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/express-fileupload/-/express-fileupload-1.2.2.tgz", + "integrity": "sha512-sWU1EVFfLsdAginKVrkwTRbRPnbn7dawxEFEBgaRDcpNFCUuksZtASaAKEhqwEIg6fSdeTyI6dIUGl3thhrypg==", + "dependencies": { + "@types/busboy": "^0", + "@types/express": "*" + } + }, "node_modules/@types/express-serve-static-core": { "version": "4.17.24", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.24.tgz", "integrity": "sha512-3UJuW+Qxhzwjq3xhwXm2onQcFHn76frIYVbTu+kn24LFxI+dEhdfISDFovPB8VpEgW8oQCTpRuCe+0zJxB7NEA==", - "dev": true, "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*" } }, + "node_modules/@types/handlebars": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@types/handlebars/-/handlebars-4.1.0.tgz", + "integrity": "sha512-gq9YweFKNNB1uFK71eRqsd4niVkXrxHugqWFQkeLRJvGjnxsLr16bYtcsG4tOFwmYi0Bax+wCkbf1reUfdl4kA==", + "deprecated": "This is a stub types definition. handlebars provides its own type definitions, so you do not need this installed.", + "dependencies": { + "handlebars": "*" + } + }, "node_modules/@types/jsonwebtoken": { "version": "8.5.8", "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.8.tgz", @@ -224,8 +292,20 @@ "node_modules/@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", - "dev": true + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + }, + "node_modules/@types/mjml": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@types/mjml/-/mjml-4.7.0.tgz", + "integrity": "sha512-aWWu8Lxq2SexXGs+lBPRUpN3kFf0sDRo3Y4jz7BQ15cQvMfyZOadgFJsNlHmDqI6D2Qjx0PIK+1f9IMXgq9vTA==", + "dependencies": { + "@types/mjml-core": "*" + } + }, + "node_modules/@types/mjml-core": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/@types/mjml-core/-/mjml-core-4.7.1.tgz", + "integrity": "sha512-k5IRafi93tyZBGF+0BTrcBDvG47OueI+Q7TC4V4UjGQn0AMVvL3Y+S26QF/UHMmMJW5r1hxLyv3StX2/+FatFg==" }, "node_modules/@types/mocha": { "version": "9.0.0", @@ -249,14 +329,12 @@ "node_modules/@types/qs": { "version": "6.9.7", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" }, "node_modules/@types/range-parser": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", - "dev": true + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, "node_modules/@types/redis": { "version": "2.8.32", @@ -270,7 +348,6 @@ "version": "1.13.10", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", - "dev": true, "dependencies": { "@types/mime": "^1", "@types/node": "*" @@ -366,7 +443,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, "engines": { "node": ">=6" } @@ -383,7 +459,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -398,7 +473,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -477,6 +551,11 @@ "node": "*" } }, + "node_modules/async": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", + "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==" + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -492,7 +571,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, "engines": { "node": ">=8" } @@ -517,6 +595,11 @@ "node": ">= 0.8" } }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -530,7 +613,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -549,6 +631,17 @@ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" }, + "node_modules/busboy": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.3.1.tgz", + "integrity": "sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw==", + "dependencies": { + "dicer": "0.3.0" + }, + "engines": { + "node": ">=4.5.0" + } + }, "node_modules/bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -557,6 +650,15 @@ "node": ">= 0.8" } }, + "node_modules/camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==", + "dependencies": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, "node_modules/camelcase": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", @@ -653,11 +755,45 @@ "node": "*" } }, + "node_modules/cheerio": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", + "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==", + "dependencies": { + "cheerio-select": "^1.5.0", + "dom-serializer": "^1.3.2", + "domhandler": "^4.2.0", + "htmlparser2": "^6.1.0", + "parse5": "^6.0.1", + "parse5-htmlparser2-tree-adapter": "^6.0.1", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.6.0.tgz", + "integrity": "sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g==", + "dependencies": { + "css-select": "^4.3.0", + "css-what": "^6.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.3.1", + "domutils": "^2.8.0" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, "node_modules/chokidar": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "dev": true, "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -682,22 +818,40 @@ "node": ">=10" } }, + "node_modules/clean-css": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", + "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 4.0" + } + }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, + "node_modules/color": { + "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" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -708,8 +862,16 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/color-string": { + "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" + } }, "node_modules/color-support": { "version": "1.1.3", @@ -719,6 +881,28 @@ "color-support": "bin.js" } }, + "node_modules/color/node_modules/color-convert": { + "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" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "node_modules/colorspace": { + "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" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -731,6 +915,11 @@ "node": ">= 0.8" } }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, "node_modules/component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", @@ -742,6 +931,15 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "node_modules/config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, "node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", @@ -797,6 +995,32 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -875,6 +1099,22 @@ "node": ">=0.10" } }, + "node_modules/detect-node": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", + "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==" + }, + "node_modules/dicer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz", + "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==", + "dependencies": { + "streamsearch": "0.1.2" + }, + "engines": { + "node": ">=4.5.0" + } + }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -884,6 +1124,57 @@ "node": ">=0.3.1" } }, + "node_modules/dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, "node_modules/dotenv": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", @@ -900,6 +1191,42 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "dependencies": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "bin": { + "editorconfig": "bin/editorconfig" + } + }, + "node_modules/editorconfig/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/editorconfig/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/editorconfig/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -910,6 +1237,11 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, + "node_modules/enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -918,15 +1250,33 @@ "node": ">= 0.8" } }, + "node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, "engines": { "node": ">=6" } }, + "node_modules/escape-goat": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-3.0.0.tgz", + "integrity": "sha512-w3PwNZJwRxlp47QGzhuEBldEqVHHhh8/tIPcl6ecf2Bou99cdAt0knihBV0Ecc7CGxYduXVBDheH1K2oADRlvw==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -992,17 +1342,71 @@ "node": ">= 0.10.0" } }, + "node_modules/express-async-errors": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/express-async-errors/-/express-async-errors-3.1.1.tgz", + "integrity": "sha512-h6aK1da4tpqWSbyCa3FxB/V6Ehd4EEB15zyQq9qe75OZBp0krinNKuH4rAY+S/U/2I36vdLAUFSjQJ+TFmODng==", + "peerDependencies": { + "express": "^4.16.2" + } + }, + "node_modules/express-fileupload": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/express-fileupload/-/express-fileupload-1.3.1.tgz", + "integrity": "sha512-LD1yabD3exmWIFujKGDnT1rmxSomaqQSlUvzIsrA1ZgwCJ6ci7lg2YHFGM3Q6DfK+Yk0gAVU7GWLE7qDMwZLkw==", + "dependencies": { + "busboy": "^0.3.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, + "node_modules/fast-xml-parser": { + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.21.1.tgz", + "integrity": "sha512-FTFVjYoBOZTJekiUsawGsSYV9QL0A+zDYCRj7y34IO6Jg+2IMYEtQa+bbictpdpV8dHxXywqU7C0gRDEOFtBFg==", + "dependencies": { + "strnum": "^1.0.4" + }, + "bin": { + "xml2js": "cli.js" + }, + "funding": { + "type": "paypal", + "url": "https://paypal.me/naturalintelligence" + } + }, + "node_modules/fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" + }, + "node_modules/file-type": { + "version": "16.5.3", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.3.tgz", + "integrity": "sha512-uVsl7iFhHSOY4bEONLlTK47iAHtNsFHWP5YE4xJfZ4rnX7S1Q3wce09XgqSC7E/xh8Ncv/be1lNoyprlUH/x6A==", + "dependencies": { + "readable-web-to-node-stream": "^3.0.0", + "strtok3": "^6.2.4", + "token-types": "^4.1.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -1052,6 +1456,11 @@ "flat": "cli.js" } }, + "node_modules/fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" + }, "node_modules/form-data": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", @@ -1111,7 +1520,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "hasInstallScript": true, "optional": true, "os": [ @@ -1144,7 +1552,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -1181,7 +1588,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -1198,6 +1604,26 @@ "node": ">=4.x" } }, + "node_modules/handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -1216,11 +1642,48 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, "bin": { "he": "bin/he" } }, + "node_modules/html-minifier": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-4.0.0.tgz", + "integrity": "sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==", + "dependencies": { + "camel-case": "^3.0.0", + "clean-css": "^4.2.1", + "commander": "^2.19.0", + "he": "^1.2.0", + "param-case": "^2.1.1", + "relateurl": "^0.2.7", + "uglify-js": "^3.5.1" + }, + "bin": { + "html-minifier": "cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, "node_modules/http-errors": { "version": "1.7.2", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", @@ -1280,6 +1743,25 @@ "node": ">=0.10.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -1294,6 +1776,11 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, "node_modules/ip-regex": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", @@ -1311,11 +1798,15 @@ "node": ">= 0.10" } }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, "dependencies": { "binary-extensions": "^2.0.0" }, @@ -1327,7 +1818,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -1344,7 +1834,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -1368,7 +1857,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "engines": { "node": ">=0.12.0" } @@ -1382,6 +1870,31 @@ "node": ">=8" } }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-svg": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-4.3.2.tgz", + "integrity": "sha512-mM90duy00JGMyjqIVHu9gNTjywdZV+8qNasX8cm/EEYZ53PHDgajvbBwNVvty5dwSAxLUD3p3bdo+7sR/UMrpw==", + "dependencies": { + "fast-xml-parser": "^3.19.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -1406,6 +1919,25 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, + "node_modules/js-beautify": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.3.tgz", + "integrity": "sha512-f1ra8PHtOEu/70EBnmiUlV8nJePS58y9qKjl4JHfYWlFH6bo7ogZBz//FAZp7jDuXtYnGYKymZPlrg2I/9Zo4g==", + "dependencies": { + "config-chain": "^1.1.13", + "editorconfig": "^0.15.3", + "glob": "^7.1.3", + "nopt": "^5.0.0" + }, + "bin": { + "css-beautify": "js/bin/css-beautify.js", + "html-beautify": "js/bin/html-beautify.js", + "js-beautify": "js/bin/js-beautify.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -1452,6 +1984,32 @@ "semver": "bin/semver" } }, + "node_modules/juice": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/juice/-/juice-7.0.0.tgz", + "integrity": "sha512-AjKQX31KKN+uJs+zaf+GW8mBO/f/0NqSh2moTMyvwBY+4/lXIYTU8D8I2h6BAV3Xnz6GGsbalUyFqbYMe+Vh+Q==", + "dependencies": { + "cheerio": "^1.0.0-rc.3", + "commander": "^5.1.0", + "mensch": "^0.3.4", + "slick": "^1.12.2", + "web-resource-inliner": "^5.0.0" + }, + "bin": { + "juice": "bin/juice" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/juice/node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "engines": { + "node": ">= 6" + } + }, "node_modules/jwa": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", @@ -1471,6 +2029,11 @@ "safe-buffer": "^5.0.1" } }, + "node_modules/kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -1486,6 +2049,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "node_modules/lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -1537,6 +2105,28 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/logform": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.4.0.tgz", + "integrity": "sha512-CPSJw4ftjf517EhXZGGvTHHkYobo7ZCc0kvwUoOYcjfR2UVrI66RHj8MCrfAdEitdmFqbu2BYdYs8FHHZSb6iw==", + "dependencies": { + "@colors/colors": "1.5.0", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + } + }, + "node_modules/logform/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=" + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -1584,6 +2174,11 @@ "node": ">= 0.6" } }, + "node_modules/mensch": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/mensch/-/mensch-0.3.4.tgz", + "integrity": "sha512-IAeFvcOnV9V0Yk+bFhYR07O3yNina9ANIN5MoXBKYJ/RLYPurd2d0yw14MDhpr9/momp0WofT1bPUh3hkzdi/g==" + }, "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -1638,6 +2233,11 @@ "node": "*" } }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + }, "node_modules/minipass": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", @@ -1661,6 +2261,404 @@ "node": ">= 8" } }, + "node_modules/mjml": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml/-/mjml-4.12.0.tgz", + "integrity": "sha512-uWDu1pPQVyoX4iKIrM02J6qOBN6PC1rSMP64DKi2qGU4dpOztVgvTBh6JttIbINV4ZiALtpeGu+jeEUqp2ROXA==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "mjml-cli": "4.12.0", + "mjml-core": "4.12.0", + "mjml-migrate": "4.12.0", + "mjml-preset-core": "4.12.0", + "mjml-validator": "4.12.0" + }, + "bin": { + "mjml": "bin/mjml" + } + }, + "node_modules/mjml-accordion": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-accordion/-/mjml-accordion-4.12.0.tgz", + "integrity": "sha512-vqBk4NhXN+w6F3c5vnLxkvgneREpkwTzZpbxtMzpNqkUW2yei0oSQ26j/wLgXYTaX+4Czp+oVr0cnNxjyCZHjA==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-body": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-body/-/mjml-body-4.12.0.tgz", + "integrity": "sha512-IQBAHhdRKsNUXat+oxvRTjVJ1qzTRkNjFe/mtD/Pbn9olUnQmV+RKxnkqRZf7QtiTxVIOGC4kU9VLPjNymsFXQ==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-button": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-button/-/mjml-button-4.12.0.tgz", + "integrity": "sha512-XJfLP+mHvCr6Ky16ooYz5+8ODkf10+ATyvENCKyrof+rietr5WxN2FxWCZA9Orq20OE74/hvaOeZZdkxwtsXig==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-carousel": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-carousel/-/mjml-carousel-4.12.0.tgz", + "integrity": "sha512-vQ5Aqvix9mbAE0GspxIDpKK4dVMRuKFO3qV6N/CkrIAOe4+2CKV4AMn2fWUvQEx6hA6CGxayeLkI7E0hNOWcZA==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-cli": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-cli/-/mjml-cli-4.12.0.tgz", + "integrity": "sha512-//Y4XsN6aFgpZtDbQZRu4qe+CQzGWV3i5K3rC1dwPcdtpDMsXBPKiwIZFrQxpRVBwxs0hU4ZBQOMtvYZkoicdQ==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "chokidar": "^3.0.0", + "glob": "^7.1.1", + "html-minifier": "^4.0.0", + "js-beautify": "^1.6.14", + "lodash": "^4.17.21", + "mjml-core": "4.12.0", + "mjml-migrate": "4.12.0", + "mjml-parser-xml": "4.12.0", + "mjml-validator": "4.12.0", + "yargs": "^16.1.0" + }, + "bin": { + "mjml-cli": "bin/mjml" + } + }, + "node_modules/mjml-column": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-column/-/mjml-column-4.12.0.tgz", + "integrity": "sha512-Ub/7ov2B1T2jfSpxvF61o3UCU4gGDFUqIelr7ghuazLc2KvTwdHYeR8mWt8l8RBM6zZiWjkYEFMP22ty7WXztg==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-core": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-core/-/mjml-core-4.12.0.tgz", + "integrity": "sha512-B3gUkV3kFN1IlzIV3GnpWBmE21XHH5ARyydMxacR75iC53PvJ9c50hr6DWLGdrrDCC6Fdud8jTmgD9dnWPmJhQ==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "cheerio": "1.0.0-rc.10", + "detect-node": "2.0.4", + "html-minifier": "^4.0.0", + "js-beautify": "^1.6.14", + "juice": "^7.0.0", + "lodash": "^4.17.21", + "mjml-migrate": "4.12.0", + "mjml-parser-xml": "4.12.0", + "mjml-validator": "4.12.0" + } + }, + "node_modules/mjml-divider": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-divider/-/mjml-divider-4.12.0.tgz", + "integrity": "sha512-L87iqrhVS+PnUInYbXK4lcTQcHfWMTL7ZqDL9XEMBywzX8cCfviLNMbqmLCO2HD8nMPVMRbcE32H04T6LyZ2qw==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-group": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-group/-/mjml-group-4.12.0.tgz", + "integrity": "sha512-Rl7Iydd7M2SnbH1ItIi07hYY+FrEai5c6kYMKbcFWAuNupCuvUThuhx1AphMPCZFMLbbPSKNWMarBkWhepS7cw==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-head": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-head/-/mjml-head-4.12.0.tgz", + "integrity": "sha512-LcI4ykOB6nMV5W//tF9S1unlXxexfNZUnnyZ2OOzP1V7J5poLXdKXqB8XATN2YGGTsDZ5Q/5V1KO+NnjpW7zSw==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-head-attributes": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-head-attributes/-/mjml-head-attributes-4.12.0.tgz", + "integrity": "sha512-tRwKUzIrtcw1FGy8Xpy4vrFo0u2daZgqx3X0cM5WWrGFcKe7ZdjNEAkU/3w+WsFjeMcb0fHdKvd+sxBjPJ6fpA==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-head-breakpoint": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-head-breakpoint/-/mjml-head-breakpoint-4.12.0.tgz", + "integrity": "sha512-BVVbvAIcIu49P1EJkEPPIY8Gu4GleyzpkdddqD3ihAPn3Pz07SEsFlHvI35eCszuaJeeMbSSxLrsF4m+aQQlvw==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-head-font": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-head-font/-/mjml-head-font-4.12.0.tgz", + "integrity": "sha512-ja5sWbGOIr1gF/7IIPzrgOlWYiKk57BC8JWYRANV7CxNKa635sd6aBJHbzXv1A6Ph+zH5KtE0MSQCK8n49BIsw==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-head-html-attributes": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-head-html-attributes/-/mjml-head-html-attributes-4.12.0.tgz", + "integrity": "sha512-XJesJuW9uzlNN5w/S7t5ZquSVDay7BehOKmIZKMwKn1y0SJBXiakcwt9M9hhF0HB189Bew0gpGt3m7QYvTez8g==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-head-preview": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-head-preview/-/mjml-head-preview-4.12.0.tgz", + "integrity": "sha512-pr02ZkxwU6/LWhrL3xP/hLrUXx27I1FnfgaYjgvMjh6pMURuy7W+W8BrNJKeyXZo685b2A5lNFDJV7rCJ6HrEQ==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-head-style": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-head-style/-/mjml-head-style-4.12.0.tgz", + "integrity": "sha512-64IVdJ2Xl000SrwLt4cebl+MiZcino/ywMkuLQ/c48XeR6pkvbjXYAInWsdlMG1y041n1bOZICNnQQc4xhNJrw==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-head-title": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-head-title/-/mjml-head-title-4.12.0.tgz", + "integrity": "sha512-c7thJUmNLIdVy1ftLbYUjchHwrIfAb9SHdbuVQHdtQz45a3Ni2nie4AWxF/srn90k8q/uEKtQq1taOa4f71Zug==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-hero": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-hero/-/mjml-hero-4.12.0.tgz", + "integrity": "sha512-j87DgSAyLzMMuNtVqR1okkI/orKnvZoR7i+RsA1yueNql9dZtnw3Ezy8cas8MJaAoGOmqIy9AqGRJIr82w4mxQ==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-image": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-image/-/mjml-image-4.12.0.tgz", + "integrity": "sha512-P77M+PLLNn7QvGhL8sx+6yzkQbEMxIQO3yxqUC+x8Ie8kXS8phSNGcqx8qfhdN7p7sQ3CZdOIZSXkG7RRAF94w==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-migrate": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-migrate/-/mjml-migrate-4.12.0.tgz", + "integrity": "sha512-KDdPkuOzL9CAekY0CslM0Yqiomk4TubNMszw6UFfylp5xRA3CfBo0HdGcnewHBkZ8+isjPlzDWf3n+NkU11OiA==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "js-beautify": "^1.6.14", + "lodash": "^4.17.21", + "mjml-core": "4.12.0", + "mjml-parser-xml": "4.12.0", + "yargs": "^16.1.0" + }, + "bin": { + "migrate": "lib/cli.js" + } + }, + "node_modules/mjml-navbar": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-navbar/-/mjml-navbar-4.12.0.tgz", + "integrity": "sha512-TWKV5lFgwUvRbG+FNz6Uo7mGPJRU/BK1v0BeQr1e5Ykft4052iYIuv2XNwRkeoORmLT+7AN8FbkP+TVBpflbWw==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-parser-xml": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-parser-xml/-/mjml-parser-xml-4.12.0.tgz", + "integrity": "sha512-cmCcvoiirH0kuCglGAjwBVfDrlnqS3e83uBwPN6wDN6IfxSgsPT6IV0vRfcJERsr2ThpFjvoSq4GmYi9oCUSMw==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "detect-node": "2.0.4", + "htmlparser2": "^4.1.0", + "lodash": "^4.17.15" + } + }, + "node_modules/mjml-parser-xml/node_modules/domhandler": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz", + "integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==", + "dependencies": { + "domelementtype": "^2.0.1" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/mjml-parser-xml/node_modules/htmlparser2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-4.1.0.tgz", + "integrity": "sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^3.0.0", + "domutils": "^2.0.0", + "entities": "^2.0.0" + } + }, + "node_modules/mjml-preset-core": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-preset-core/-/mjml-preset-core-4.12.0.tgz", + "integrity": "sha512-zoiCKcl/bK43ltr2J8dY9Qg5fcB3TbhaWcTG84oGYWdii5WEkKTXj5hpP1ss1XqdOGMNLij/HVwmli+xQCo6FQ==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "mjml-accordion": "4.12.0", + "mjml-body": "4.12.0", + "mjml-button": "4.12.0", + "mjml-carousel": "4.12.0", + "mjml-column": "4.12.0", + "mjml-divider": "4.12.0", + "mjml-group": "4.12.0", + "mjml-head": "4.12.0", + "mjml-head-attributes": "4.12.0", + "mjml-head-breakpoint": "4.12.0", + "mjml-head-font": "4.12.0", + "mjml-head-html-attributes": "4.12.0", + "mjml-head-preview": "4.12.0", + "mjml-head-style": "4.12.0", + "mjml-head-title": "4.12.0", + "mjml-hero": "4.12.0", + "mjml-image": "4.12.0", + "mjml-navbar": "4.12.0", + "mjml-raw": "4.12.0", + "mjml-section": "4.12.0", + "mjml-social": "4.12.0", + "mjml-spacer": "4.12.0", + "mjml-table": "4.12.0", + "mjml-text": "4.12.0", + "mjml-wrapper": "4.12.0" + } + }, + "node_modules/mjml-raw": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-raw/-/mjml-raw-4.12.0.tgz", + "integrity": "sha512-vQUmrEZEgu0DCca7tiPdQ/vf8GM5QyeaabbLd1rX3XCt5Mid47LCdszmVcrk1WxqNuExIw1fNyEGCCDeP2qCJg==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-section": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-section/-/mjml-section-4.12.0.tgz", + "integrity": "sha512-5BdHrAghS/XJ40t3qtLHpY3rIVuBnJXv8dGm8U+oMVAzw3L4ySk5WI+FulRkchdPFCKpeXQZjXZaX0C7pmNaIw==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-social": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-social/-/mjml-social-4.12.0.tgz", + "integrity": "sha512-eTsqJoKP65Imawh+WEX2dv4N34ItUmvIbsCeSQPhC/NG6klxDjzg5oDA1F2tZk+CPIuXVmJiauQ5/vPHLzUiVw==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-spacer": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-spacer/-/mjml-spacer-4.12.0.tgz", + "integrity": "sha512-YB+VCixcuWXDzICrGLFw7PJDkL166e4OG8IUUB2yhvd5VHtFFBc0iRksaEAumOL1r6MnXVCRq4Wcmxlzj7zOfQ==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-table": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-table/-/mjml-table-4.12.0.tgz", + "integrity": "sha512-IuLvyiJOsM6RgobuIfZuM36fJcoH8pK/A4awCLTEme0HCxEkkjzDkl4RBMK/KX53Cpor0U6oR6RlQfZcducpLg==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-text": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-text/-/mjml-text-4.12.0.tgz", + "integrity": "sha512-AFcXiQBC48ZfKKgAdU0NRS2nqftc8zLGxBtPwHNgFkuh5Lf2rWgPK6JRubNi7qhb8Sd7M8stU+LIRA5sxM1nRQ==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "node_modules/mjml-validator": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-validator/-/mjml-validator-4.12.0.tgz", + "integrity": "sha512-EmOScfcJJ4LdIyHnE+K4FdkryQ+c6QRV7qp+zlunAHE5AUPaBS0OrHPHuNo1sOu7g1tc+bVl7eHR4FIb0Wkzwg==", + "dependencies": { + "@babel/runtime": "^7.14.6" + } + }, + "node_modules/mjml-wrapper": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-wrapper/-/mjml-wrapper-4.12.0.tgz", + "integrity": "sha512-u0pq+A9QBLwpeF/hdv2uWZIv3Qp4wwf+CMaHZsUpb3YfOJD/6YKwLvkeA7ngE+YxwwzgtgjmIEs4eDae1evlgQ==", + "dependencies": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0", + "mjml-section": "4.12.0" + } + }, "node_modules/mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -1753,16 +2751,27 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, + "node_modules/mocha/node_modules/nanoid": { + "version": "3.1.25", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", + "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "node_modules/nanoid": { - "version": "3.1.25", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", - "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", - "dev": true, + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -1778,6 +2787,19 @@ "node": ">= 0.6" } }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "node_modules/no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "dependencies": { + "lower-case": "^1.1.1" + } + }, "node_modules/node-addon-api": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", @@ -1828,7 +2850,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -1844,6 +2865,17 @@ "set-blocking": "^2.0.0" } }, + "node_modules/nth-check": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", + "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -1871,6 +2903,14 @@ "wrappy": "1" } }, + "node_modules/one-time": { + "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" + } + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -1901,6 +2941,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", + "dependencies": { + "no-case": "^2.2.0" + } + }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dependencies": { + "parse5": "^6.0.1" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -1940,11 +3001,22 @@ "node": "*" } }, + "node_modules/peek-readable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", + "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==", + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/picomatch": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true, "engines": { "node": ">=8.6" }, @@ -1975,6 +3047,11 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=" + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -1987,6 +3064,11 @@ "node": ">= 0.10" } }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, "node_modules/qs": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", @@ -2041,11 +3123,38 @@ "util-deprecate": "~1.0.1" } }, + "node_modules/readable-web-to-node-stream": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", + "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", + "dependencies": { + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/readable-web-to-node-stream/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, "dependencies": { "picomatch": "^2.2.1" }, @@ -2095,11 +3204,23 @@ "node": ">=4" } }, + "node_modules/regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -2123,6 +3244,14 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "node_modules/safe-stable-stringify": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.3.1.tgz", + "integrity": "sha512-kYBSfT+troD9cDA85VDnHZ1rpHC50O0g1e6WlGHVCz/g+JS+9WKLj+XwFYyR8UbrZN8ll9HUpDAAddY58MGisg==", + "engines": { + "node": ">=10" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -2203,11 +3332,48 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" }, + "node_modules/sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/slick": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/slick/-/slick-1.12.2.tgz", + "integrity": "sha1-vQSN23TefRymkV+qSldXCzVQwtc=", + "engines": { + "node": "*" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "engines": { + "node": "*" + } + }, "node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -2216,6 +3382,14 @@ "node": ">= 0.6" } }, + "node_modules/streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -2260,6 +3434,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + }, + "node_modules/strtok3": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", + "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", + "dependencies": { + "@tokenizer/token": "^0.3.0", + "peek-readable": "^4.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/superagent": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", @@ -2327,11 +3522,15 @@ "node": ">= 10" } }, + "node_modules/text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, "node_modules/to-regex-range": { "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==", - "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -2347,11 +3546,32 @@ "node": ">=0.6" } }, + "node_modules/token-types": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.0.tgz", + "integrity": "sha512-P0rrp4wUpefLncNamWIef62J0v0kQR/GfDVji9WKY7GDCWy5YbVSrKUTam07iWPZQGy0zWNOfstYTykMmPNR7w==", + "dependencies": { + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" }, + "node_modules/triple-beam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", + "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" + }, "node_modules/ts-node": { "version": "10.2.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", @@ -2396,6 +3616,11 @@ } } }, + "node_modules/tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -2430,6 +3655,17 @@ "node": ">=4.2.0" } }, + "node_modules/uglify-js": { + "version": "3.15.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.5.tgz", + "integrity": "sha512-hNM5q5GbBRB5xB+PMqVRcgYe4c8jbyZ1pzZhS6jbq54/4F2gFK869ZheiE5A8/t+W5jtTNpWef/5Q9zk639FNQ==", + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -2438,6 +3674,11 @@ "node": ">= 0.8" } }, + "node_modules/upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=" + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -2451,6 +3692,14 @@ "node": ">= 0.4.0" } }, + "node_modules/valid-data-url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-3.0.1.tgz", + "integrity": "sha512-jOWVmzVceKlVVdwjNSenT4PbGghU0SBIizAev8ofZVgivk/TVHXSbNL8LP6M3spZvkR9/QolkyJavGSX5Cs0UA==", + "engines": { + "node": ">=10" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -2459,6 +3708,58 @@ "node": ">= 0.8" } }, + "node_modules/web-resource-inliner": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/web-resource-inliner/-/web-resource-inliner-5.0.0.tgz", + "integrity": "sha512-AIihwH+ZmdHfkJm7BjSXiEClVt4zUFqX4YlFAzjL13wLtDuUneSaFvDBTbdYRecs35SiU7iNKbMnN+++wVfb6A==", + "dependencies": { + "ansi-colors": "^4.1.1", + "escape-goat": "^3.0.0", + "htmlparser2": "^4.0.0", + "mime": "^2.4.6", + "node-fetch": "^2.6.0", + "valid-data-url": "^3.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/web-resource-inliner/node_modules/domhandler": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz", + "integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==", + "dependencies": { + "domelementtype": "^2.0.1" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/web-resource-inliner/node_modules/htmlparser2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-4.1.0.tgz", + "integrity": "sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==", + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^3.0.0", + "domutils": "^2.0.0", + "entities": "^2.0.0" + } + }, + "node_modules/web-resource-inliner/node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -2496,6 +3797,70 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, + "node_modules/winston": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.7.2.tgz", + "integrity": "sha512-QziIqtojHBoyzUOdQvQiar1DH0Xp9nF1A1y7NVy2DGEsz82SBDtOalS0ulTRGVT14xPX3WRWkCsdcJKqNflKng==", + "dependencies": { + "@dabh/diagnostics": "^2.0.2", + "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" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-transport": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz", + "integrity": "sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==", + "dependencies": { + "logform": "^2.3.2", + "readable-stream": "^3.6.0", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 6.4.0" + } + }, + "node_modules/winston-transport/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/winston/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + }, "node_modules/workerpool": { "version": "6.1.5", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", @@ -2506,7 +3871,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -2528,7 +3892,6 @@ "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, "engines": { "node": ">=10" } @@ -2542,7 +3905,6 @@ "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -2560,7 +3922,6 @@ "version": "20.2.4", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true, "engines": { "node": ">=10" } @@ -2600,9 +3961,30 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.16.0.tgz", + "integrity": "sha512-szrIkryADbTM+xBt2a1KoS2CJQXec4f9xG78bj5MJeEH/XqmmHpnO+fG3IE115AKBJak+2HrbxLZkc9mhdbDKA==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } } }, "dependencies": { + "@babel/runtime": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.9.tgz", + "integrity": "sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==" + }, "@cspotcode/source-map-consumer": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", @@ -2618,6 +4000,16 @@ "@cspotcode/source-map-consumer": "0.8.0" } }, + "@dabh/diagnostics": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "requires": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, "@mapbox/node-pre-gyp": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.8.tgz", @@ -2658,6 +4050,11 @@ "resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-3.3.0-30.33838b0f78f1fe9052cf9a00e9761c9dc097a63c.tgz", "integrity": "sha512-g21xPYq0zHoJ/xUkNxIf5Hle0oiDyelZHU8gwq7J3RNVrccjbUZ28S99KT4yUabV8SQQRNSnR0QMLGMv9Eqs/A==" }, + "@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==" + }, "@tsconfig/node10": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", @@ -2686,12 +4083,19 @@ "version": "1.19.1", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.1.tgz", "integrity": "sha512-a6bTJ21vFOGIkwM0kzh9Yr89ziVxq4vYH2fQ6N8AeipEzai/cFK6aGMArIkUeIdRIgpwQa+2bXiLuUJCpSf2Cg==", - "dev": true, "requires": { "@types/connect": "*", "@types/node": "*" } }, + "@types/busboy": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@types/busboy/-/busboy-0.3.2.tgz", + "integrity": "sha512-iEvdm9Z9KdSs/ozuh1Z7ZsXrOl8F4M/CLMXPZHr3QuJ4d6Bjn+HBMC5EMKpwpAo8oi8iK9GZfFoHaIMrrZgwVw==", + "requires": { + "@types/node": "*" + } + }, "@types/chai": { "version": "4.2.22", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.22.tgz", @@ -2720,7 +4124,6 @@ "version": "3.4.35", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dev": true, "requires": { "@types/node": "*" } @@ -2735,7 +4138,6 @@ "version": "4.17.13", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", - "dev": true, "requires": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.18", @@ -2743,17 +4145,33 @@ "@types/serve-static": "*" } }, + "@types/express-fileupload": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/express-fileupload/-/express-fileupload-1.2.2.tgz", + "integrity": "sha512-sWU1EVFfLsdAginKVrkwTRbRPnbn7dawxEFEBgaRDcpNFCUuksZtASaAKEhqwEIg6fSdeTyI6dIUGl3thhrypg==", + "requires": { + "@types/busboy": "^0", + "@types/express": "*" + } + }, "@types/express-serve-static-core": { "version": "4.17.24", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.24.tgz", "integrity": "sha512-3UJuW+Qxhzwjq3xhwXm2onQcFHn76frIYVbTu+kn24LFxI+dEhdfISDFovPB8VpEgW8oQCTpRuCe+0zJxB7NEA==", - "dev": true, "requires": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*" } }, + "@types/handlebars": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@types/handlebars/-/handlebars-4.1.0.tgz", + "integrity": "sha512-gq9YweFKNNB1uFK71eRqsd4niVkXrxHugqWFQkeLRJvGjnxsLr16bYtcsG4tOFwmYi0Bax+wCkbf1reUfdl4kA==", + "requires": { + "handlebars": "*" + } + }, "@types/jsonwebtoken": { "version": "8.5.8", "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.8.tgz", @@ -2765,8 +4183,20 @@ "@types/mime": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", - "dev": true + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==" + }, + "@types/mjml": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@types/mjml/-/mjml-4.7.0.tgz", + "integrity": "sha512-aWWu8Lxq2SexXGs+lBPRUpN3kFf0sDRo3Y4jz7BQ15cQvMfyZOadgFJsNlHmDqI6D2Qjx0PIK+1f9IMXgq9vTA==", + "requires": { + "@types/mjml-core": "*" + } + }, + "@types/mjml-core": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/@types/mjml-core/-/mjml-core-4.7.1.tgz", + "integrity": "sha512-k5IRafi93tyZBGF+0BTrcBDvG47OueI+Q7TC4V4UjGQn0AMVvL3Y+S26QF/UHMmMJW5r1hxLyv3StX2/+FatFg==" }, "@types/mocha": { "version": "9.0.0", @@ -2790,14 +4220,12 @@ "@types/qs": { "version": "6.9.7", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" }, "@types/range-parser": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", - "dev": true + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, "@types/redis": { "version": "2.8.32", @@ -2811,7 +4239,6 @@ "version": "1.13.10", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", - "dev": true, "requires": { "@types/mime": "^1", "@types/node": "*" @@ -2885,8 +4312,7 @@ "ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" }, "ansi-regex": { "version": "5.0.1", @@ -2897,7 +4323,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -2906,7 +4331,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -2971,6 +4395,11 @@ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, + "async": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", + "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==" + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -2985,8 +4414,7 @@ "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" }, "body-parser": { "version": "1.19.0", @@ -3005,6 +4433,11 @@ "type-is": "~1.6.17" } }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3018,7 +4451,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -3034,11 +4466,28 @@ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" }, + "busboy": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.3.1.tgz", + "integrity": "sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw==", + "requires": { + "dicer": "0.3.0" + } + }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" }, + "camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==", + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, "camelcase": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", @@ -3110,11 +4559,36 @@ "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", "dev": true }, + "cheerio": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", + "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==", + "requires": { + "cheerio-select": "^1.5.0", + "dom-serializer": "^1.3.2", + "domhandler": "^4.2.0", + "htmlparser2": "^6.1.0", + "parse5": "^6.0.1", + "parse5-htmlparser2-tree-adapter": "^6.0.1", + "tslib": "^2.2.0" + } + }, + "cheerio-select": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.6.0.tgz", + "integrity": "sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g==", + "requires": { + "css-select": "^4.3.0", + "css-what": "^6.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.3.1", + "domutils": "^2.8.0" + } + }, "chokidar": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz", "integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==", - "dev": true, "requires": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -3131,22 +4605,52 @@ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" }, + "clean-css": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.4.tgz", + "integrity": "sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==", + "requires": { + "source-map": "~0.6.0" + } + }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, + "color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "requires": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + }, + "dependencies": { + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + } + } + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "requires": { "color-name": "~1.1.4" } @@ -3154,14 +4658,31 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } }, "color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" }, + "colorspace": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "requires": { + "color": "^3.1.3", + "text-hex": "1.0.x" + } + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -3171,6 +4692,11 @@ "delayed-stream": "~1.0.0" } }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" + }, "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", @@ -3182,6 +4708,15 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "config-chain": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", + "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", @@ -3228,6 +4763,23 @@ "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, + "css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "requires": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + } + }, + "css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==" + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -3282,12 +4834,58 @@ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" }, + "detect-node": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", + "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==" + }, + "dicer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz", + "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==", + "requires": { + "streamsearch": "0.1.2" + } + }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, + "dom-serializer": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", + "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" + }, + "domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, "dotenv": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", @@ -3301,6 +4899,38 @@ "safe-buffer": "^5.0.1" } }, + "editorconfig": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", + "integrity": "sha512-M9wIMFx96vq0R4F+gRpY3o2exzb8hEj/n9S8unZtHSvYjibBp/iMufSzvmOcV/laG0ZtuTVGtiJggPOSW2r93g==", + "requires": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + } + } + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -3311,16 +4941,30 @@ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, + "enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" + }, "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "escape-goat": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/escape-goat/-/escape-goat-3.0.0.tgz", + "integrity": "sha512-w3PwNZJwRxlp47QGzhuEBldEqVHHhh8/tIPcl6ecf2Bou99cdAt0knihBV0Ecc7CGxYduXVBDheH1K2oADRlvw==" }, "escape-html": { "version": "1.0.3", @@ -3375,17 +5019,53 @@ "vary": "~1.1.2" } }, + "express-async-errors": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/express-async-errors/-/express-async-errors-3.1.1.tgz", + "integrity": "sha512-h6aK1da4tpqWSbyCa3FxB/V6Ehd4EEB15zyQq9qe75OZBp0krinNKuH4rAY+S/U/2I36vdLAUFSjQJ+TFmODng==", + "requires": {} + }, + "express-fileupload": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/express-fileupload/-/express-fileupload-1.3.1.tgz", + "integrity": "sha512-LD1yabD3exmWIFujKGDnT1rmxSomaqQSlUvzIsrA1ZgwCJ6ci7lg2YHFGM3Q6DfK+Yk0gAVU7GWLE7qDMwZLkw==", + "requires": { + "busboy": "^0.3.1" + } + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, + "fast-xml-parser": { + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-3.21.1.tgz", + "integrity": "sha512-FTFVjYoBOZTJekiUsawGsSYV9QL0A+zDYCRj7y34IO6Jg+2IMYEtQa+bbictpdpV8dHxXywqU7C0gRDEOFtBFg==", + "requires": { + "strnum": "^1.0.4" + } + }, + "fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==" + }, + "file-type": { + "version": "16.5.3", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-16.5.3.tgz", + "integrity": "sha512-uVsl7iFhHSOY4bEONLlTK47iAHtNsFHWP5YE4xJfZ4rnX7S1Q3wce09XgqSC7E/xh8Ncv/be1lNoyprlUH/x6A==", + "requires": { + "readable-web-to-node-stream": "^3.0.0", + "strtok3": "^6.2.4", + "token-types": "^4.1.1" + } + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "requires": { "to-regex-range": "^5.0.1" } @@ -3420,6 +5100,11 @@ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", "dev": true }, + "fn.name": { + "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": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", @@ -3464,7 +5149,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, "optional": true }, "gauge": { @@ -3486,8 +5170,7 @@ "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-func-name": { "version": "2.0.0", @@ -3512,7 +5195,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "requires": { "is-glob": "^4.0.1" } @@ -3523,6 +5205,18 @@ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, + "handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + } + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -3537,8 +5231,32 @@ "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, + "html-minifier": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-4.0.0.tgz", + "integrity": "sha512-aoGxanpFPLg7MkIl/DDFYtb0iWz7jMFGqFhvEDZga6/4QTjneiD8I/NXL1x5aaoCp7FSIT6h/OhykDdPsbtMig==", + "requires": { + "camel-case": "^3.0.0", + "clean-css": "^4.2.1", + "commander": "^2.19.0", + "he": "^1.2.0", + "param-case": "^2.1.1", + "relateurl": "^0.2.7", + "uglify-js": "^3.5.1" + } + }, + "htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } }, "http-errors": { "version": "1.7.2", @@ -3584,6 +5302,11 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -3598,6 +5321,11 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, "ip-regex": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", @@ -3609,11 +5337,15 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, "requires": { "binary-extensions": "^2.0.0" } @@ -3621,8 +5353,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, "is-fullwidth-code-point": { "version": "3.0.0", @@ -3633,7 +5364,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -3650,8 +5380,7 @@ "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, "is-plain-obj": { "version": "2.1.0", @@ -3659,6 +5388,19 @@ "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==" + }, + "is-svg": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-4.3.2.tgz", + "integrity": "sha512-mM90duy00JGMyjqIVHu9gNTjywdZV+8qNasX8cm/EEYZ53PHDgajvbBwNVvty5dwSAxLUD3p3bdo+7sR/UMrpw==", + "requires": { + "fast-xml-parser": "^3.19.0" + } + }, "is-unicode-supported": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", @@ -3677,6 +5419,17 @@ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, + "js-beautify": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.3.tgz", + "integrity": "sha512-f1ra8PHtOEu/70EBnmiUlV8nJePS58y9qKjl4JHfYWlFH6bo7ogZBz//FAZp7jDuXtYnGYKymZPlrg2I/9Zo4g==", + "requires": { + "config-chain": "^1.1.13", + "editorconfig": "^0.15.3", + "glob": "^7.1.3", + "nopt": "^5.0.0" + } + }, "js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -3715,6 +5468,25 @@ } } }, + "juice": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/juice/-/juice-7.0.0.tgz", + "integrity": "sha512-AjKQX31KKN+uJs+zaf+GW8mBO/f/0NqSh2moTMyvwBY+4/lXIYTU8D8I2h6BAV3Xnz6GGsbalUyFqbYMe+Vh+Q==", + "requires": { + "cheerio": "^1.0.0-rc.3", + "commander": "^5.1.0", + "mensch": "^0.3.4", + "slick": "^1.12.2", + "web-resource-inliner": "^5.0.0" + }, + "dependencies": { + "commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==" + } + } + }, "jwa": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", @@ -3734,6 +5506,11 @@ "safe-buffer": "^5.0.1" } }, + "kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==" + }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -3743,6 +5520,11 @@ "p-locate": "^5.0.0" } }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "lodash.includes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", @@ -3788,6 +5570,30 @@ "is-unicode-supported": "^0.1.0" } }, + "logform": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.4.0.tgz", + "integrity": "sha512-CPSJw4ftjf517EhXZGGvTHHkYobo7ZCc0kvwUoOYcjfR2UVrI66RHj8MCrfAdEitdmFqbu2BYdYs8FHHZSb6iw==", + "requires": { + "@colors/colors": "1.5.0", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + }, + "dependencies": { + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=" + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -3822,6 +5628,11 @@ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, + "mensch": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/mensch/-/mensch-0.3.4.tgz", + "integrity": "sha512-IAeFvcOnV9V0Yk+bFhYR07O3yNina9ANIN5MoXBKYJ/RLYPurd2d0yw14MDhpr9/momp0WofT1bPUh3hkzdi/g==" + }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -3858,6 +5669,11 @@ "brace-expansion": "^1.1.7" } }, + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + }, "minipass": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", @@ -3875,6 +5691,391 @@ "yallist": "^4.0.0" } }, + "mjml": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml/-/mjml-4.12.0.tgz", + "integrity": "sha512-uWDu1pPQVyoX4iKIrM02J6qOBN6PC1rSMP64DKi2qGU4dpOztVgvTBh6JttIbINV4ZiALtpeGu+jeEUqp2ROXA==", + "requires": { + "@babel/runtime": "^7.14.6", + "mjml-cli": "4.12.0", + "mjml-core": "4.12.0", + "mjml-migrate": "4.12.0", + "mjml-preset-core": "4.12.0", + "mjml-validator": "4.12.0" + } + }, + "mjml-accordion": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-accordion/-/mjml-accordion-4.12.0.tgz", + "integrity": "sha512-vqBk4NhXN+w6F3c5vnLxkvgneREpkwTzZpbxtMzpNqkUW2yei0oSQ26j/wLgXYTaX+4Czp+oVr0cnNxjyCZHjA==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-body": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-body/-/mjml-body-4.12.0.tgz", + "integrity": "sha512-IQBAHhdRKsNUXat+oxvRTjVJ1qzTRkNjFe/mtD/Pbn9olUnQmV+RKxnkqRZf7QtiTxVIOGC4kU9VLPjNymsFXQ==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-button": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-button/-/mjml-button-4.12.0.tgz", + "integrity": "sha512-XJfLP+mHvCr6Ky16ooYz5+8ODkf10+ATyvENCKyrof+rietr5WxN2FxWCZA9Orq20OE74/hvaOeZZdkxwtsXig==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-carousel": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-carousel/-/mjml-carousel-4.12.0.tgz", + "integrity": "sha512-vQ5Aqvix9mbAE0GspxIDpKK4dVMRuKFO3qV6N/CkrIAOe4+2CKV4AMn2fWUvQEx6hA6CGxayeLkI7E0hNOWcZA==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-cli": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-cli/-/mjml-cli-4.12.0.tgz", + "integrity": "sha512-//Y4XsN6aFgpZtDbQZRu4qe+CQzGWV3i5K3rC1dwPcdtpDMsXBPKiwIZFrQxpRVBwxs0hU4ZBQOMtvYZkoicdQ==", + "requires": { + "@babel/runtime": "^7.14.6", + "chokidar": "^3.0.0", + "glob": "^7.1.1", + "html-minifier": "^4.0.0", + "js-beautify": "^1.6.14", + "lodash": "^4.17.21", + "mjml-core": "4.12.0", + "mjml-migrate": "4.12.0", + "mjml-parser-xml": "4.12.0", + "mjml-validator": "4.12.0", + "yargs": "^16.1.0" + } + }, + "mjml-column": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-column/-/mjml-column-4.12.0.tgz", + "integrity": "sha512-Ub/7ov2B1T2jfSpxvF61o3UCU4gGDFUqIelr7ghuazLc2KvTwdHYeR8mWt8l8RBM6zZiWjkYEFMP22ty7WXztg==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-core": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-core/-/mjml-core-4.12.0.tgz", + "integrity": "sha512-B3gUkV3kFN1IlzIV3GnpWBmE21XHH5ARyydMxacR75iC53PvJ9c50hr6DWLGdrrDCC6Fdud8jTmgD9dnWPmJhQ==", + "requires": { + "@babel/runtime": "^7.14.6", + "cheerio": "1.0.0-rc.10", + "detect-node": "2.0.4", + "html-minifier": "^4.0.0", + "js-beautify": "^1.6.14", + "juice": "^7.0.0", + "lodash": "^4.17.21", + "mjml-migrate": "4.12.0", + "mjml-parser-xml": "4.12.0", + "mjml-validator": "4.12.0" + } + }, + "mjml-divider": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-divider/-/mjml-divider-4.12.0.tgz", + "integrity": "sha512-L87iqrhVS+PnUInYbXK4lcTQcHfWMTL7ZqDL9XEMBywzX8cCfviLNMbqmLCO2HD8nMPVMRbcE32H04T6LyZ2qw==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-group": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-group/-/mjml-group-4.12.0.tgz", + "integrity": "sha512-Rl7Iydd7M2SnbH1ItIi07hYY+FrEai5c6kYMKbcFWAuNupCuvUThuhx1AphMPCZFMLbbPSKNWMarBkWhepS7cw==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-head": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-head/-/mjml-head-4.12.0.tgz", + "integrity": "sha512-LcI4ykOB6nMV5W//tF9S1unlXxexfNZUnnyZ2OOzP1V7J5poLXdKXqB8XATN2YGGTsDZ5Q/5V1KO+NnjpW7zSw==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-head-attributes": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-head-attributes/-/mjml-head-attributes-4.12.0.tgz", + "integrity": "sha512-tRwKUzIrtcw1FGy8Xpy4vrFo0u2daZgqx3X0cM5WWrGFcKe7ZdjNEAkU/3w+WsFjeMcb0fHdKvd+sxBjPJ6fpA==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-head-breakpoint": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-head-breakpoint/-/mjml-head-breakpoint-4.12.0.tgz", + "integrity": "sha512-BVVbvAIcIu49P1EJkEPPIY8Gu4GleyzpkdddqD3ihAPn3Pz07SEsFlHvI35eCszuaJeeMbSSxLrsF4m+aQQlvw==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-head-font": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-head-font/-/mjml-head-font-4.12.0.tgz", + "integrity": "sha512-ja5sWbGOIr1gF/7IIPzrgOlWYiKk57BC8JWYRANV7CxNKa635sd6aBJHbzXv1A6Ph+zH5KtE0MSQCK8n49BIsw==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-head-html-attributes": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-head-html-attributes/-/mjml-head-html-attributes-4.12.0.tgz", + "integrity": "sha512-XJesJuW9uzlNN5w/S7t5ZquSVDay7BehOKmIZKMwKn1y0SJBXiakcwt9M9hhF0HB189Bew0gpGt3m7QYvTez8g==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-head-preview": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-head-preview/-/mjml-head-preview-4.12.0.tgz", + "integrity": "sha512-pr02ZkxwU6/LWhrL3xP/hLrUXx27I1FnfgaYjgvMjh6pMURuy7W+W8BrNJKeyXZo685b2A5lNFDJV7rCJ6HrEQ==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-head-style": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-head-style/-/mjml-head-style-4.12.0.tgz", + "integrity": "sha512-64IVdJ2Xl000SrwLt4cebl+MiZcino/ywMkuLQ/c48XeR6pkvbjXYAInWsdlMG1y041n1bOZICNnQQc4xhNJrw==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-head-title": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-head-title/-/mjml-head-title-4.12.0.tgz", + "integrity": "sha512-c7thJUmNLIdVy1ftLbYUjchHwrIfAb9SHdbuVQHdtQz45a3Ni2nie4AWxF/srn90k8q/uEKtQq1taOa4f71Zug==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-hero": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-hero/-/mjml-hero-4.12.0.tgz", + "integrity": "sha512-j87DgSAyLzMMuNtVqR1okkI/orKnvZoR7i+RsA1yueNql9dZtnw3Ezy8cas8MJaAoGOmqIy9AqGRJIr82w4mxQ==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-image": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-image/-/mjml-image-4.12.0.tgz", + "integrity": "sha512-P77M+PLLNn7QvGhL8sx+6yzkQbEMxIQO3yxqUC+x8Ie8kXS8phSNGcqx8qfhdN7p7sQ3CZdOIZSXkG7RRAF94w==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-migrate": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-migrate/-/mjml-migrate-4.12.0.tgz", + "integrity": "sha512-KDdPkuOzL9CAekY0CslM0Yqiomk4TubNMszw6UFfylp5xRA3CfBo0HdGcnewHBkZ8+isjPlzDWf3n+NkU11OiA==", + "requires": { + "@babel/runtime": "^7.14.6", + "js-beautify": "^1.6.14", + "lodash": "^4.17.21", + "mjml-core": "4.12.0", + "mjml-parser-xml": "4.12.0", + "yargs": "^16.1.0" + } + }, + "mjml-navbar": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-navbar/-/mjml-navbar-4.12.0.tgz", + "integrity": "sha512-TWKV5lFgwUvRbG+FNz6Uo7mGPJRU/BK1v0BeQr1e5Ykft4052iYIuv2XNwRkeoORmLT+7AN8FbkP+TVBpflbWw==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-parser-xml": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-parser-xml/-/mjml-parser-xml-4.12.0.tgz", + "integrity": "sha512-cmCcvoiirH0kuCglGAjwBVfDrlnqS3e83uBwPN6wDN6IfxSgsPT6IV0vRfcJERsr2ThpFjvoSq4GmYi9oCUSMw==", + "requires": { + "@babel/runtime": "^7.14.6", + "detect-node": "2.0.4", + "htmlparser2": "^4.1.0", + "lodash": "^4.17.15" + }, + "dependencies": { + "domhandler": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz", + "integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==", + "requires": { + "domelementtype": "^2.0.1" + } + }, + "htmlparser2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-4.1.0.tgz", + "integrity": "sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^3.0.0", + "domutils": "^2.0.0", + "entities": "^2.0.0" + } + } + } + }, + "mjml-preset-core": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-preset-core/-/mjml-preset-core-4.12.0.tgz", + "integrity": "sha512-zoiCKcl/bK43ltr2J8dY9Qg5fcB3TbhaWcTG84oGYWdii5WEkKTXj5hpP1ss1XqdOGMNLij/HVwmli+xQCo6FQ==", + "requires": { + "@babel/runtime": "^7.14.6", + "mjml-accordion": "4.12.0", + "mjml-body": "4.12.0", + "mjml-button": "4.12.0", + "mjml-carousel": "4.12.0", + "mjml-column": "4.12.0", + "mjml-divider": "4.12.0", + "mjml-group": "4.12.0", + "mjml-head": "4.12.0", + "mjml-head-attributes": "4.12.0", + "mjml-head-breakpoint": "4.12.0", + "mjml-head-font": "4.12.0", + "mjml-head-html-attributes": "4.12.0", + "mjml-head-preview": "4.12.0", + "mjml-head-style": "4.12.0", + "mjml-head-title": "4.12.0", + "mjml-hero": "4.12.0", + "mjml-image": "4.12.0", + "mjml-navbar": "4.12.0", + "mjml-raw": "4.12.0", + "mjml-section": "4.12.0", + "mjml-social": "4.12.0", + "mjml-spacer": "4.12.0", + "mjml-table": "4.12.0", + "mjml-text": "4.12.0", + "mjml-wrapper": "4.12.0" + } + }, + "mjml-raw": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-raw/-/mjml-raw-4.12.0.tgz", + "integrity": "sha512-vQUmrEZEgu0DCca7tiPdQ/vf8GM5QyeaabbLd1rX3XCt5Mid47LCdszmVcrk1WxqNuExIw1fNyEGCCDeP2qCJg==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-section": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-section/-/mjml-section-4.12.0.tgz", + "integrity": "sha512-5BdHrAghS/XJ40t3qtLHpY3rIVuBnJXv8dGm8U+oMVAzw3L4ySk5WI+FulRkchdPFCKpeXQZjXZaX0C7pmNaIw==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-social": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-social/-/mjml-social-4.12.0.tgz", + "integrity": "sha512-eTsqJoKP65Imawh+WEX2dv4N34ItUmvIbsCeSQPhC/NG6klxDjzg5oDA1F2tZk+CPIuXVmJiauQ5/vPHLzUiVw==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-spacer": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-spacer/-/mjml-spacer-4.12.0.tgz", + "integrity": "sha512-YB+VCixcuWXDzICrGLFw7PJDkL166e4OG8IUUB2yhvd5VHtFFBc0iRksaEAumOL1r6MnXVCRq4Wcmxlzj7zOfQ==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-table": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-table/-/mjml-table-4.12.0.tgz", + "integrity": "sha512-IuLvyiJOsM6RgobuIfZuM36fJcoH8pK/A4awCLTEme0HCxEkkjzDkl4RBMK/KX53Cpor0U6oR6RlQfZcducpLg==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-text": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-text/-/mjml-text-4.12.0.tgz", + "integrity": "sha512-AFcXiQBC48ZfKKgAdU0NRS2nqftc8zLGxBtPwHNgFkuh5Lf2rWgPK6JRubNi7qhb8Sd7M8stU+LIRA5sxM1nRQ==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0" + } + }, + "mjml-validator": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-validator/-/mjml-validator-4.12.0.tgz", + "integrity": "sha512-EmOScfcJJ4LdIyHnE+K4FdkryQ+c6QRV7qp+zlunAHE5AUPaBS0OrHPHuNo1sOu7g1tc+bVl7eHR4FIb0Wkzwg==", + "requires": { + "@babel/runtime": "^7.14.6" + } + }, + "mjml-wrapper": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/mjml-wrapper/-/mjml-wrapper-4.12.0.tgz", + "integrity": "sha512-u0pq+A9QBLwpeF/hdv2uWZIv3Qp4wwf+CMaHZsUpb3YfOJD/6YKwLvkeA7ngE+YxwwzgtgjmIEs4eDae1evlgQ==", + "requires": { + "@babel/runtime": "^7.14.6", + "lodash": "^4.17.21", + "mjml-core": "4.12.0", + "mjml-section": "4.12.0" + } + }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", @@ -3940,6 +6141,12 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true + }, + "nanoid": { + "version": "3.1.25", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", + "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", + "dev": true } } }, @@ -3949,16 +6156,28 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, "nanoid": { - "version": "3.1.25", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.25.tgz", - "integrity": "sha512-rdwtIXaXCLFAQbnfqDRnI6jaRHp9fTcYBjtFKE8eezcZ7LuLjhUaQGNeMXf1HmRoCH32CLz6XwX0TtxEOS/A3Q==", - "dev": true + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" }, "negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" + }, + "no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "requires": { + "lower-case": "^1.1.1" + } + }, "node-addon-api": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", @@ -3988,8 +6207,7 @@ "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "npmlog": { "version": "5.0.1", @@ -4002,6 +6220,14 @@ "set-blocking": "^2.0.0" } }, + "nth-check": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", + "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", + "requires": { + "boolbase": "^1.0.0" + } + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -4023,6 +6249,14 @@ "wrappy": "1" } }, + "one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "requires": { + "fn.name": "1.x.x" + } + }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -4041,6 +6275,27 @@ "p-limit": "^3.0.2" } }, + "param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", + "requires": { + "no-case": "^2.2.0" + } + }, + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "requires": { + "parse5": "^6.0.1" + } + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -4068,11 +6323,15 @@ "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true }, + "peek-readable": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-4.1.0.tgz", + "integrity": "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==" + }, "picomatch": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", - "dev": true + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==" }, "prisma": { "version": "3.3.0", @@ -4089,6 +6348,11 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, + "proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=" + }, "proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -4098,6 +6362,11 @@ "ipaddr.js": "1.9.1" } }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, "qs": { "version": "6.7.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", @@ -4143,11 +6412,30 @@ "util-deprecate": "~1.0.1" } }, + "readable-web-to-node-stream": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", + "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", + "requires": { + "readable-stream": "^3.6.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, "requires": { "picomatch": "^2.2.1" } @@ -4181,11 +6469,20 @@ "redis-errors": "^1.0.0" } }, + "regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=" + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, "rimraf": { "version": "3.0.2", @@ -4200,6 +6497,11 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "safe-stable-stringify": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.3.1.tgz", + "integrity": "sha512-kYBSfT+troD9cDA85VDnHZ1rpHC50O0g1e6WlGHVCz/g+JS+9WKLj+XwFYyR8UbrZN8ll9HUpDAAddY58MGisg==" + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -4270,16 +6572,49 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" }, + "sigmund": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", + "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=" + }, "signal-exit": { "version": "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": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "requires": { + "is-arrayish": "^0.3.1" + } + }, + "slick": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/slick/-/slick-1.12.2.tgz", + "integrity": "sha1-vQSN23TefRymkV+qSldXCzVQwtc=" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + }, + "stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" + }, "statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, + "streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -4312,6 +6647,20 @@ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, + "strnum": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz", + "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==" + }, + "strtok3": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-6.3.0.tgz", + "integrity": "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==", + "requires": { + "@tokenizer/token": "^0.3.0", + "peek-readable": "^4.1.0" + } + }, "superagent": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", @@ -4369,11 +6718,15 @@ "yallist": "^4.0.0" } }, + "text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" + }, "to-regex-range": { "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==", - "dev": true, "requires": { "is-number": "^7.0.0" } @@ -4383,11 +6736,25 @@ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" }, + "token-types": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-4.2.0.tgz", + "integrity": "sha512-P0rrp4wUpefLncNamWIef62J0v0kQR/GfDVji9WKY7GDCWy5YbVSrKUTam07iWPZQGy0zWNOfstYTykMmPNR7w==", + "requires": { + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + } + }, "tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" }, + "triple-beam": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", + "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" + }, "ts-node": { "version": "10.2.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", @@ -4408,6 +6775,11 @@ "yn": "3.1.1" } }, + "tslib": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", + "integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==" + }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -4429,11 +6801,21 @@ "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==", "dev": true }, + "uglify-js": { + "version": "3.15.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.5.tgz", + "integrity": "sha512-hNM5q5GbBRB5xB+PMqVRcgYe4c8jbyZ1pzZhS6jbq54/4F2gFK869ZheiE5A8/t+W5jtTNpWef/5Q9zk639FNQ==" + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" }, + "upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=" + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -4444,11 +6826,55 @@ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, + "valid-data-url": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/valid-data-url/-/valid-data-url-3.0.1.tgz", + "integrity": "sha512-jOWVmzVceKlVVdwjNSenT4PbGghU0SBIizAev8ofZVgivk/TVHXSbNL8LP6M3spZvkR9/QolkyJavGSX5Cs0UA==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, + "web-resource-inliner": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/web-resource-inliner/-/web-resource-inliner-5.0.0.tgz", + "integrity": "sha512-AIihwH+ZmdHfkJm7BjSXiEClVt4zUFqX4YlFAzjL13wLtDuUneSaFvDBTbdYRecs35SiU7iNKbMnN+++wVfb6A==", + "requires": { + "ansi-colors": "^4.1.1", + "escape-goat": "^3.0.0", + "htmlparser2": "^4.0.0", + "mime": "^2.4.6", + "node-fetch": "^2.6.0", + "valid-data-url": "^3.0.0" + }, + "dependencies": { + "domhandler": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-3.3.0.tgz", + "integrity": "sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA==", + "requires": { + "domelementtype": "^2.0.1" + } + }, + "htmlparser2": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-4.1.0.tgz", + "integrity": "sha512-4zDq1a1zhE4gQso/c5LP1OtrhYTncXNSpvJYtWJBtXAETPlMfi3IFNjGuQbYLuVY4ZR0QMqRVvo4Pdy9KLyP8Q==", + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^3.0.0", + "domutils": "^2.0.0", + "entities": "^2.0.0" + } + }, + "mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==" + } + } + }, "webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -4480,6 +6906,62 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, + "winston": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.7.2.tgz", + "integrity": "sha512-QziIqtojHBoyzUOdQvQiar1DH0Xp9nF1A1y7NVy2DGEsz82SBDtOalS0ulTRGVT14xPX3WRWkCsdcJKqNflKng==", + "requires": { + "@dabh/diagnostics": "^2.0.2", + "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" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "winston-transport": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz", + "integrity": "sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q==", + "requires": { + "logform": "^2.3.2", + "readable-stream": "^3.6.0", + "triple-beam": "^1.3.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + }, "workerpool": { "version": "6.1.5", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.5.tgz", @@ -4490,7 +6972,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -4505,8 +6986,7 @@ "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" }, "yallist": { "version": "4.0.0", @@ -4517,7 +6997,6 @@ "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, "requires": { "cliui": "^7.0.2", "escalade": "^3.1.1", @@ -4531,8 +7010,7 @@ "yargs-parser": { "version": "20.2.4", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==" }, "yargs-unparser": { "version": "2.0.0", @@ -4557,6 +7035,11 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true + }, + "zod": { + "version": "3.16.0", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.16.0.tgz", + "integrity": "sha512-szrIkryADbTM+xBt2a1KoS2CJQXec4f9xG78bj5MJeEH/XqmmHpnO+fG3IE115AKBJak+2HrbxLZkc9mhdbDKA==" } } } diff --git a/src/Controllers/discipline.controller.ts b/src/Controllers/discipline.controller.ts index 73ce9d1..a19c918 100644 --- a/src/Controllers/discipline.controller.ts +++ b/src/Controllers/discipline.controller.ts @@ -220,12 +220,12 @@ export const addVisual = async (req: Request, res: }) }; -export const deleteVisual = async (req: Request, res: Response) => { +export const deleteVisual = async (req: Request, res: Response) => { if (req.auth?.permission_level != "ELEVATED"){ res.status(403).json(createInsufficientPermissionsError()); } - const { disciplinePid } = req.params; + const { disciplinePid, pid } = req.params; try { await prisma.discipline.update({ @@ -233,7 +233,7 @@ export const deleteVisual = async (req: Request, r pid: disciplinePid, }, data: { - visual: { disconnect: { pid: req.body.mediaPid } } + visual: { disconnect: { pid } } } }); return res.status(204).end(); diff --git a/src/Controllers/event.controller.ts b/src/Controllers/event.controller.ts index 7befc07..179b3e7 100644 --- a/src/Controllers/event.controller.ts +++ b/src/Controllers/event.controller.ts @@ -5,6 +5,8 @@ import prisma from "../lib/prisma"; import NotFoundError from "../Middleware/error/NotFoundError"; import { createInsufficientPermissionsError, DataType, generateError, generateInvalidBodyError } from "./common"; +require("express-async-errors"); + export const getAllEvents = async (req: Request, res: Response) => { const events = await prisma.event.findMany({ select: { @@ -53,6 +55,10 @@ export const getEvent = async (req: Request, res: Response) => { }, }); + if (!event) { + throw new NotFoundError("event", eventId); + } + res.status(200).json({ type: "success", payload: { @@ -61,7 +67,7 @@ export const getEvent = async (req: Request, res: Response) => { }); } catch (e) { if (e instanceof Prisma.PrismaClientKnownRequestError) { - res.status(500).json({ + return res.status(500).json({ type: "error", payload: { message: `Internal Server error occured. Try again later`, @@ -70,7 +76,7 @@ export const getEvent = async (req: Request, res: Response) => { return; } if (e instanceof Prisma.PrismaClientUnknownRequestError) { - res.status(500).json({ + return res.status(500).json({ type: "error", payload: { message: "Unknown error occurred with your request. Check if your parameters are correct", @@ -81,6 +87,8 @@ export const getEvent = async (req: Request, res: Response) => { }); return; } + + throw e; } }; @@ -92,14 +100,15 @@ export const addEvent = async (req: Request, res: Response) => { if ( typeof req.body.name !== "string" || typeof req.body.date !== "string" || - typeof req.body.description !== "string" || - req.body.fullDescription && req.body.fullDescription !== "string" + typeof req.body.briefDescription !== "string" || + req.body.fullDescription && typeof req.body.fullDescription !== "string" ) { - generateInvalidBodyError({ + return res.status(400).json(generateInvalidBodyError({ name: DataType.STRING, date: DataType.DATETIME, - description: DataType.STRING, - }); + briefDescription: DataType.STRING, + ["fullDescription?"]: DataType.STRING, + })); } //TODO: Check if date is valid @@ -108,7 +117,8 @@ export const addEvent = async (req: Request, res: Response) => { data: { name: req.body.name, date: req.body.date, - briefDescription: req.body.description, + briefDescription: req.body.briefDescription, + fullDescription: req.body.fullDescription, }, select: { name: true, @@ -133,7 +143,7 @@ interface DeleteEventQueryParams { } // requires: auth(ELEVATED) -export const deleteEvent = (req: Request, res: Response) => { +export const deleteEvent = async (req: Request, res: Response) => { if (req.auth?.permission_level !== "ELEVATED") { res.status(403).json(createInsufficientPermissionsError()); } @@ -141,7 +151,7 @@ export const deleteEvent = (req: Request, res: Response) const { pid } = req.params; try { - prisma.event.delete({ where: { pid } }); + await prisma.event.delete({ where: { pid } }); return res.status(204).end(); } catch (e) { @@ -191,12 +201,12 @@ export const addVisual = async (req: Request, res: }) }; -export const deleteVisual = async (req: Request, res: Response) => { +export const deleteVisual = async (req: Request, res: Response) => { if (req.auth?.permission_level != "ELEVATED"){ res.status(403).json(createInsufficientPermissionsError()); } - const { eventPid } = req.params; + const { eventPid, pid } = req.params; try { await prisma.event.update({ @@ -204,7 +214,7 @@ export const deleteVisual = async (req: Request, r pid: eventPid, }, data: { - visual: { disconnect: { pid: req.body.mediaPid } } + visual: { disconnect: { pid } }, } }); return res.status(204).end(); diff --git a/src/Controllers/media.controller.ts b/src/Controllers/media.controller.ts index 94dedef..1246e2d 100644 --- a/src/Controllers/media.controller.ts +++ b/src/Controllers/media.controller.ts @@ -132,9 +132,9 @@ export const getAllMedia = async (req: Request, res: Response) => { const medias = await prisma.media.findMany({ select: { description: true, - events: true, - disciplines: true, - roles: true, + events: {select: {pid: true}}, + disciplines: {select: {pid: true}}, + roles: {select: {pid: true}}, pid: true, id: false, }, diff --git a/src/Controllers/role_schema.controller.ts b/src/Controllers/role_schema.controller.ts index 8c94265..f694667 100644 --- a/src/Controllers/role_schema.controller.ts +++ b/src/Controllers/role_schema.controller.ts @@ -156,12 +156,12 @@ export const addVisual = async (req: Request, res: }) }; -export const deleteVisual = async (req: Request, res: Response) => { +export const deleteVisual = async (req: Request, res: Response) => { if (req.auth?.permission_level != "ELEVATED"){ res.status(403).json(createInsufficientPermissionsError()); } - const { schemaPid } = req.params; + const { schemaPid, pid } = req.params; try { await prisma.roleSchema.update({ @@ -169,7 +169,7 @@ export const deleteVisual = async (req: Request, r pid: schemaPid, }, data: { - visual: { disconnect: { pid: req.body.mediaPid } } + visual: { disconnect: { pid } } } }); return res.status(204).end(); diff --git a/src/Routes/event.routes.ts b/src/Routes/event.routes.ts index efc9137..42bc8dc 100644 --- a/src/Routes/event.routes.ts +++ b/src/Routes/event.routes.ts @@ -1,6 +1,6 @@ import Express from "express"; import { string } from "zod"; -import { addEvent, addVisual, deleteVisual, getAllEvents, getEvent } from "../Controllers/event.controller"; +import { addEvent, addVisual, deleteEvent, deleteVisual, getAllEvents, getEvent } from "../Controllers/event.controller"; import { requireAuthentication } from "../Middleware/auth/auth"; const router = Express.Router(); @@ -10,6 +10,8 @@ router.get("/:eventId", getEvent); router.post("/", requireAuthentication, addEvent); +router.delete<"/:pid/", { pid: string }>("/:pid/", requireAuthentication, deleteEvent); + router.post<"/:eventPid/media", { eventPid: string }>("/:eventPid/media", requireAuthentication, addVisual); router.delete<"/:eventPid/media/:pid", { eventPid: string; pid: string }>( diff --git a/src/Routes/media.routes.ts b/src/Routes/media.routes.ts index cd53682..f340de1 100644 --- a/src/Routes/media.routes.ts +++ b/src/Routes/media.routes.ts @@ -2,6 +2,9 @@ import express from "express"; import fileUpload from "express-fileupload"; import { requireAuthentication } from "../Middleware/auth/auth"; import { deleteMedia, getAllMedia, getMediaMeta, uploadImage } from "../Controllers/media.controller"; +import eventRouter from "./event.routes"; +import disciplineRouter from "./discipline.routes"; +import roleSchemaRouter from "./role_schema.routes"; const router = express.Router(); @@ -11,6 +14,7 @@ router.use("/", express.static("/app/media", { redirect: false })); router.post("/", requireAuthentication, fileUpload(), uploadImage); router.get("/", requireAuthentication, getAllMedia); // Reading all files should be a senstive operation + router.get("/:pid/meta", getMediaMeta); router.delete("/:pid", requireAuthentication, deleteMedia); From 0ee140ad0065b159c949691291ec5a824c067e08 Mon Sep 17 00:00:00 2001 From: Laurin <60652077+Flexla54@users.noreply.github.com> Date: Tue, 17 May 2022 16:18:22 +0200 Subject: [PATCH 14/15] more bug fixes and add update to event --- src/Controllers/discipline.controller.ts | 4 +- src/Controllers/event.controller.ts | 110 +++++++++++++++++++--- src/Controllers/role_schema.controller.ts | 2 +- src/Routes/event.routes.ts | 4 +- 4 files changed, 102 insertions(+), 18 deletions(-) diff --git a/src/Controllers/discipline.controller.ts b/src/Controllers/discipline.controller.ts index a19c918..57aeb61 100644 --- a/src/Controllers/discipline.controller.ts +++ b/src/Controllers/discipline.controller.ts @@ -18,7 +18,7 @@ require("express-async-errors"); const basicDiscipline = { pid: true, name: true, - visual: { select: { pid: true, location: true } }, + visual: { select: { pid: true } }, maxTeamSize: true, minTeamSize: true, event: { select: { pid: true, name: true } }, @@ -206,7 +206,7 @@ export const addVisual = async (req: Request, res: const discipline = await prisma.discipline.update({ where: { pid: disciplinePid }, data: { - visual: { connect: { pid: req.body.mediaPid } } + visual: {connect: {pid: req.body.mediaPid}} } }); diff --git a/src/Controllers/event.controller.ts b/src/Controllers/event.controller.ts index 179b3e7..5ebbdc9 100644 --- a/src/Controllers/event.controller.ts +++ b/src/Controllers/event.controller.ts @@ -1,6 +1,7 @@ import { Prisma } from "@prisma/client"; import { PrismaClientKnownRequestError } from "@prisma/client/runtime"; import { Request, Response } from "express"; +import { z } from "zod"; import prisma from "../lib/prisma"; import NotFoundError from "../Middleware/error/NotFoundError"; import { createInsufficientPermissionsError, DataType, generateError, generateInvalidBodyError } from "./common"; @@ -13,7 +14,7 @@ export const getAllEvents = async (req: Request, res: Response) => { name: true, briefDescription: true, fullDescription: true, - visual: {select: {pid: true, description: true}}, + visual: { select: { pid: true, description: true } }, date: true, pid: true, id: false, @@ -51,7 +52,7 @@ export const getEvent = async (req: Request, res: Response) => { date: true, pid: true, id: false, - visual: {select: {pid: true, description: true}} + visual: { select: { pid: true, description: true } } }, }); @@ -73,7 +74,6 @@ export const getEvent = async (req: Request, res: Response) => { message: `Internal Server error occured. Try again later`, }, }); - return; } if (e instanceof Prisma.PrismaClientUnknownRequestError) { return res.status(500).json({ @@ -85,7 +85,6 @@ export const getEvent = async (req: Request, res: Response) => { }, }, }); - return; } throw e; @@ -138,6 +137,89 @@ export const addEvent = async (req: Request, res: Response) => { }); }; +const EventBody = z.object({ + name: z.string(), + date: z.string(), + briefDescription: z.string(), + fullDescription: z.string() +}) + +const UpdateBody = EventBody.partial(); + +export const updateEvent = async (req: Request<{ pid: string }>, res: Response) => { + if (req.auth?.permission_level !== "ELEVATED") { + res.status(403).json(createInsufficientPermissionsError()); + } + + const { pid } = req.params; + + const result = UpdateBody.safeParse(req.body); + + if (result.success === false) { + return res.status(400).json(generateInvalidBodyError({ + name: DataType.STRING, + date: DataType.DATETIME, + briefDescription: DataType.STRING, + ["fullDescription?"]: DataType.STRING, + })); + } + + const body = result.data; + + try { + const event = await prisma.event.update({ + where: { pid }, + data: { + name: body.name, + date: body.date, + briefDescription: body.briefDescription, + fullDescription: body.fullDescription + }, + select: { + pid: true, + name: true, + date: true, + briefDescription: true, + fullDescription: true + } + }) + + if (!event) { + throw new NotFoundError("event", pid); + } + + res.status(200).json({ + type: "success", + payload: { + event + }, + }); + } catch (e) { + if (e instanceof Prisma.PrismaClientKnownRequestError) { + return res.status(500).json({ + type: "error", + payload: { + message: `Internal Server error occured. Try again later`, + }, + }); + } + if (e instanceof Prisma.PrismaClientUnknownRequestError) { + return res.status(500).json({ + type: "error", + payload: { + message: "Unknown error occurred with your request. Check if your parameters are correct", + schema: { + eventId: DataType.UUID, + }, + }, + }); + } + + throw e; + } + +} + interface DeleteEventQueryParams { pid: string; } @@ -174,16 +256,16 @@ interface visualBody { } export const addVisual = async (req: Request, res: Response) => { - if (req.auth?.permission_level != "ELEVATED"){ + if (req.auth?.permission_level != "ELEVATED") { res.status(403).json(createInsufficientPermissionsError()); } const { eventPid } = req.params; if (typeof req.body.mediaPid !== "string") { - res.status(400).json(generateInvalidBodyError({mediaPid: DataType.STRING})); + res.status(400).json(generateInvalidBodyError({ mediaPid: DataType.STRING })); } - + const event = await prisma.event.update({ where: { pid: eventPid }, data: { @@ -197,25 +279,25 @@ export const addVisual = async (req: Request, res: return res.status(200).json({ type: "success", - payload: { } + payload: {} }) }; export const deleteVisual = async (req: Request, res: Response) => { - if (req.auth?.permission_level != "ELEVATED"){ + if (req.auth?.permission_level != "ELEVATED") { res.status(403).json(createInsufficientPermissionsError()); } const { eventPid, pid } = req.params; try { - await prisma.event.update({ - where: { + await prisma.event.update({ + where: { pid: eventPid, - }, - data: { + }, + data: { visual: { disconnect: { pid } }, - } + } }); return res.status(204).end(); } catch (e) { diff --git a/src/Controllers/role_schema.controller.ts b/src/Controllers/role_schema.controller.ts index f694667..9f09f4b 100644 --- a/src/Controllers/role_schema.controller.ts +++ b/src/Controllers/role_schema.controller.ts @@ -17,7 +17,7 @@ const roleSchema = { name: true, schema: true, discipline: { select: { pid: true, name: true } }, - visual: { select: { pid: true, location: true } }, + visual: { select: { pid: true } }, } as const; export const _getAllRoleSchemas = async (res: Response, disciplinePid: string | undefined) => { diff --git a/src/Routes/event.routes.ts b/src/Routes/event.routes.ts index 42bc8dc..bdf58ab 100644 --- a/src/Routes/event.routes.ts +++ b/src/Routes/event.routes.ts @@ -1,6 +1,6 @@ import Express from "express"; import { string } from "zod"; -import { addEvent, addVisual, deleteEvent, deleteVisual, getAllEvents, getEvent } from "../Controllers/event.controller"; +import { addEvent, addVisual, deleteEvent, deleteVisual, getAllEvents, getEvent, updateEvent } from "../Controllers/event.controller"; import { requireAuthentication } from "../Middleware/auth/auth"; const router = Express.Router(); @@ -10,6 +10,8 @@ router.get("/:eventId", getEvent); router.post("/", requireAuthentication, addEvent); +router.patch<"/:pid/", { pid: string }>("/:pid/", requireAuthentication, updateEvent); + router.delete<"/:pid/", { pid: string }>("/:pid/", requireAuthentication, deleteEvent); router.post<"/:eventPid/media", { eventPid: string }>("/:eventPid/media", requireAuthentication, addVisual); From 4926f2659df2e929ebc4876648550e7e5a132164 Mon Sep 17 00:00:00 2001 From: Flexla54 Date: Tue, 17 May 2022 14:37:08 +0000 Subject: [PATCH 15/15] [create-pull-request] push formatted files --- src/Controllers/discipline.controller.ts | 26 +++++----- src/Controllers/event.controller.ts | 59 ++++++++++++----------- src/Controllers/media.controller.ts | 6 +-- src/Controllers/role_schema.controller.ts | 28 +++++------ src/Routes/discipline.routes.ts | 12 ++++- src/Routes/event.routes.ts | 10 +++- src/Routes/role_schema.routes.ts | 9 ++-- 7 files changed, 86 insertions(+), 64 deletions(-) diff --git a/src/Controllers/discipline.controller.ts b/src/Controllers/discipline.controller.ts index 57aeb61..de8abbd 100644 --- a/src/Controllers/discipline.controller.ts +++ b/src/Controllers/discipline.controller.ts @@ -197,17 +197,17 @@ interface visualBody { } export const addVisual = async (req: Request, res: Response) => { - if (req.auth?.permission_level != "ELEVATED"){ + if (req.auth?.permission_level != "ELEVATED") { res.status(403).json(createInsufficientPermissionsError()); } const { disciplinePid } = req.params; - + const discipline = await prisma.discipline.update({ where: { pid: disciplinePid }, data: { - visual: {connect: {pid: req.body.mediaPid}} - } + visual: { connect: { pid: req.body.mediaPid } }, + }, }); if (!discipline) { @@ -216,25 +216,25 @@ export const addVisual = async (req: Request, res: return res.status(200).json({ type: "success", - payload: { } - }) + payload: {}, + }); }; export const deleteVisual = async (req: Request, res: Response) => { - if (req.auth?.permission_level != "ELEVATED"){ + if (req.auth?.permission_level != "ELEVATED") { res.status(403).json(createInsufficientPermissionsError()); } const { disciplinePid, pid } = req.params; try { - await prisma.discipline.update({ - where: { + await prisma.discipline.update({ + where: { pid: disciplinePid, - }, - data: { - visual: { disconnect: { pid } } - } + }, + data: { + visual: { disconnect: { pid } }, + }, }); return res.status(204).end(); } catch (e) { diff --git a/src/Controllers/event.controller.ts b/src/Controllers/event.controller.ts index 5ebbdc9..3193c37 100644 --- a/src/Controllers/event.controller.ts +++ b/src/Controllers/event.controller.ts @@ -52,7 +52,7 @@ export const getEvent = async (req: Request, res: Response) => { date: true, pid: true, id: false, - visual: { select: { pid: true, description: true } } + visual: { select: { pid: true, description: true } }, }, }); @@ -100,14 +100,16 @@ export const addEvent = async (req: Request, res: Response) => { typeof req.body.name !== "string" || typeof req.body.date !== "string" || typeof req.body.briefDescription !== "string" || - req.body.fullDescription && typeof req.body.fullDescription !== "string" + (req.body.fullDescription && typeof req.body.fullDescription !== "string") ) { - return res.status(400).json(generateInvalidBodyError({ - name: DataType.STRING, - date: DataType.DATETIME, - briefDescription: DataType.STRING, - ["fullDescription?"]: DataType.STRING, - })); + return res.status(400).json( + generateInvalidBodyError({ + name: DataType.STRING, + date: DataType.DATETIME, + briefDescription: DataType.STRING, + ["fullDescription?"]: DataType.STRING, + }) + ); } //TODO: Check if date is valid @@ -141,8 +143,8 @@ const EventBody = z.object({ name: z.string(), date: z.string(), briefDescription: z.string(), - fullDescription: z.string() -}) + fullDescription: z.string(), +}); const UpdateBody = EventBody.partial(); @@ -156,12 +158,14 @@ export const updateEvent = async (req: Request<{ pid: string }>, res: Response) const result = UpdateBody.safeParse(req.body); if (result.success === false) { - return res.status(400).json(generateInvalidBodyError({ - name: DataType.STRING, - date: DataType.DATETIME, - briefDescription: DataType.STRING, - ["fullDescription?"]: DataType.STRING, - })); + return res.status(400).json( + generateInvalidBodyError({ + name: DataType.STRING, + date: DataType.DATETIME, + briefDescription: DataType.STRING, + ["fullDescription?"]: DataType.STRING, + }) + ); } const body = result.data; @@ -173,16 +177,16 @@ export const updateEvent = async (req: Request<{ pid: string }>, res: Response) name: body.name, date: body.date, briefDescription: body.briefDescription, - fullDescription: body.fullDescription + fullDescription: body.fullDescription, }, select: { pid: true, name: true, date: true, briefDescription: true, - fullDescription: true - } - }) + fullDescription: true, + }, + }); if (!event) { throw new NotFoundError("event", pid); @@ -191,7 +195,7 @@ export const updateEvent = async (req: Request<{ pid: string }>, res: Response) res.status(200).json({ type: "success", payload: { - event + event, }, }); } catch (e) { @@ -217,8 +221,7 @@ export const updateEvent = async (req: Request<{ pid: string }>, res: Response) throw e; } - -} +}; interface DeleteEventQueryParams { pid: string; @@ -269,8 +272,8 @@ export const addVisual = async (req: Request, res: const event = await prisma.event.update({ where: { pid: eventPid }, data: { - visual: { connect: { pid: req.body.mediaPid } } - } + visual: { connect: { pid: req.body.mediaPid } }, + }, }); if (!event) { @@ -279,8 +282,8 @@ export const addVisual = async (req: Request, res: return res.status(200).json({ type: "success", - payload: {} - }) + payload: {}, + }); }; export const deleteVisual = async (req: Request, res: Response) => { @@ -297,7 +300,7 @@ export const deleteVisual = async (req: Request, }, data: { visual: { disconnect: { pid } }, - } + }, }); return res.status(204).end(); } catch (e) { diff --git a/src/Controllers/media.controller.ts b/src/Controllers/media.controller.ts index 1246e2d..eb78bc3 100644 --- a/src/Controllers/media.controller.ts +++ b/src/Controllers/media.controller.ts @@ -132,9 +132,9 @@ export const getAllMedia = async (req: Request, res: Response) => { const medias = await prisma.media.findMany({ select: { description: true, - events: {select: {pid: true}}, - disciplines: {select: {pid: true}}, - roles: {select: {pid: true}}, + events: { select: { pid: true } }, + disciplines: { select: { pid: true } }, + roles: { select: { pid: true } }, pid: true, id: false, }, diff --git a/src/Controllers/role_schema.controller.ts b/src/Controllers/role_schema.controller.ts index 9f09f4b..36265de 100644 --- a/src/Controllers/role_schema.controller.ts +++ b/src/Controllers/role_schema.controller.ts @@ -133,17 +133,17 @@ interface visualBody { } export const addVisual = async (req: Request, res: Response) => { - if (req.auth?.permission_level != "ELEVATED"){ + if (req.auth?.permission_level != "ELEVATED") { res.status(403).json(createInsufficientPermissionsError()); } const { schemaPid } = req.params; - + const schema = await prisma.roleSchema.update({ where: { pid: schemaPid }, data: { - visual: { connect: { pid: req.body.mediaPid } } - } + visual: { connect: { pid: req.body.mediaPid } }, + }, }); if (!schema) { @@ -152,25 +152,25 @@ export const addVisual = async (req: Request, res: return res.status(200).json({ type: "success", - payload: { } - }) + payload: {}, + }); }; -export const deleteVisual = async (req: Request, res: Response) => { - if (req.auth?.permission_level != "ELEVATED"){ +export const deleteVisual = async (req: Request, res: Response) => { + if (req.auth?.permission_level != "ELEVATED") { res.status(403).json(createInsufficientPermissionsError()); } const { schemaPid, pid } = req.params; try { - await prisma.roleSchema.update({ - where: { + await prisma.roleSchema.update({ + where: { pid: schemaPid, - }, - data: { - visual: { disconnect: { pid } } - } + }, + data: { + visual: { disconnect: { pid } }, + }, }); return res.status(204).end(); } catch (e) { diff --git a/src/Routes/discipline.routes.ts b/src/Routes/discipline.routes.ts index acc2d76..2d97a8e 100644 --- a/src/Routes/discipline.routes.ts +++ b/src/Routes/discipline.routes.ts @@ -18,9 +18,17 @@ router.get("/:pid", getDiscipline); router.delete<"/:pid", { pid: string }>("/:pid", requireAuthentication, deleteDiscipline); -router.post<"/:disciplinePid/images", {disciplinePid: string}>("/:disciplinePid/images", requireAuthentication, addVisual); +router.post<"/:disciplinePid/images", { disciplinePid: string }>( + "/:disciplinePid/images", + requireAuthentication, + addVisual +); -router.delete<"/:disciplinePid/images/:pid", {disciplinePid: string, pid: string}>("/:disciplinePid/images/:pid", requireAuthentication, deleteVisual); +router.delete<"/:disciplinePid/images/:pid", { disciplinePid: string; pid: string }>( + "/:disciplinePid/images/:pid", + requireAuthentication, + deleteVisual +); eventRouter.post("/:eventPid/disciplines", requireAuthentication, createDiscipline); diff --git a/src/Routes/event.routes.ts b/src/Routes/event.routes.ts index bdf58ab..5e68bd8 100644 --- a/src/Routes/event.routes.ts +++ b/src/Routes/event.routes.ts @@ -1,6 +1,14 @@ import Express from "express"; import { string } from "zod"; -import { addEvent, addVisual, deleteEvent, deleteVisual, getAllEvents, getEvent, updateEvent } from "../Controllers/event.controller"; +import { + addEvent, + addVisual, + deleteEvent, + deleteVisual, + getAllEvents, + getEvent, + updateEvent, +} from "../Controllers/event.controller"; import { requireAuthentication } from "../Middleware/auth/auth"; const router = Express.Router(); diff --git a/src/Routes/role_schema.routes.ts b/src/Routes/role_schema.routes.ts index 0ec3f67..f6ada5f 100644 --- a/src/Routes/role_schema.routes.ts +++ b/src/Routes/role_schema.routes.ts @@ -20,9 +20,12 @@ disciplineRouter.get("/:disciplinePid/role-schemas", getAllRoleSchemasWithParam) disciplineRouter.post("/:disciplinePid/role-schemas", requireAuthentication, createRoleSchema); -router.post<"/:schemaPid/images", {schemaPid: string}>("/:schemaPid/images", requireAuthentication, addVisual); - -router.delete<"/:schemaPid/images/:pid", {schemaPid: string, pid: string}>("/:schemaPid/images/:pid", requireAuthentication, deleteVisual); +router.post<"/:schemaPid/images", { schemaPid: string }>("/:schemaPid/images", requireAuthentication, addVisual); +router.delete<"/:schemaPid/images/:pid", { schemaPid: string; pid: string }>( + "/:schemaPid/images/:pid", + requireAuthentication, + deleteVisual +); export default router;