From 31e76d8245510ab0690f5ed8e6c6f651f818b18a Mon Sep 17 00:00:00 2001 From: magiicloud Date: Wed, 20 Mar 2024 22:00:48 +0800 Subject: [PATCH 01/44] installed sequelize and did initial setup up to step before creating migration, model, seeder. also added auth0 initial setup before controllers and routers --- .gitignore | 3 +- .sequelizerc | 8 + config/database.js | 11 + db/models/index.js | 43 + index.js | 18 +- package-lock.json | 2233 +++++++++++++++++++++++++++++++++++++++++++- package.json | 9 +- 7 files changed, 2294 insertions(+), 31 deletions(-) create mode 100644 .sequelizerc create mode 100644 config/database.js create mode 100644 db/models/index.js diff --git a/.gitignore b/.gitignore index 40b878db..3ec544c7 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -node_modules/ \ No newline at end of file +node_modules/ +.env \ No newline at end of file diff --git a/.sequelizerc b/.sequelizerc new file mode 100644 index 00000000..409a4bed --- /dev/null +++ b/.sequelizerc @@ -0,0 +1,8 @@ +const path = require("path"); + +module.exports = { + config: path.resolve("config", "database.js"), + "models-path": path.resolve("db", "models"), + "seeders-path": path.resolve("db", "seeders"), + "migrations-path": path.resolve("db", "migrations"), +}; diff --git a/config/database.js b/config/database.js new file mode 100644 index 00000000..bed84df2 --- /dev/null +++ b/config/database.js @@ -0,0 +1,11 @@ +require("dotenv").config(); + +module.exports = { + development: { + username: process.env.DB_USERNAME, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + host: process.env.DB_HOST, + dialect: process.env.DB_DIALECT, + }, +}; diff --git a/db/models/index.js b/db/models/index.js new file mode 100644 index 00000000..5edbd256 --- /dev/null +++ b/db/models/index.js @@ -0,0 +1,43 @@ +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const Sequelize = require('sequelize'); +const process = require('process'); +const basename = path.basename(__filename); +const env = process.env.NODE_ENV || 'development'; +const config = require(__dirname + '/../../config/database.js')[env]; +const db = {}; + +let sequelize; +if (config.use_env_variable) { + sequelize = new Sequelize(process.env[config.use_env_variable], config); +} else { + sequelize = new Sequelize(config.database, config.username, config.password, config); +} + +fs + .readdirSync(__dirname) + .filter(file => { + return ( + file.indexOf('.') !== 0 && + file !== basename && + file.slice(-3) === '.js' && + file.indexOf('.test.js') === -1 + ); + }) + .forEach(file => { + const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes); + db[model.name] = model; + }); + +Object.keys(db).forEach(modelName => { + if (db[modelName].associate) { + db[modelName].associate(db); + } +}); + +db.sequelize = sequelize; +db.Sequelize = Sequelize; + +module.exports = db; diff --git a/index.js b/index.js index 3fd92432..3cad7559 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,21 @@ -import express from "express"; +const cors = require("cors"); +const express = require("express"); +const { auth } = require("express-oauth2-jwt-bearer"); +require("dotenv").config(); -const PORT = 3000; +const PORT = process.env.PORT; const app = express(); +const { auth } = require("express-oauth2-jwt-bearer"); + +// Authorization middleware. When used, the Access Token must +// exist and be verified against the Auth0 JSON Web Key Set. +const checkJwt = auth({ + audience: process.env.AUTH_API, + issuerBaseURL: process.env.AUTH_DOMAIN, +}); + +// Enable CORS access to this server +app.use(cors()); app.get("/", (req, res) => { res.send("Hello, World!"); diff --git a/package-lock.json b/package-lock.json index bc0ea392..37712b57 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,10 +8,15 @@ "name": "project3-backend-bootcamp", "version": "1.0.0", "dependencies": { - "express": "^4.18.1" + "dotenv": "^16.4.5", + "express": "^4.18.1", + "express-oauth2-jwt-bearer": "^1.6.0", + "pg": "^8.11.3", + "sequelize": "^6.37.1" }, "devDependencies": { - "eslint": "^8.16.0" + "eslint": "^8.16.0", + "sequelize-cli": "^6.6.2" } }, "node_modules/@eslint/eslintrc": { @@ -100,6 +105,153 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@one-ini/wasm": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", + "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==", + "dev": true + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" + }, + "node_modules/@types/node": { + "version": "20.11.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.30.tgz", + "integrity": "sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/validator": { + "version": "13.11.9", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.9.tgz", + "integrity": "sha512-FCTsikRozryfayPuiI46QzH3fnrOoctTjvOYZkho9BTFLCOZ2rgZJHMOVgCOfttjPJcgOx52EpkY0CMfy87MIw==" + }, + "node_modules/abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -184,12 +336,27 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, "node_modules/body-parser": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", @@ -223,6 +390,14 @@ "concat-map": "0.0.1" } }, + "node_modules/buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", + "engines": { + "node": ">=4" + } + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -268,6 +443,33 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/cli-color": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.4.tgz", + "integrity": "sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.64", + "es6-iterator": "^2.0.3", + "memoizee": "^0.4.15", + "timers-ext": "^0.1.7" + }, + "engines": { + "node": ">=0.10" + } + }, + "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-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -286,12 +488,31 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "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==", + "dev": true, + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -338,6 +559,19 @@ "node": ">= 8" } }, + "node_modules/d": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", + "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", + "dev": true, + "dependencies": { + "es5-ext": "^0.10.64", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.12" + } + }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -381,11 +615,81 @@ "node": ">=6.0.0" } }, + "node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dottie": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.6.tgz", + "integrity": "sha512-iGCHkfUc5kFekGiqhe8B/mdaurD+lakO9txNnTvKtA6PISrw86LgqHvRzWYPyoE2Ph5aMIrCw9/uko6XHTKCwA==" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/editorconfig": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz", + "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==", + "dev": true, + "dependencies": { + "@one-ini/wasm": "0.1.1", + "commander": "^10.0.0", + "minimatch": "9.0.1", + "semver": "^7.5.3" + }, + "bin": { + "editorconfig": "bin/editorconfig" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/editorconfig/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/editorconfig/node_modules/minimatch": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", + "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -394,6 +698,67 @@ "node": ">= 0.8" } }, + "node_modules/es5-ext": { + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", + "next-tick": "^1.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/es6-symbol": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", + "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", + "dev": true, + "dependencies": { + "d": "^1.0.2", + "ext": "^1.7.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -535,6 +900,21 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + }, + "engines": { + "node": ">=0.10" + } + }, "node_modules/espree": { "version": "9.3.2", "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", @@ -599,6 +979,16 @@ "node": ">= 0.6" } }, + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dev": true, + "dependencies": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, "node_modules/express": { "version": "4.18.1", "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", @@ -640,6 +1030,26 @@ "node": ">= 0.10.0" } }, + "node_modules/express-oauth2-jwt-bearer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/express-oauth2-jwt-bearer/-/express-oauth2-jwt-bearer-1.6.0.tgz", + "integrity": "sha512-HXnez7vocYlOqlfF3ozPcf/WE3zxT7zfUNfeg5FHJnvNwhBYlNXiPOvuCtBalis8xcigvwtInzEKhBuH87+9ug==", + "dependencies": { + "jose": "^4.13.1" + }, + "engines": { + "node": "^12.19.0 || ^14.15.0 || ^16.13.0 || ^18.12.0 || ^20.2.0" + } + }, + "node_modules/ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dev": true, + "dependencies": { + "type": "^2.7.2" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -706,6 +1116,22 @@ "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", "dev": true }, + "node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -722,6 +1148,21 @@ "node": ">= 0.6" } }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -729,9 +1170,12 @@ "dev": true }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/functional-red-black-tree": { "version": "1.0.1", @@ -739,6 +1183,15 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, + "node_modules/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, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/get-intrinsic": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", @@ -799,6 +1252,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -830,6 +1289,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -890,6 +1361,14 @@ "node": ">=0.8.19" } }, + "node_modules/inflection": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.4.tgz", + "integrity": "sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==", + "engines": [ + "node >= 0.4.0" + ] + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -905,6 +1384,12 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -913,6 +1398,18 @@ "node": ">= 0.10" } }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -922,6 +1419,15 @@ "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -934,24 +1440,132 @@ "node": ">=0.10.0" } }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "dev": true + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", "dev": true, "dependencies": { - "argparse": "^2.0.1" + "@isaacs/cliui": "^8.0.2" }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jose": { + "version": "4.15.5", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", + "integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-beautify": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.1.tgz", + "integrity": "sha512-ESjNzSlt/sWE8sciZH8kBF8BPlwXPwhR6pWKAw8bw4Bwj+iZcnKW6ONWUutJ7eObuBZQpiIb8S7OYspWrKt7rA==", + "dev": true, + "dependencies": { + "config-chain": "^1.1.13", + "editorconfig": "^1.0.4", + "glob": "^10.3.3", + "js-cookie": "^3.0.5", + "nopt": "^7.2.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": ">=14" + } + }, + "node_modules/js-beautify/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/js-beautify/node_modules/glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/js-beautify/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/js-cookie": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", + "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -964,6 +1578,18 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -977,12 +1603,37 @@ "node": ">= 0.8.0" } }, + "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.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", + "dev": true, + "dependencies": { + "es5-ext": "~0.10.2" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -991,6 +1642,22 @@ "node": ">= 0.6" } }, + "node_modules/memoizee": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", + "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", + "dev": true, + "dependencies": { + "d": "^1.0.1", + "es5-ext": "^0.10.53", + "es6-weak-map": "^2.0.3", + "event-emitter": "^0.3.5", + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + } + }, "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -1046,6 +1713,34 @@ "node": "*" } }, + "node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "engines": { + "node": "*" + } + }, + "node_modules/moment-timezone": { + "version": "0.5.45", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz", + "integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==", + "dependencies": { + "moment": "^2.29.4" + }, + "engines": { + "node": "*" + } + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -1065,6 +1760,27 @@ "node": ">= 0.6" } }, + "node_modules/next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true + }, + "node_modules/nopt": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.0.tgz", + "integrity": "sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA==", + "dev": true, + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/object-inspect": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.1.tgz", @@ -1110,6 +1826,11 @@ "node": ">= 0.8.0" } }, + "node_modules/packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -1148,11 +1869,160 @@ "node": ">=8" } }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, + "node_modules/pg": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz", + "integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==", + "dependencies": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "^2.6.2", + "pg-pool": "^3.6.1", + "pg-protocol": "^1.6.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + }, + "engines": { + "node": ">= 8.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.1.1" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", + "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", + "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz", + "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", + "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -1162,6 +2032,12 @@ "node": ">= 0.8.0" } }, + "node_modules/proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -1231,6 +2107,32 @@ "url": "https://github.com/sponsors/mysticatea" } }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -1240,6 +2142,11 @@ "node": ">=4" } }, + "node_modules/retry-as-promised": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-7.0.4.tgz", + "integrity": "sha512-XgmCoxKWkDofwH8WddD0w85ZfqYz+ZHlr5yo+3YUCfycWawU56T5ckWXsScsj5B8tqUcIG67DxXByo3VUgiAdA==" + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -1279,6 +2186,20 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -1307,6 +2228,118 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, + "node_modules/sequelize": { + "version": "6.37.1", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.37.1.tgz", + "integrity": "sha512-vIKKzQ9dGp2aBOxQRD1FmUYViuQiKXSJ8yah8TsaBx4U3BokJt+Y2A0qz2C4pj08uX59qpWxRqSLEfRmVOEgQw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/sequelize" + } + ], + "dependencies": { + "@types/debug": "^4.1.8", + "@types/validator": "^13.7.17", + "debug": "^4.3.4", + "dottie": "^2.0.6", + "inflection": "^1.13.4", + "lodash": "^4.17.21", + "moment": "^2.29.4", + "moment-timezone": "^0.5.43", + "pg-connection-string": "^2.6.1", + "retry-as-promised": "^7.0.4", + "semver": "^7.5.4", + "sequelize-pool": "^7.1.0", + "toposort-class": "^1.0.1", + "uuid": "^8.3.2", + "validator": "^13.9.0", + "wkx": "^0.5.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependenciesMeta": { + "ibm_db": { + "optional": true + }, + "mariadb": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "oracledb": { + "optional": true + }, + "pg": { + "optional": true + }, + "pg-hstore": { + "optional": true + }, + "snowflake-sdk": { + "optional": true + }, + "sqlite3": { + "optional": true + }, + "tedious": { + "optional": true + } + } + }, + "node_modules/sequelize-cli": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/sequelize-cli/-/sequelize-cli-6.6.2.tgz", + "integrity": "sha512-V8Oh+XMz2+uquLZltZES6MVAD+yEnmMfwfn+gpXcDiwE3jyQygLt4xoI0zG8gKt6cRcs84hsKnXAKDQjG/JAgg==", + "dev": true, + "dependencies": { + "cli-color": "^2.0.3", + "fs-extra": "^9.1.0", + "js-beautify": "^1.14.5", + "lodash": "^4.17.21", + "resolve": "^1.22.1", + "umzug": "^2.3.0", + "yargs": "^16.2.0" + }, + "bin": { + "sequelize": "lib/sequelize", + "sequelize-cli": "lib/sequelize" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/sequelize-pool": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-7.1.0.tgz", + "integrity": "sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/sequelize/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/sequelize/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, "node_modules/serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", @@ -1360,6 +2393,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -1368,6 +2421,35 @@ "node": ">= 0.8" } }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -1380,6 +2462,19 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -1404,12 +2499,34 @@ "node": ">=8" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "node_modules/timers-ext": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", + "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "dev": true, + "dependencies": { + "es5-ext": "~0.10.46", + "next-tick": "1" + } + }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -1418,6 +2535,17 @@ "node": ">=0.6" } }, + "node_modules/toposort-class": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", + "integrity": "sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg==" + }, + "node_modules/type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", + "dev": true + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -1454,6 +2582,32 @@ "node": ">= 0.6" } }, + "node_modules/umzug": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/umzug/-/umzug-2.3.0.tgz", + "integrity": "sha512-Z274K+e8goZK8QJxmbRPhl89HPO1K+ORFtm6rySPhFKfKc5GHhqdzD0SGhSWHkzoXasqJuItdhorSvY7/Cgflw==", + "dev": true, + "dependencies": { + "bluebird": "^3.7.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -1479,12 +2633,28 @@ "node": ">= 0.4.0" } }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, + "node_modules/validator": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -1508,6 +2678,14 @@ "node": ">= 8" } }, + "node_modules/wkx": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.5.0.tgz", + "integrity": "sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -1517,11 +2695,95 @@ "node": ">=0.10.0" } }, + "node_modules/wrap-ansi": { + "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", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "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", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "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" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yargs": { + "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", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } } }, "dependencies": { @@ -1593,6 +2855,116 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + } + } + } + }, + "@one-ini/wasm": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", + "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==", + "dev": true + }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true + }, + "@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "requires": { + "@types/ms": "*" + } + }, + "@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" + }, + "@types/node": { + "version": "20.11.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.30.tgz", + "integrity": "sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==", + "requires": { + "undici-types": "~5.26.4" + } + }, + "@types/validator": { + "version": "13.11.9", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.9.tgz", + "integrity": "sha512-FCTsikRozryfayPuiI46QzH3fnrOoctTjvOYZkho9BTFLCOZ2rgZJHMOVgCOfttjPJcgOx52EpkY0CMfy87MIw==" + }, + "abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "dev": true + }, "accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -1653,12 +3025,24 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, "body-parser": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", @@ -1688,6 +3072,11 @@ "concat-map": "0.0.1" } }, + "buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==" + }, "bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -1718,6 +3107,30 @@ "supports-color": "^7.1.0" } }, + "cli-color": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.4.tgz", + "integrity": "sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==", + "dev": true, + "requires": { + "d": "^1.0.1", + "es5-ext": "^0.10.64", + "es6-iterator": "^2.0.3", + "memoizee": "^0.4.15", + "timers-ext": "^0.1.7" + } + }, + "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-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1733,12 +3146,28 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "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==", + "dev": true, + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, "content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", @@ -1773,6 +3202,16 @@ "which": "^2.0.1" } }, + "d": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", + "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", + "dev": true, + "requires": { + "es5-ext": "^0.10.64", + "type": "^2.7.2" + } + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -1803,18 +3242,123 @@ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "requires": { - "esutils": "^2.0.2" + "esutils": "^2.0.2" + } + }, + "dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==" + }, + "dottie": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.6.tgz", + "integrity": "sha512-iGCHkfUc5kFekGiqhe8B/mdaurD+lakO9txNnTvKtA6PISrw86LgqHvRzWYPyoE2Ph5aMIrCw9/uko6XHTKCwA==" + }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "editorconfig": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz", + "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==", + "dev": true, + "requires": { + "@one-ini/wasm": "0.1.1", + "commander": "^10.0.0", + "minimatch": "9.0.1", + "semver": "^7.5.3" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", + "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "es5-ext": { + "version": "0.10.64", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", + "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", + "dev": true, + "requires": { + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.3", + "esniff": "^2.0.1", + "next-tick": "^1.1.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-symbol": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", + "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", + "dev": true, + "requires": { + "d": "^1.0.2", + "ext": "^1.7.0" } }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + "es6-weak-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", + "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.46", + "es6-iterator": "^2.0.3", + "es6-symbol": "^3.1.1" + } }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + "escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true }, "escape-html": { "version": "1.0.3", @@ -1920,6 +3464,18 @@ "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true }, + "esniff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", + "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", + "dev": true, + "requires": { + "d": "^1.0.1", + "es5-ext": "^0.10.62", + "event-emitter": "^0.3.5", + "type": "^2.7.2" + } + }, "espree": { "version": "9.3.2", "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", @@ -1966,6 +3522,16 @@ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, + "event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "~0.10.14" + } + }, "express": { "version": "4.18.1", "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", @@ -2004,6 +3570,23 @@ "vary": "~1.1.2" } }, + "express-oauth2-jwt-bearer": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/express-oauth2-jwt-bearer/-/express-oauth2-jwt-bearer-1.6.0.tgz", + "integrity": "sha512-HXnez7vocYlOqlfF3ozPcf/WE3zxT7zfUNfeg5FHJnvNwhBYlNXiPOvuCtBalis8xcigvwtInzEKhBuH87+9ug==", + "requires": { + "jose": "^4.13.1" + } + }, + "ext": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", + "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", + "dev": true, + "requires": { + "type": "^2.7.2" + } + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -2061,6 +3644,16 @@ "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", "dev": true }, + "foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + } + }, "forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -2071,6 +3664,18 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2078,9 +3683,9 @@ "dev": true }, "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" }, "functional-red-black-tree": { "version": "1.0.1", @@ -2088,6 +3693,12 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, + "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 + }, "get-intrinsic": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", @@ -2130,6 +3741,12 @@ "type-fest": "^0.20.2" } }, + "graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -2149,6 +3766,15 @@ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, + "hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "requires": { + "function-bind": "^1.1.2" + } + }, "http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -2191,6 +3817,11 @@ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, + "inflection": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.4.tgz", + "integrity": "sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -2206,17 +3837,38 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, + "is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "requires": { + "hasown": "^2.0.0" + } + }, "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 }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -2226,12 +3878,85 @@ "is-extglob": "^2.1.1" } }, + "is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "dev": true + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, + "jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, + "jose": { + "version": "4.15.5", + "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", + "integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==" + }, + "js-beautify": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.1.tgz", + "integrity": "sha512-ESjNzSlt/sWE8sciZH8kBF8BPlwXPwhR6pWKAw8bw4Bwj+iZcnKW6ONWUutJ7eObuBZQpiIb8S7OYspWrKt7rA==", + "dev": true, + "requires": { + "config-chain": "^1.1.13", + "editorconfig": "^1.0.4", + "glob": "^10.3.3", + "js-cookie": "^3.0.5", + "nopt": "^7.2.0" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "glob": { + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "dev": true, + "requires": { + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + } + }, + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, + "js-cookie": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", + "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", + "dev": true + }, "js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -2253,6 +3978,16 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -2263,17 +3998,55 @@ "type-check": "~0.4.0" } }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "lru-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", + "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", + "dev": true, + "requires": { + "es5-ext": "~0.10.2" + } + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, + "memoizee": { + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", + "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", + "dev": true, + "requires": { + "d": "^1.0.1", + "es5-ext": "^0.10.53", + "es6-weak-map": "^2.0.3", + "event-emitter": "^0.3.5", + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + } + }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -2311,6 +4084,25 @@ "brace-expansion": "^1.1.7" } }, + "minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true + }, + "moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==" + }, + "moment-timezone": { + "version": "0.5.45", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz", + "integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==", + "requires": { + "moment": "^2.29.4" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -2327,6 +4119,21 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, + "next-tick": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", + "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", + "dev": true + }, + "nopt": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.0.tgz", + "integrity": "sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA==", + "dev": true, + "requires": { + "abbrev": "^2.0.0" + } + }, "object-inspect": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.1.tgz", @@ -2363,6 +4170,11 @@ "word-wrap": "^1.2.3" } }, + "packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -2389,17 +4201,132 @@ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "requires": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", + "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "dev": true + } + } + }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, + "pg": { + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz", + "integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==", + "requires": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-cloudflare": "^1.1.1", + "pg-connection-string": "^2.6.2", + "pg-pool": "^3.6.1", + "pg-protocol": "^1.6.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + } + }, + "pg-cloudflare": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", + "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", + "optional": true + }, + "pg-connection-string": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", + "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" + }, + "pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" + }, + "pg-pool": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz", + "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==", + "requires": {} + }, + "pg-protocol": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", + "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" + }, + "pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "requires": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + } + }, + "pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "requires": { + "split2": "^4.1.0" + } + }, + "postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" + }, + "postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==" + }, + "postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==" + }, + "postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "requires": { + "xtend": "^4.0.0" + } + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, + "proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", + "dev": true + }, "proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -2445,12 +4372,34 @@ "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true + }, + "resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "requires": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "retry-as-promised": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-7.0.4.tgz", + "integrity": "sha512-XgmCoxKWkDofwH8WddD0w85ZfqYz+ZHlr5yo+3YUCfycWawU56T5ckWXsScsj5B8tqUcIG67DxXByo3VUgiAdA==" + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -2470,6 +4419,14 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "requires": { + "lru-cache": "^6.0.0" + } + }, "send": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", @@ -2497,6 +4454,64 @@ } } }, + "sequelize": { + "version": "6.37.1", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.37.1.tgz", + "integrity": "sha512-vIKKzQ9dGp2aBOxQRD1FmUYViuQiKXSJ8yah8TsaBx4U3BokJt+Y2A0qz2C4pj08uX59qpWxRqSLEfRmVOEgQw==", + "requires": { + "@types/debug": "^4.1.8", + "@types/validator": "^13.7.17", + "debug": "^4.3.4", + "dottie": "^2.0.6", + "inflection": "^1.13.4", + "lodash": "^4.17.21", + "moment": "^2.29.4", + "moment-timezone": "^0.5.43", + "pg-connection-string": "^2.6.1", + "retry-as-promised": "^7.0.4", + "semver": "^7.5.4", + "sequelize-pool": "^7.1.0", + "toposort-class": "^1.0.1", + "uuid": "^8.3.2", + "validator": "^13.9.0", + "wkx": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "sequelize-cli": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/sequelize-cli/-/sequelize-cli-6.6.2.tgz", + "integrity": "sha512-V8Oh+XMz2+uquLZltZES6MVAD+yEnmMfwfn+gpXcDiwE3jyQygLt4xoI0zG8gKt6cRcs84hsKnXAKDQjG/JAgg==", + "dev": true, + "requires": { + "cli-color": "^2.0.3", + "fs-extra": "^9.1.0", + "js-beautify": "^1.14.5", + "lodash": "^4.17.21", + "resolve": "^1.22.1", + "umzug": "^2.3.0", + "yargs": "^16.2.0" + } + }, + "sequelize-pool": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-7.1.0.tgz", + "integrity": "sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==" + }, "serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", @@ -2538,11 +4553,44 @@ "object-inspect": "^1.9.0" } }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + }, + "split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==" + }, "statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -2552,6 +4600,15 @@ "ansi-regex": "^5.0.1" } }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -2567,17 +4624,44 @@ "has-flag": "^4.0.0" } }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, + "timers-ext": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", + "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", + "dev": true, + "requires": { + "es5-ext": "~0.10.46", + "next-tick": "1" + } + }, "toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" }, + "toposort-class": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", + "integrity": "sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg==" + }, + "type": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", + "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", + "dev": true + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -2602,6 +4686,26 @@ "mime-types": "~2.1.24" } }, + "umzug": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/umzug/-/umzug-2.3.0.tgz", + "integrity": "sha512-Z274K+e8goZK8QJxmbRPhl89HPO1K+ORFtm6rySPhFKfKc5GHhqdzD0SGhSWHkzoXasqJuItdhorSvY7/Cgflw==", + "dev": true, + "requires": { + "bluebird": "^3.7.2" + } + }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, + "universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -2621,12 +4725,22 @@ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + }, "v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, + "validator": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -2641,17 +4755,84 @@ "isexe": "^2.0.0" } }, + "wkx": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.5.0.tgz", + "integrity": "sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==", + "requires": { + "@types/node": "*" + } + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, + "wrap-ansi": { + "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", + "strip-ansi": "^6.0.0" + } + }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@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", + "strip-ansi": "^6.0.0" + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "yargs": { + "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", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true } } } diff --git a/package.json b/package.json index 09b3bc32..17f0b995 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,14 @@ "start": "nodemon index.js" }, "dependencies": { - "express": "^4.18.1" + "dotenv": "^16.4.5", + "express": "^4.18.1", + "express-oauth2-jwt-bearer": "^1.6.0", + "pg": "^8.11.3", + "sequelize": "^6.37.1" }, "devDependencies": { - "eslint": "^8.16.0" + "eslint": "^8.16.0", + "sequelize-cli": "^6.6.2" } } From 97a31128ef955d6af310fa84bbe9f1640e8dc73e Mon Sep 17 00:00:00 2001 From: magiicloud Date: Tue, 26 Mar 2024 01:16:01 +0800 Subject: [PATCH 02/44] changed to sequelize-typescript and finished configuring migrations and models --- .../20240325145721-initial-migration.ts | 326 ++++++++++++++++++ db/models/Building.ts | 39 +++ db/models/BuildingUser.ts | 37 ++ db/models/Cart.ts | 36 ++ db/models/CartLineItem.ts | 44 +++ db/models/Item.ts | 31 ++ db/models/Room.ts | 44 +++ db/models/RoomItem.ts | 47 +++ db/models/Transaction.ts | 39 +++ db/models/User.ts | 65 ++++ db/models/index.js | 43 --- db/models/index.ts | 52 +++ package-lock.json | 310 +++++++++++++++-- package.json | 10 +- tsconfig.json | 111 ++++++ 15 files changed, 1160 insertions(+), 74 deletions(-) create mode 100644 db/migrations/20240325145721-initial-migration.ts create mode 100644 db/models/Building.ts create mode 100644 db/models/BuildingUser.ts create mode 100644 db/models/Cart.ts create mode 100644 db/models/CartLineItem.ts create mode 100644 db/models/Item.ts create mode 100644 db/models/Room.ts create mode 100644 db/models/RoomItem.ts create mode 100644 db/models/Transaction.ts create mode 100644 db/models/User.ts delete mode 100644 db/models/index.js create mode 100644 db/models/index.ts create mode 100644 tsconfig.json diff --git a/db/migrations/20240325145721-initial-migration.ts b/db/migrations/20240325145721-initial-migration.ts new file mode 100644 index 00000000..97a1c088 --- /dev/null +++ b/db/migrations/20240325145721-initial-migration.ts @@ -0,0 +1,326 @@ +"use strict"; +/** @type {import('sequelize-cli').Migration} */ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + async up(queryInterface: QueryInterface, Sequelize: typeof DataTypes) { + await queryInterface.createTable("Users", { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER, + }, + name: { + allowNull: false, + type: Sequelize.STRING, + }, + email: { + allowNull: false, + type: Sequelize.STRING, + }, + profile_img_url: { + type: Sequelize.STRING, + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE, + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE, + }, + }); + + await queryInterface.createTable("Items", { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER, + }, + serial_num: { + allowNull: false, + type: Sequelize.STRING, + }, + item_name: { + allowNull: false, + type: Sequelize.STRING, + }, + par_level: { + allowNull: false, + type: Sequelize.INTEGER, + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE, + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE, + }, + }); + + await queryInterface.createTable("Buildings", { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER, + }, + name: { + allowNull: false, + type: Sequelize.STRING, + }, + item_size: { + allowNull: false, + type: Sequelize.STRING, + }, + building_img_url: { + allowNull: false, + type: Sequelize.INTEGER, + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE, + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE, + }, + }); + + await queryInterface.createTable("Rooms", { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER, + }, + name: { + allowNull: false, + type: Sequelize.STRING, + }, + room_coordinates: { + allowNull: false, + type: Sequelize.STRING, + }, + building_id: { + allowNull: false, + type: Sequelize.INTEGER, + references: { + model: "Building", + key: "id", + }, + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE, + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE, + }, + }); + + await queryInterface.createTable("Carts", { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER, + }, + active: { + allowNull: false, + type: Sequelize.BOOLEAN, + }, + user_id: { + allowNull: false, + type: Sequelize.INTEGER, + references: { + model: "User", + key: "id", + }, + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE, + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE, + }, + }); + + await queryInterface.createTable("Transactions", { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER, + }, + cart_id: { + allowNull: false, + type: Sequelize.INTEGER, + references: { + model: "Cart", + key: "id", + }, + }, + room_id: { + allowNull: false, + type: Sequelize.INTEGER, + references: { + model: "Room", + key: "id", + }, + }, + cycle_count: { + allowNull: false, + type: Sequelize.BOOLEAN, + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE, + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE, + }, + }); + + await queryInterface.createTable("Building_Users", { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER, + }, + building_id: { + allowNull: false, + type: Sequelize.INTEGER, + references: { + model: "Building", + key: "id", + }, + }, + user_id: { + allowNull: false, + type: Sequelize.INTEGER, + references: { + model: "User", + key: "id", + }, + }, + admin: { + allowNull: false, + type: Sequelize.BOOLEAN, + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE, + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE, + }, + }); + + await queryInterface.createTable("Cart_Line_Items", { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER, + }, + cart_id: { + allowNull: false, + type: Sequelize.INTEGER, + references: { + model: "Cart", + key: "id", + }, + }, + item_id: { + allowNull: false, + type: Sequelize.INTEGER, + references: { + model: "Item", + key: "id", + }, + }, + quantity: { + allowNull: false, + type: Sequelize.INTEGER, + }, + consumed: { + allowNull: false, + type: Sequelize.BOOLEAN, + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE, + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE, + }, + }); + + await queryInterface.createTable("Room_Items", { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER, + }, + room_id: { + allowNull: false, + type: Sequelize.INTEGER, + references: { + model: "Room", + key: "id", + }, + }, + item_id: { + allowNull: false, + type: Sequelize.INTEGER, + references: { + model: "Item", + key: "id", + }, + }, + quantity: { + allowNull: false, + type: Sequelize.INTEGER, + }, + uom: { + allowNull: false, + type: Sequelize.STRING, + }, + expiry_date: { + allowNull: false, + type: Sequelize.DATE, + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE, + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE, + }, + }); + }, + async down(queryInterface: QueryInterface, Sequelize: typeof DataTypes) { + await queryInterface.dropTable("Room_Items"); + await queryInterface.dropTable("Cart_Line_Items"); + await queryInterface.dropTable("Building_Users"); + await queryInterface.dropTable("Transactions"); + await queryInterface.dropTable("Carts"); + await queryInterface.dropTable("Rooms"); + await queryInterface.dropTable("Buildings"); + await queryInterface.dropTable("Items"); + await queryInterface.dropTable("Users"); + }, +}; diff --git a/db/models/Building.ts b/db/models/Building.ts new file mode 100644 index 00000000..f25767c9 --- /dev/null +++ b/db/models/Building.ts @@ -0,0 +1,39 @@ +import { + Table, + Column, + Model, + DataType, + HasMany, + BelongsToMany, +} from "sequelize-typescript"; +import { Room } from "./Room"; +import { User } from "./User"; +import { BuildingUser } from "./BuildingUser"; + +interface BuildingAttributes { + name: string; + item_size: string; + building_img_url: string; +} + +@Table({ + modelName: "Building", + underscored: true, +}) +export class Building extends Model { + @Column(DataType.STRING) + name!: string; + + @Column(DataType.STRING) + item_size!: string; + + @Column(DataType.STRING) + building_img_url!: string; + + // Associations can be defined here if needed + @HasMany(() => Room) + rooms!: Room[]; + + @BelongsToMany(() => User, () => BuildingUser) + users!: User[]; +} diff --git a/db/models/BuildingUser.ts b/db/models/BuildingUser.ts new file mode 100644 index 00000000..0328b208 --- /dev/null +++ b/db/models/BuildingUser.ts @@ -0,0 +1,37 @@ +import { + Table, + Column, + Model, + DataType, + ForeignKey, + BelongsTo, +} from "sequelize-typescript"; +import { Building } from "./Building"; +import { User } from "./User"; + +interface BuildingUserAttributes { + admin: boolean; +} + +@Table({ + modelName: "BuildingUser", + underscored: true, +}) +export class BuildingUser extends Model { + @ForeignKey(() => Building) + @Column(DataType.INTEGER) + building_id!: number; + + @ForeignKey(() => User) + @Column(DataType.INTEGER) + user_id!: number; + + @Column(DataType.BOOLEAN) + admin!: boolean; + + @BelongsTo(() => Building) + building!: Building; + + @BelongsTo(() => User) + user!: User; +} diff --git a/db/models/Cart.ts b/db/models/Cart.ts new file mode 100644 index 00000000..7906fb12 --- /dev/null +++ b/db/models/Cart.ts @@ -0,0 +1,36 @@ +import { + Table, + Column, + Model, + DataType, + ForeignKey, + BelongsTo, + HasMany, +} from "sequelize-typescript"; +import { User } from "./User"; +import { CartLineItem } from "./CartLineItem"; + +interface CartAttributes { + active: boolean; + user_id: number; +} + +@Table({ + modelName: "Cart", + underscored: true, +}) +export class Cart extends Model { + @Column(DataType.BOOLEAN) + active!: boolean; + + @ForeignKey(() => User) + @Column(DataType.INTEGER) + user_id!: number; + + // Associations can be defined here if needed + @BelongsTo(() => User) + user!: User; + + @HasMany(() => CartLineItem) + cartLineItems!: CartLineItem[]; +} diff --git a/db/models/CartLineItem.ts b/db/models/CartLineItem.ts new file mode 100644 index 00000000..9e9e5aa2 --- /dev/null +++ b/db/models/CartLineItem.ts @@ -0,0 +1,44 @@ +import { + Table, + Column, + Model, + DataType, + ForeignKey, + BelongsTo, +} from "sequelize-typescript"; +import { Cart } from "./Cart"; +import { Item } from "./Item"; + +interface CartLineItemAttributes { + cart_id: number; + item_id: number; + quantity: number; + consumed: boolean; +} + +@Table({ + modelName: "CartLineItem", + underscored: true, +}) +export class CartLineItem extends Model { + @ForeignKey(() => Cart) + @Column(DataType.INTEGER) + cart_id!: number; + + @ForeignKey(() => Item) + @Column(DataType.INTEGER) + item_id!: number; + + @Column(DataType.INTEGER) + quantity!: number; + + @Column(DataType.BOOLEAN) + consumed!: boolean; + + // Associations can be defined here if needed + @BelongsTo(() => Cart) + cart!: Cart; + + @BelongsTo(() => Item) + item!: Item; +} diff --git a/db/models/Item.ts b/db/models/Item.ts new file mode 100644 index 00000000..177f048a --- /dev/null +++ b/db/models/Item.ts @@ -0,0 +1,31 @@ +import { Table, Column, Model, DataType, HasMany } from "sequelize-typescript"; +import { CartLineItem } from "./CartLineItem"; +import { RoomItem } from "./RoomItem"; + +interface ItemAttributes { + serial_num: string; + item_name: string; + par_level: number; +} + +@Table({ + modelName: "Item", + underscored: true, +}) +export class Item extends Model { + @Column(DataType.STRING) + serial_num!: string; + + @Column(DataType.STRING) + item_name!: string; + + @Column(DataType.INTEGER) + par_level!: number; + + // Associations can be defined here if needed + @HasMany(() => CartLineItem) + cartLineItems!: CartLineItem[]; + + @HasMany(() => RoomItem) + roomItems!: RoomItem[]; +} diff --git a/db/models/Room.ts b/db/models/Room.ts new file mode 100644 index 00000000..1b3836f3 --- /dev/null +++ b/db/models/Room.ts @@ -0,0 +1,44 @@ +import { + Table, + Column, + Model, + DataType, + ForeignKey, + BelongsTo, + HasMany, +} from "sequelize-typescript"; +import { Building } from "./Building"; +import { Transaction } from "./Transaction"; +import { RoomItem } from "./RoomItem"; + +interface RoomAttributes { + name: string; + room_coordinates: string; + building_id: number; +} + +@Table({ + modelName: "Room", + underscored: true, +}) +export class Room extends Model { + @Column(DataType.STRING) + name!: string; + + @Column(DataType.STRING) + room_coordinates!: string; + + @ForeignKey(() => Building) + @Column(DataType.INTEGER) + building_id!: number; + + // Associations can be defined here if needed + @BelongsTo(() => Building) + building!: Building; + + @HasMany(() => Transaction) + transactions!: Transaction; + + @HasMany(() => RoomItem) + roomItems!: RoomItem[]; +} diff --git a/db/models/RoomItem.ts b/db/models/RoomItem.ts new file mode 100644 index 00000000..9743d157 --- /dev/null +++ b/db/models/RoomItem.ts @@ -0,0 +1,47 @@ +import { + Table, + Column, + Model, + DataType, + ForeignKey, + BelongsTo, +} from "sequelize-typescript"; +import { Room } from "./Room"; +import { Item } from "./Item"; + +interface RoomItemAttributes { + room_id: number; + item_id: number; + quantity: number; + uom: string; + expiry_date: Date; +} + +@Table({ + modelName: "Room_Item", + underscored: true, +}) +export class RoomItem extends Model { + @ForeignKey(() => Room) + @Column(DataType.INTEGER) + room_id!: number; + + @BelongsTo(() => Room) + room!: Room; + + @ForeignKey(() => Item) + @Column(DataType.INTEGER) + item_id!: number; + + @BelongsTo(() => Item) + item!: Item; + + @Column(DataType.INTEGER) + quantity!: number; + + @Column(DataType.STRING) + uom!: string; + + @Column(DataType.DATE) + expiry_date!: Date; +} diff --git a/db/models/Transaction.ts b/db/models/Transaction.ts new file mode 100644 index 00000000..cb3c2124 --- /dev/null +++ b/db/models/Transaction.ts @@ -0,0 +1,39 @@ +import { + Table, + Column, + Model, + DataType, + ForeignKey, + BelongsTo, +} from "sequelize-typescript"; +import { Cart } from "./Cart"; +import { Room } from "./Room"; + +interface TransactionAttributes { + cycle_count: boolean; +} + +@Table({ + modelName: "Transaction", + underscored: true, +}) +export class Transaction extends Model { + @ForeignKey(() => Cart) + @Column(DataType.INTEGER) + cart_id!: number; + + @ForeignKey(() => Room) + @Column(DataType.INTEGER) + room_id!: number; + + @Column(DataType.BOOLEAN) + cycle_count!: boolean; + + // Associations can be defined here if needed + + @BelongsTo(() => Cart) + cart!: Cart; + + @BelongsTo(() => Room) + room!: Room; +} diff --git a/db/models/User.ts b/db/models/User.ts new file mode 100644 index 00000000..f56cb941 --- /dev/null +++ b/db/models/User.ts @@ -0,0 +1,65 @@ +"use strict"; +// const { Model } = require("sequelize"); +// module.exports = (sequelize, DataTypes) => { +// class User extends Model { +// /** +// * Helper method for defining associations. +// * This method is not a part of Sequelize lifecycle. +// * The `models/index` file will call this method automatically. +// */ +// static associate(models) { +// // define association here +// } +// } +// User.init( +// { +// name: DataTypes.STRING, +// email: DataTypes.STRING, +// profile_img_url: DataTypes.STRING, +// }, +// { +// sequelize, +// modelName: "User", +// } +// ); +// return User; +// }; + +import { + Table, + Column, + Model, + DataType, + HasMany, + HasOne, +} from "sequelize-typescript"; +import { Cart } from "./Cart"; +import { BuildingUser } from "./BuildingUser"; + +interface UserAttributes { + name: string; + email: string; + profile_img_url?: string; +} + +@Table({ + modelName: "User", + underscored: true, +}) +export class User extends Model { + @Column(DataType.STRING) + name!: string; + + @Column(DataType.STRING) + email!: string; + + @Column(DataType.STRING) + profile_img_url?: string; + + // Associations can be defined here if needed + @HasMany(() => Cart) + carts!: Cart[]; + + @HasOne(() => BuildingUser) + buildingUser!: BuildingUser; +} diff --git a/db/models/index.js b/db/models/index.js deleted file mode 100644 index 5edbd256..00000000 --- a/db/models/index.js +++ /dev/null @@ -1,43 +0,0 @@ -'use strict'; - -const fs = require('fs'); -const path = require('path'); -const Sequelize = require('sequelize'); -const process = require('process'); -const basename = path.basename(__filename); -const env = process.env.NODE_ENV || 'development'; -const config = require(__dirname + '/../../config/database.js')[env]; -const db = {}; - -let sequelize; -if (config.use_env_variable) { - sequelize = new Sequelize(process.env[config.use_env_variable], config); -} else { - sequelize = new Sequelize(config.database, config.username, config.password, config); -} - -fs - .readdirSync(__dirname) - .filter(file => { - return ( - file.indexOf('.') !== 0 && - file !== basename && - file.slice(-3) === '.js' && - file.indexOf('.test.js') === -1 - ); - }) - .forEach(file => { - const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes); - db[model.name] = model; - }); - -Object.keys(db).forEach(modelName => { - if (db[modelName].associate) { - db[modelName].associate(db); - } -}); - -db.sequelize = sequelize; -db.Sequelize = Sequelize; - -module.exports = db; diff --git a/db/models/index.ts b/db/models/index.ts new file mode 100644 index 00000000..acc0e582 --- /dev/null +++ b/db/models/index.ts @@ -0,0 +1,52 @@ +"use strict"; +import { Sequelize } from "sequelize-typescript"; +import * as fs from "fs"; +import * as path from "path"; +import process from "process"; + +// const process = require("process"); +const basename = path.basename(__filename); +const env = process.env.NODE_ENV || "development"; +const config = require(__dirname + "/../../config/database.js")[env]; +const db: any = {}; + +let sequelize: Sequelize; +if (config.use_env_variable) { + const databaseUrl = process.env[config.use_env_variable] as string; + sequelize = new Sequelize(databaseUrl, config); + // sequelize = new Sequelize(process.env[config.use_env_variable], config); +} else { + sequelize = new Sequelize( + config.database, + config.username, + config.password, + config + ); +} + +// Read all model files and import them +fs.readdirSync(__dirname) + .filter((file) => { + return ( + file.indexOf(".") !== 0 && + file !== basename && + file.slice(-3) === ".ts" && + file.indexOf(".test.ts") === -1 + ); + }) + .forEach((file) => { + const model = require(path.join(__dirname, file)).default; + db[model.name] = model; + }); + +Object.keys(db).forEach((modelName) => { + if (db[modelName].associate) { + db[modelName].associate(db); + } +}); + +// Export sequelize instance and models +db.sequelize = sequelize; +db.Sequelize = Sequelize; + +module.exports = db; diff --git a/package-lock.json b/package-lock.json index 37712b57..e1e62c86 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,11 +12,17 @@ "express": "^4.18.1", "express-oauth2-jwt-bearer": "^1.6.0", "pg": "^8.11.3", - "sequelize": "^6.37.1" + "reflect-metadata": "^0.2.1", + "sequelize": "^6.37.1", + "sequelize-typescript": "^2.1.6" }, "devDependencies": { + "@types/express": "^4.17.21", + "@types/node": "^20.11.30", + "@types/validator": "^13.11.9", "eslint": "^8.16.0", - "sequelize-cli": "^6.6.2" + "sequelize-cli": "^6.6.2", + "typescript": "^5.4.3" } }, "node_modules/@eslint/eslintrc": { @@ -217,6 +223,25 @@ "node": ">=14" } }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/debug": { "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", @@ -225,6 +250,42 @@ "@types/ms": "*" } }, + "node_modules/@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.43", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", + "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, "node_modules/@types/ms": { "version": "0.7.34", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", @@ -238,6 +299,39 @@ "undici-types": "~5.26.4" } }, + "node_modules/@types/qs": { + "version": "6.9.14", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.14.tgz", + "integrity": "sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "dev": true, + "dependencies": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, "node_modules/@types/validator": { "version": "13.11.9", "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.9.tgz", @@ -348,8 +442,7 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/bluebird": { "version": "3.7.2", @@ -384,7 +477,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -500,8 +592,7 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "node_modules/config-chain": { "version": "1.1.13", @@ -1166,8 +1257,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "node_modules/function-bind": { "version": "1.1.2", @@ -1373,7 +1463,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -1705,7 +1794,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1804,7 +1892,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "dependencies": { "wrappy": "1" } @@ -1855,7 +1942,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -2095,6 +2181,11 @@ "node": ">= 0.8" } }, + "node_modules/reflect-metadata": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz", + "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==" + }, "node_modules/regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", @@ -2319,6 +2410,42 @@ "node": ">= 10.0.0" } }, + "node_modules/sequelize-typescript": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/sequelize-typescript/-/sequelize-typescript-2.1.6.tgz", + "integrity": "sha512-Vc2N++3en346RsbGjL3h7tgAl2Y7V+2liYTAOZ8XL0KTw3ahFHsyAUzOwct51n+g70I1TOUDgs06Oh6+XGcFkQ==", + "dependencies": { + "glob": "7.2.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "@types/validator": "*", + "reflect-metadata": "*", + "sequelize": ">=6.20.1" + } + }, + "node_modules/sequelize-typescript/node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/sequelize/node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -2582,6 +2709,19 @@ "node": ">= 0.6" } }, + "node_modules/typescript": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", + "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/umzug": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/umzug/-/umzug-2.3.0.tgz", @@ -2733,8 +2873,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "node_modules/xtend": { "version": "4.0.2", @@ -2933,6 +3072,25 @@ "dev": true, "optional": true }, + "@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/debug": { "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", @@ -2941,6 +3099,42 @@ "@types/ms": "*" } }, + "@types/express": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", + "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.43", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", + "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true + }, + "@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true + }, "@types/ms": { "version": "0.7.34", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", @@ -2954,6 +3148,39 @@ "undici-types": "~5.26.4" } }, + "@types/qs": { + "version": "6.9.14", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.14.tgz", + "integrity": "sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true + }, + "@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "@types/serve-static": { + "version": "1.15.5", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", + "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", + "dev": true, + "requires": { + "@types/http-errors": "*", + "@types/mime": "*", + "@types/node": "*" + } + }, "@types/validator": { "version": "13.11.9", "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.9.tgz", @@ -3034,8 +3261,7 @@ "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "bluebird": { "version": "3.7.2", @@ -3066,7 +3292,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3155,8 +3380,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "config-chain": { "version": "1.1.13", @@ -3679,8 +3903,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "function-bind": { "version": "1.1.2", @@ -3826,7 +4049,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -4079,7 +4301,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -4151,7 +4372,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } @@ -4192,8 +4412,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-key": { "version": "3.1.1", @@ -4366,6 +4585,11 @@ "unpipe": "1.0.0" } }, + "reflect-metadata": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz", + "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==" + }, "regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", @@ -4512,6 +4736,29 @@ "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-7.1.0.tgz", "integrity": "sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==" }, + "sequelize-typescript": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/sequelize-typescript/-/sequelize-typescript-2.1.6.tgz", + "integrity": "sha512-Vc2N++3en346RsbGjL3h7tgAl2Y7V+2liYTAOZ8XL0KTw3ahFHsyAUzOwct51n+g70I1TOUDgs06Oh6+XGcFkQ==", + "requires": { + "glob": "7.2.0" + }, + "dependencies": { + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, "serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", @@ -4686,6 +4933,12 @@ "mime-types": "~2.1.24" } }, + "typescript": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", + "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", + "dev": true + }, "umzug": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/umzug/-/umzug-2.3.0.tgz", @@ -4794,8 +5047,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "xtend": { "version": "4.0.2", diff --git a/package.json b/package.json index 17f0b995..7173cd3e 100644 --- a/package.json +++ b/package.json @@ -9,10 +9,16 @@ "express": "^4.18.1", "express-oauth2-jwt-bearer": "^1.6.0", "pg": "^8.11.3", - "sequelize": "^6.37.1" + "reflect-metadata": "^0.2.1", + "sequelize": "^6.37.1", + "sequelize-typescript": "^2.1.6" }, "devDependencies": { + "@types/express": "^4.17.21", + "@types/node": "^20.11.30", + "@types/validator": "^13.11.9", "eslint": "^8.16.0", - "sequelize-cli": "^6.6.2" + "sequelize-cli": "^6.6.2", + "typescript": "^5.4.3" } } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..c5b0d2f5 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,111 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + /* Modules */ + "module": "commonjs" /* Specify what module code is generated. */, + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, + + /* Type Checking */ + "strict": true /* Enable all strict type-checking options. */, + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + }, + "include": ["**/*.ts", "**/*.tsx", "config/database.js"] +} From 8fa385b5e221b18eb89b6407dabee5628a806fa7 Mon Sep 17 00:00:00 2001 From: magiicloud Date: Tue, 26 Mar 2024 09:32:58 +0800 Subject: [PATCH 03/44] separated migrations into primary, secondary and tertiary tables --- .../20240325145721-initial-migration.ts | 228 ------------------ .../20240326012147-secondary_tables.ts | 111 +++++++++ .../20240326012343-tertiary_tables.ts | 135 +++++++++++ 3 files changed, 246 insertions(+), 228 deletions(-) create mode 100644 db/migrations/20240326012147-secondary_tables.ts create mode 100644 db/migrations/20240326012343-tertiary_tables.ts diff --git a/db/migrations/20240325145721-initial-migration.ts b/db/migrations/20240325145721-initial-migration.ts index 97a1c088..7bfcfd5d 100644 --- a/db/migrations/20240325145721-initial-migration.ts +++ b/db/migrations/20240325145721-initial-migration.ts @@ -89,236 +89,8 @@ module.exports = { type: Sequelize.DATE, }, }); - - await queryInterface.createTable("Rooms", { - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: Sequelize.INTEGER, - }, - name: { - allowNull: false, - type: Sequelize.STRING, - }, - room_coordinates: { - allowNull: false, - type: Sequelize.STRING, - }, - building_id: { - allowNull: false, - type: Sequelize.INTEGER, - references: { - model: "Building", - key: "id", - }, - }, - createdAt: { - allowNull: false, - type: Sequelize.DATE, - }, - updatedAt: { - allowNull: false, - type: Sequelize.DATE, - }, - }); - - await queryInterface.createTable("Carts", { - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: Sequelize.INTEGER, - }, - active: { - allowNull: false, - type: Sequelize.BOOLEAN, - }, - user_id: { - allowNull: false, - type: Sequelize.INTEGER, - references: { - model: "User", - key: "id", - }, - }, - createdAt: { - allowNull: false, - type: Sequelize.DATE, - }, - updatedAt: { - allowNull: false, - type: Sequelize.DATE, - }, - }); - - await queryInterface.createTable("Transactions", { - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: Sequelize.INTEGER, - }, - cart_id: { - allowNull: false, - type: Sequelize.INTEGER, - references: { - model: "Cart", - key: "id", - }, - }, - room_id: { - allowNull: false, - type: Sequelize.INTEGER, - references: { - model: "Room", - key: "id", - }, - }, - cycle_count: { - allowNull: false, - type: Sequelize.BOOLEAN, - }, - createdAt: { - allowNull: false, - type: Sequelize.DATE, - }, - updatedAt: { - allowNull: false, - type: Sequelize.DATE, - }, - }); - - await queryInterface.createTable("Building_Users", { - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: Sequelize.INTEGER, - }, - building_id: { - allowNull: false, - type: Sequelize.INTEGER, - references: { - model: "Building", - key: "id", - }, - }, - user_id: { - allowNull: false, - type: Sequelize.INTEGER, - references: { - model: "User", - key: "id", - }, - }, - admin: { - allowNull: false, - type: Sequelize.BOOLEAN, - }, - createdAt: { - allowNull: false, - type: Sequelize.DATE, - }, - updatedAt: { - allowNull: false, - type: Sequelize.DATE, - }, - }); - - await queryInterface.createTable("Cart_Line_Items", { - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: Sequelize.INTEGER, - }, - cart_id: { - allowNull: false, - type: Sequelize.INTEGER, - references: { - model: "Cart", - key: "id", - }, - }, - item_id: { - allowNull: false, - type: Sequelize.INTEGER, - references: { - model: "Item", - key: "id", - }, - }, - quantity: { - allowNull: false, - type: Sequelize.INTEGER, - }, - consumed: { - allowNull: false, - type: Sequelize.BOOLEAN, - }, - createdAt: { - allowNull: false, - type: Sequelize.DATE, - }, - updatedAt: { - allowNull: false, - type: Sequelize.DATE, - }, - }); - - await queryInterface.createTable("Room_Items", { - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: Sequelize.INTEGER, - }, - room_id: { - allowNull: false, - type: Sequelize.INTEGER, - references: { - model: "Room", - key: "id", - }, - }, - item_id: { - allowNull: false, - type: Sequelize.INTEGER, - references: { - model: "Item", - key: "id", - }, - }, - quantity: { - allowNull: false, - type: Sequelize.INTEGER, - }, - uom: { - allowNull: false, - type: Sequelize.STRING, - }, - expiry_date: { - allowNull: false, - type: Sequelize.DATE, - }, - createdAt: { - allowNull: false, - type: Sequelize.DATE, - }, - updatedAt: { - allowNull: false, - type: Sequelize.DATE, - }, - }); }, async down(queryInterface: QueryInterface, Sequelize: typeof DataTypes) { - await queryInterface.dropTable("Room_Items"); - await queryInterface.dropTable("Cart_Line_Items"); - await queryInterface.dropTable("Building_Users"); - await queryInterface.dropTable("Transactions"); - await queryInterface.dropTable("Carts"); - await queryInterface.dropTable("Rooms"); await queryInterface.dropTable("Buildings"); await queryInterface.dropTable("Items"); await queryInterface.dropTable("Users"); diff --git a/db/migrations/20240326012147-secondary_tables.ts b/db/migrations/20240326012147-secondary_tables.ts new file mode 100644 index 00000000..f300c374 --- /dev/null +++ b/db/migrations/20240326012147-secondary_tables.ts @@ -0,0 +1,111 @@ +"use strict"; +/** @type {import('sequelize-cli').Migration} */ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + async up(queryInterface: QueryInterface, Sequelize: typeof DataTypes) { + await queryInterface.createTable("Rooms", { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER, + }, + name: { + allowNull: false, + type: Sequelize.STRING, + }, + room_coordinates: { + allowNull: false, + type: Sequelize.STRING, + }, + building_id: { + allowNull: false, + type: Sequelize.INTEGER, + references: { + model: "Building", + key: "id", + }, + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE, + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE, + }, + }); + + await queryInterface.createTable("Carts", { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER, + }, + active: { + allowNull: false, + type: Sequelize.BOOLEAN, + }, + user_id: { + allowNull: false, + type: Sequelize.INTEGER, + references: { + model: "User", + key: "id", + }, + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE, + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE, + }, + }); + + await queryInterface.createTable("Transactions", { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER, + }, + cart_id: { + allowNull: false, + type: Sequelize.INTEGER, + references: { + model: "Cart", + key: "id", + }, + }, + room_id: { + allowNull: false, + type: Sequelize.INTEGER, + references: { + model: "Room", + key: "id", + }, + }, + cycle_count: { + allowNull: false, + type: Sequelize.BOOLEAN, + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE, + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE, + }, + }); + }, + async down(queryInterface: QueryInterface, Sequelize: typeof DataTypes) { + await queryInterface.dropTable("Transactions"); + await queryInterface.dropTable("Carts"); + await queryInterface.dropTable("Rooms"); + }, +}; diff --git a/db/migrations/20240326012343-tertiary_tables.ts b/db/migrations/20240326012343-tertiary_tables.ts new file mode 100644 index 00000000..3e6f8a4e --- /dev/null +++ b/db/migrations/20240326012343-tertiary_tables.ts @@ -0,0 +1,135 @@ +"use strict"; +/** @type {import('sequelize-cli').Migration} */ +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + async up(queryInterface: QueryInterface, Sequelize: typeof DataTypes) { + await queryInterface.createTable("Building_Users", { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER, + }, + building_id: { + allowNull: false, + type: Sequelize.INTEGER, + references: { + model: "Building", + key: "id", + }, + }, + user_id: { + allowNull: false, + type: Sequelize.INTEGER, + references: { + model: "User", + key: "id", + }, + }, + admin: { + allowNull: false, + type: Sequelize.BOOLEAN, + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE, + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE, + }, + }); + + await queryInterface.createTable("Cart_Line_Items", { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER, + }, + cart_id: { + allowNull: false, + type: Sequelize.INTEGER, + references: { + model: "Cart", + key: "id", + }, + }, + item_id: { + allowNull: false, + type: Sequelize.INTEGER, + references: { + model: "Item", + key: "id", + }, + }, + quantity: { + allowNull: false, + type: Sequelize.INTEGER, + }, + consumed: { + allowNull: false, + type: Sequelize.BOOLEAN, + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE, + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE, + }, + }); + + await queryInterface.createTable("Room_Items", { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: Sequelize.INTEGER, + }, + room_id: { + allowNull: false, + type: Sequelize.INTEGER, + references: { + model: "Room", + key: "id", + }, + }, + item_id: { + allowNull: false, + type: Sequelize.INTEGER, + references: { + model: "Item", + key: "id", + }, + }, + quantity: { + allowNull: false, + type: Sequelize.INTEGER, + }, + uom: { + allowNull: false, + type: Sequelize.STRING, + }, + expiry_date: { + allowNull: false, + type: Sequelize.DATE, + }, + createdAt: { + allowNull: false, + type: Sequelize.DATE, + }, + updatedAt: { + allowNull: false, + type: Sequelize.DATE, + }, + }); + }, + async down(queryInterface: QueryInterface, Sequelize: typeof DataTypes) { + await queryInterface.dropTable("Room_Items"); + await queryInterface.dropTable("Cart_Line_Items"); + await queryInterface.dropTable("Building_Users"); + }, +}; From a7609bdf25cccdc6d1dceb86e8cbcf0885588792 Mon Sep 17 00:00:00 2001 From: magiicloud Date: Tue, 26 Mar 2024 09:54:28 +0800 Subject: [PATCH 04/44] amended migration FK reference names to table names --- .sequelizerc | 6 +++--- db/migrations/20240326012147-secondary_tables.ts | 8 ++++---- db/migrations/20240326012343-tertiary_tables.ts | 12 ++++++------ tsconfig.json | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.sequelizerc b/.sequelizerc index 409a4bed..fc065902 100644 --- a/.sequelizerc +++ b/.sequelizerc @@ -2,7 +2,7 @@ const path = require("path"); module.exports = { config: path.resolve("config", "database.js"), - "models-path": path.resolve("db", "models"), - "seeders-path": path.resolve("db", "seeders"), - "migrations-path": path.resolve("db", "migrations"), + "models-path": path.resolve("dist", "models"), + "seeders-path": path.resolve("dist", "seeders"), + "migrations-path": path.resolve("dist", "migrations"), }; diff --git a/db/migrations/20240326012147-secondary_tables.ts b/db/migrations/20240326012147-secondary_tables.ts index f300c374..9662697f 100644 --- a/db/migrations/20240326012147-secondary_tables.ts +++ b/db/migrations/20240326012147-secondary_tables.ts @@ -23,7 +23,7 @@ module.exports = { allowNull: false, type: Sequelize.INTEGER, references: { - model: "Building", + model: "Buildings", key: "id", }, }, @@ -52,7 +52,7 @@ module.exports = { allowNull: false, type: Sequelize.INTEGER, references: { - model: "User", + model: "Users", key: "id", }, }, @@ -77,7 +77,7 @@ module.exports = { allowNull: false, type: Sequelize.INTEGER, references: { - model: "Cart", + model: "Carts", key: "id", }, }, @@ -85,7 +85,7 @@ module.exports = { allowNull: false, type: Sequelize.INTEGER, references: { - model: "Room", + model: "Rooms", key: "id", }, }, diff --git a/db/migrations/20240326012343-tertiary_tables.ts b/db/migrations/20240326012343-tertiary_tables.ts index 3e6f8a4e..f48ff97f 100644 --- a/db/migrations/20240326012343-tertiary_tables.ts +++ b/db/migrations/20240326012343-tertiary_tables.ts @@ -15,7 +15,7 @@ module.exports = { allowNull: false, type: Sequelize.INTEGER, references: { - model: "Building", + model: "Buildings", key: "id", }, }, @@ -23,7 +23,7 @@ module.exports = { allowNull: false, type: Sequelize.INTEGER, references: { - model: "User", + model: "Users", key: "id", }, }, @@ -52,7 +52,7 @@ module.exports = { allowNull: false, type: Sequelize.INTEGER, references: { - model: "Cart", + model: "Carts", key: "id", }, }, @@ -60,7 +60,7 @@ module.exports = { allowNull: false, type: Sequelize.INTEGER, references: { - model: "Item", + model: "Items", key: "id", }, }, @@ -93,7 +93,7 @@ module.exports = { allowNull: false, type: Sequelize.INTEGER, references: { - model: "Room", + model: "Rooms", key: "id", }, }, @@ -101,7 +101,7 @@ module.exports = { allowNull: false, type: Sequelize.INTEGER, references: { - model: "Item", + model: "Items", key: "id", }, }, diff --git a/tsconfig.json b/tsconfig.json index c5b0d2f5..be2908e4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -56,7 +56,7 @@ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ - // "outDir": "./", /* Specify an output folder for all emitted files. */ + "outDir": "./dist" /* Specify an output folder for all emitted files. */, // "removeComments": true, /* Disable emitting comments. */ // "noEmit": true, /* Disable emitting files from a compilation. */ // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ From a53a7443279340e487342bf42e29064878687e74 Mon Sep 17 00:00:00 2001 From: magiicloud Date: Tue, 26 Mar 2024 11:59:11 +0800 Subject: [PATCH 05/44] amended Building migration from item_size to image_size. amended model as well. created primary seed data --- .gitignore | 3 +- .sequelizerc | 6 +- .../20240325145721-initial-migration.ts | 2 +- db/models/Building.ts | 4 +- db/seeders/20240326034148-demo-user.ts | 107 ++++++++++++++++++ tsconfig.json | 2 +- 6 files changed, 116 insertions(+), 8 deletions(-) create mode 100644 db/seeders/20240326034148-demo-user.ts diff --git a/.gitignore b/.gitignore index 3ec544c7..b3eb616a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules/ -.env \ No newline at end of file +.env +dist/ \ No newline at end of file diff --git a/.sequelizerc b/.sequelizerc index fc065902..466f578c 100644 --- a/.sequelizerc +++ b/.sequelizerc @@ -2,7 +2,7 @@ const path = require("path"); module.exports = { config: path.resolve("config", "database.js"), - "models-path": path.resolve("dist", "models"), - "seeders-path": path.resolve("dist", "seeders"), - "migrations-path": path.resolve("dist", "migrations"), + "models-path": path.resolve("dist", "db", "models"), + "seeders-path": path.resolve("dist", "db", "seeders"), + "migrations-path": path.resolve("dist", "db", "migrations"), }; diff --git a/db/migrations/20240325145721-initial-migration.ts b/db/migrations/20240325145721-initial-migration.ts index 7bfcfd5d..b9e014af 100644 --- a/db/migrations/20240325145721-initial-migration.ts +++ b/db/migrations/20240325145721-initial-migration.ts @@ -72,7 +72,7 @@ module.exports = { allowNull: false, type: Sequelize.STRING, }, - item_size: { + image_size: { allowNull: false, type: Sequelize.STRING, }, diff --git a/db/models/Building.ts b/db/models/Building.ts index f25767c9..80091385 100644 --- a/db/models/Building.ts +++ b/db/models/Building.ts @@ -12,7 +12,7 @@ import { BuildingUser } from "./BuildingUser"; interface BuildingAttributes { name: string; - item_size: string; + image_size: string; building_img_url: string; } @@ -25,7 +25,7 @@ export class Building extends Model { name!: string; @Column(DataType.STRING) - item_size!: string; + image_size!: string; @Column(DataType.STRING) building_img_url!: string; diff --git a/db/seeders/20240326034148-demo-user.ts b/db/seeders/20240326034148-demo-user.ts new file mode 100644 index 00000000..0b1258eb --- /dev/null +++ b/db/seeders/20240326034148-demo-user.ts @@ -0,0 +1,107 @@ +"use strict"; +/** @type {import('sequelize-cli').Migration} */ + +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + async up(queryInterface: QueryInterface, Sequelize: typeof DataTypes) { + await queryInterface.bulkInsert("Users", [ + { + name: "Paloma Diamond", + email: "pdiamond@gmail.com", + profile_img_url: null, + createdAt: new Date(), + updatedAt: new Date(), + }, + { + name: "Lynn Kelogg", + email: "lynnk@gmail.com", + profile_img_url: null, + createdAt: new Date(), + updatedAt: new Date(), + }, + { + name: "Lorelai Lynch", + email: "lorelailynch@gmail.com", + profile_img_url: null, + createdAt: new Date(), + updatedAt: new Date(), + }, + ]); + + await queryInterface.bulkInsert("Items", [ + { + serial_num: "0005-84-129-C", + item_name: "clotrimazole 1% CREAM 15G/20G", + par_level: 200, + createdAt: new Date(), + updatedAt: new Date(), + }, + { + serial_num: "0005-84-002-E", + item_name: "chlorhexidine 1% CREAM 15G", + par_level: 100, + createdAt: new Date(), + updatedAt: new Date(), + }, + { + serial_num: "0005-84-082-C", + item_name: "tetracycline 3% SKIN oint 15G", + par_level: 50, + createdAt: new Date(), + updatedAt: new Date(), + }, + { + serial_num: "0005-84-108-K", + item_name: "betamethasone 0.025%/CLIOQUINOL 3% cream 15G", + par_level: 250, + createdAt: new Date(), + updatedAt: new Date(), + }, + { + serial_num: "0000-21-18X-2", + item_name: "etoricoxib <90mg> tab", + par_level: 250, + createdAt: new Date(), + updatedAt: new Date(), + }, + { + serial_num: "0005-84-153-F", + item_name: "KETOPROFEN 30MG PLAST(KEFENTECH)7S/8S/9S", + par_level: 250, + createdAt: new Date(), + updatedAt: new Date(), + }, + { + serial_num: "0004-40-022-F", + item_name: "calcium CARBONATE 625mg tab", + par_level: 350, + createdAt: new Date(), + updatedAt: new Date(), + }, + { + serial_num: "0463-49-68X-9", + item_name: "IRON POLYMALTOSE 100MG CAP", + par_level: 300, + createdAt: new Date(), + updatedAt: new Date(), + }, + ]); + + await queryInterface.bulkInsert("Buildings", [ + { + name: "Health Plus", + image_size: "250px", + building_img_url: "https://www.buildingimgurl.com", + createdAt: new Date(), + updatedAt: new Date(), + }, + ]); + }, + + async down(queryInterface: QueryInterface, Sequelize: typeof DataTypes) { + await queryInterface.bulkDelete("Users", {}, {}); + await queryInterface.bulkDelete("Items", {}, {}); + await queryInterface.bulkDelete("Buildings", {}, {}); + }, +}; diff --git a/tsconfig.json b/tsconfig.json index be2908e4..90da8d6a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -27,7 +27,7 @@ "emitDecoratorMetadata": true, /* Modules */ "module": "commonjs" /* Specify what module code is generated. */, - // "rootDir": "./", /* Specify the root folder within your source files. */ + "rootDir": "./" /* Specify the root folder within your source files. */, // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ From 38d5b206a325e16ed44cd6656ffd561adc90931b Mon Sep 17 00:00:00 2001 From: magiicloud Date: Tue, 26 Mar 2024 12:01:52 +0800 Subject: [PATCH 06/44] changed image url from int to string --- db/migrations/20240325145721-initial-migration.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/migrations/20240325145721-initial-migration.ts b/db/migrations/20240325145721-initial-migration.ts index b9e014af..8c8e1885 100644 --- a/db/migrations/20240325145721-initial-migration.ts +++ b/db/migrations/20240325145721-initial-migration.ts @@ -78,7 +78,7 @@ module.exports = { }, building_img_url: { allowNull: false, - type: Sequelize.INTEGER, + type: Sequelize.STRING, }, createdAt: { allowNull: false, From 65046b711c2ae99df5db5e100f9490c6a0b9ee41 Mon Sep 17 00:00:00 2001 From: magiicloud Date: Tue, 26 Mar 2024 14:25:01 +0800 Subject: [PATCH 07/44] amended the order of async down for primary seed, seeded data for sec and ter seeds --- db/seeders/20240326034148-demo-user.ts | 4 +- db/seeders/20240326050435-secondary-seeds.ts | 63 +++++++++++++ db/seeders/20240326050453-tertiary-seeds.ts | 95 ++++++++++++++++++++ 3 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 db/seeders/20240326050435-secondary-seeds.ts create mode 100644 db/seeders/20240326050453-tertiary-seeds.ts diff --git a/db/seeders/20240326034148-demo-user.ts b/db/seeders/20240326034148-demo-user.ts index 0b1258eb..c03a7833 100644 --- a/db/seeders/20240326034148-demo-user.ts +++ b/db/seeders/20240326034148-demo-user.ts @@ -100,8 +100,8 @@ module.exports = { }, async down(queryInterface: QueryInterface, Sequelize: typeof DataTypes) { - await queryInterface.bulkDelete("Users", {}, {}); - await queryInterface.bulkDelete("Items", {}, {}); await queryInterface.bulkDelete("Buildings", {}, {}); + await queryInterface.bulkDelete("Items", {}, {}); + await queryInterface.bulkDelete("Users", {}, {}); }, }; diff --git a/db/seeders/20240326050435-secondary-seeds.ts b/db/seeders/20240326050435-secondary-seeds.ts new file mode 100644 index 00000000..5ca71d38 --- /dev/null +++ b/db/seeders/20240326050435-secondary-seeds.ts @@ -0,0 +1,63 @@ +"use strict"; +/** @type {import('sequelize-cli').Migration} */ + +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + async up(queryInterface: QueryInterface, Sequelize: typeof DataTypes) { + await queryInterface.bulkInsert("Rooms", [ + { + name: "Main Area", + room_coordinates: "pdiamond@gmail.com", + building_id: 1, + createdAt: new Date(), + updatedAt: new Date(), + }, + { + name: "Store Room", + room_coordinates: "pdiamond@gmail.com", + building_id: 1, + createdAt: new Date(), + updatedAt: new Date(), + }, + { + name: "Satellite", + room_coordinates: "pdiamond@gmail.com", + building_id: 1, + createdAt: new Date(), + updatedAt: new Date(), + }, + ]); + + await queryInterface.bulkInsert("Carts", [ + { + active: true, + user_id: 1, + }, + { + active: false, + user_id: 2, + }, + { + active: false, + user_id: 3, + }, + ]); + + await queryInterface.bulkInsert("Transactions", [ + { + cart_id: 1, + room_id: 1, + cycle_count: false, + createdAt: new Date(), + updatedAt: new Date(), + }, + ]); + }, + + async down(queryInterface: QueryInterface, Sequelize: typeof DataTypes) { + await queryInterface.bulkDelete("Transactions", {}, {}); + await queryInterface.bulkDelete("Carts", {}, {}); + await queryInterface.bulkDelete("Rooms", {}, {}); + }, +}; diff --git a/db/seeders/20240326050453-tertiary-seeds.ts b/db/seeders/20240326050453-tertiary-seeds.ts new file mode 100644 index 00000000..cec1eb8f --- /dev/null +++ b/db/seeders/20240326050453-tertiary-seeds.ts @@ -0,0 +1,95 @@ +"use strict"; +/** @type {import('sequelize-cli').Migration} */ + +import { QueryInterface, DataTypes } from "sequelize"; + +module.exports = { + async up(queryInterface: QueryInterface, Sequelize: typeof DataTypes) { + await queryInterface.bulkInsert("Building_Users", [ + { + building_id: 1, + user_id: 1, + admin: false, + createdAt: new Date(), + updatedAt: new Date(), + }, + { + building_id: 1, + user_id: 2, + admin: false, + createdAt: new Date(), + updatedAt: new Date(), + }, + { + building_id: 1, + user_id: 3, + admin: true, + createdAt: new Date(), + updatedAt: new Date(), + }, + ]); + + await queryInterface.bulkInsert("Cart_Line_Items", [ + { + cart_id: 1, + item_id: 1, + quantity: 20, + consumed: true, + createdAt: new Date(), + updatedAt: new Date(), + }, + { + cart_id: 1, + item_id: 2, + quantity: 30, + consumed: false, + createdAt: new Date(), + updatedAt: new Date(), + }, + { + cart_id: 1, + item_id: 3, + quantity: 25, + consumed: false, + createdAt: new Date(), + updatedAt: new Date(), + }, + ]); + + await queryInterface.bulkInsert("Room_Items", [ + { + room_id: 1, + item_id: 1, + quantity: 20, + uom: "TUBE", + expiry_date: new Date("2024-12-31"), + createdAt: new Date(), + updatedAt: new Date(), + }, + { + room_id: 1, + item_id: 2, + quantity: 30, + uom: "TUBE", + expiry_date: new Date("2024-06-31"), + createdAt: new Date(), + updatedAt: new Date(), + }, + { + room_id: 1, + item_id: 3, + quantity: 25, + uom: "TUBE", + expiry_date: new Date("2025-09-31"), + createdAt: new Date(), + updatedAt: new Date(), + }, + ]); + }, + + async down(queryInterface: QueryInterface, Sequelize: typeof DataTypes) { + await queryInterface.bulkDelete("Room_Items", {}, {}); + await queryInterface.bulkDelete("Cart_Line_Items", {}, {}); + await queryInterface.bulkDelete("Building_Users", {}, {}); + }, +}; From 6be21fb64854d4b033f21942f13cdb914e1dcde2 Mon Sep 17 00:00:00 2001 From: magiicloud Date: Tue, 26 Mar 2024 14:27:01 +0800 Subject: [PATCH 08/44] amended seed data for carts to add created and updated --- db/seeders/20240326050435-secondary-seeds.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/db/seeders/20240326050435-secondary-seeds.ts b/db/seeders/20240326050435-secondary-seeds.ts index 5ca71d38..c1ae48b6 100644 --- a/db/seeders/20240326050435-secondary-seeds.ts +++ b/db/seeders/20240326050435-secondary-seeds.ts @@ -33,14 +33,20 @@ module.exports = { { active: true, user_id: 1, + createdAt: new Date(), + updatedAt: new Date(), }, { active: false, user_id: 2, + createdAt: new Date(), + updatedAt: new Date(), }, { active: false, user_id: 3, + createdAt: new Date(), + updatedAt: new Date(), }, ]); From 748c37dfbe5d3961ddaaeca3905729f59fa75b35 Mon Sep 17 00:00:00 2001 From: magiicloud Date: Tue, 26 Mar 2024 16:37:34 +0800 Subject: [PATCH 09/44] installed cors --- index.js | 1 - package-lock.json | 35 +++++++++++++++++++++++++++++++++++ package.json | 1 + 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 3cad7559..74c05f32 100644 --- a/index.js +++ b/index.js @@ -5,7 +5,6 @@ require("dotenv").config(); const PORT = process.env.PORT; const app = express(); -const { auth } = require("express-oauth2-jwt-bearer"); // Authorization middleware. When used, the Access Token must // exist and be verified against the Auth0 JSON Web Key Set. diff --git a/package-lock.json b/package-lock.json index e1e62c86..8c194153 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "project3-backend-bootcamp", "version": "1.0.0", "dependencies": { + "cors": "^2.8.5", "dotenv": "^16.4.5", "express": "^4.18.1", "express-oauth2-jwt-bearer": "^1.6.0", @@ -636,6 +637,18 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1869,6 +1882,14 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.1.tgz", @@ -3415,6 +3436,15 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, + "cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "requires": { + "object-assign": "^4", + "vary": "^1" + } + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -4355,6 +4385,11 @@ "abbrev": "^2.0.0" } }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + }, "object-inspect": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.1.tgz", diff --git a/package.json b/package.json index 7173cd3e..43baae69 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "start": "nodemon index.js" }, "dependencies": { + "cors": "^2.8.5", "dotenv": "^16.4.5", "express": "^4.18.1", "express-oauth2-jwt-bearer": "^1.6.0", From b947cd6f9452584f271bd8ebe29b7b20dbba4278 Mon Sep 17 00:00:00 2001 From: magiicloud Date: Wed, 27 Mar 2024 00:16:32 +0800 Subject: [PATCH 10/44] rewrite indexjs of models. rewrote migrations models to include tableName and amended createdAt to created_at and updatedAts. rewrote router and controller classes. added scripts in packagejson. --- controllers/itemsController.ts | 13 +++ .../20240325145721-initial-migration.ts | 12 +-- .../20240326012147-secondary_tables.ts | 12 +-- .../20240326012343-tertiary_tables.ts | 12 +-- db/models/Building.ts | 1 + db/models/BuildingUser.ts | 1 + db/models/Cart.ts | 1 + db/models/CartLineItem.ts | 1 + db/models/Item.ts | 1 + db/models/Room.ts | 1 + db/models/RoomItem.ts | 3 +- db/models/Transaction.ts | 1 + db/models/User.ts | 27 +---- db/models/index.ts | 101 ++++++++++-------- db/seeders/20240326034148-demo-user.ts | 48 ++++----- db/seeders/20240326050435-secondary-seeds.ts | 28 ++--- db/seeders/20240326050453-tertiary-seeds.ts | 36 +++---- index.js => index.ts | 17 +-- package-lock.json | 19 ++++ package.json | 6 +- routers/itemsRouter.ts | 12 +++ 21 files changed, 197 insertions(+), 156 deletions(-) create mode 100644 controllers/itemsController.ts rename index.js => index.ts (59%) create mode 100644 routers/itemsRouter.ts diff --git a/controllers/itemsController.ts b/controllers/itemsController.ts new file mode 100644 index 00000000..81221f31 --- /dev/null +++ b/controllers/itemsController.ts @@ -0,0 +1,13 @@ +import { Request, Response } from "express"; +import { Item } from "../db/models"; + +export class ItemsController { + async getAllItems(req: Request, res: Response) { + try { + const output = await Item.findAll(); + return res.json(output); + } catch (err) { + return res.status(400).json({ error: true, msg: (err as Error).message }); + } + } +} diff --git a/db/migrations/20240325145721-initial-migration.ts b/db/migrations/20240325145721-initial-migration.ts index 8c8e1885..ce011d52 100644 --- a/db/migrations/20240325145721-initial-migration.ts +++ b/db/migrations/20240325145721-initial-migration.ts @@ -22,11 +22,11 @@ module.exports = { profile_img_url: { type: Sequelize.STRING, }, - createdAt: { + created_at: { allowNull: false, type: Sequelize.DATE, }, - updatedAt: { + updated_at: { allowNull: false, type: Sequelize.DATE, }, @@ -51,11 +51,11 @@ module.exports = { allowNull: false, type: Sequelize.INTEGER, }, - createdAt: { + created_at: { allowNull: false, type: Sequelize.DATE, }, - updatedAt: { + updated_at: { allowNull: false, type: Sequelize.DATE, }, @@ -80,11 +80,11 @@ module.exports = { allowNull: false, type: Sequelize.STRING, }, - createdAt: { + created_at: { allowNull: false, type: Sequelize.DATE, }, - updatedAt: { + updated_at: { allowNull: false, type: Sequelize.DATE, }, diff --git a/db/migrations/20240326012147-secondary_tables.ts b/db/migrations/20240326012147-secondary_tables.ts index 9662697f..d28469fe 100644 --- a/db/migrations/20240326012147-secondary_tables.ts +++ b/db/migrations/20240326012147-secondary_tables.ts @@ -27,11 +27,11 @@ module.exports = { key: "id", }, }, - createdAt: { + created_at: { allowNull: false, type: Sequelize.DATE, }, - updatedAt: { + updated_at: { allowNull: false, type: Sequelize.DATE, }, @@ -56,11 +56,11 @@ module.exports = { key: "id", }, }, - createdAt: { + created_at: { allowNull: false, type: Sequelize.DATE, }, - updatedAt: { + updated_at: { allowNull: false, type: Sequelize.DATE, }, @@ -93,11 +93,11 @@ module.exports = { allowNull: false, type: Sequelize.BOOLEAN, }, - createdAt: { + created_at: { allowNull: false, type: Sequelize.DATE, }, - updatedAt: { + updated_at: { allowNull: false, type: Sequelize.DATE, }, diff --git a/db/migrations/20240326012343-tertiary_tables.ts b/db/migrations/20240326012343-tertiary_tables.ts index f48ff97f..e76b7c46 100644 --- a/db/migrations/20240326012343-tertiary_tables.ts +++ b/db/migrations/20240326012343-tertiary_tables.ts @@ -31,11 +31,11 @@ module.exports = { allowNull: false, type: Sequelize.BOOLEAN, }, - createdAt: { + created_at: { allowNull: false, type: Sequelize.DATE, }, - updatedAt: { + updated_at: { allowNull: false, type: Sequelize.DATE, }, @@ -72,11 +72,11 @@ module.exports = { allowNull: false, type: Sequelize.BOOLEAN, }, - createdAt: { + created_at: { allowNull: false, type: Sequelize.DATE, }, - updatedAt: { + updated_at: { allowNull: false, type: Sequelize.DATE, }, @@ -117,11 +117,11 @@ module.exports = { allowNull: false, type: Sequelize.DATE, }, - createdAt: { + created_at: { allowNull: false, type: Sequelize.DATE, }, - updatedAt: { + updated_at: { allowNull: false, type: Sequelize.DATE, }, diff --git a/db/models/Building.ts b/db/models/Building.ts index 80091385..8f2ace0e 100644 --- a/db/models/Building.ts +++ b/db/models/Building.ts @@ -17,6 +17,7 @@ interface BuildingAttributes { } @Table({ + tableName: "Buildings", modelName: "Building", underscored: true, }) diff --git a/db/models/BuildingUser.ts b/db/models/BuildingUser.ts index 0328b208..e1c79176 100644 --- a/db/models/BuildingUser.ts +++ b/db/models/BuildingUser.ts @@ -14,6 +14,7 @@ interface BuildingUserAttributes { } @Table({ + tableName: "Building_Users", modelName: "BuildingUser", underscored: true, }) diff --git a/db/models/Cart.ts b/db/models/Cart.ts index 7906fb12..11e8ba78 100644 --- a/db/models/Cart.ts +++ b/db/models/Cart.ts @@ -16,6 +16,7 @@ interface CartAttributes { } @Table({ + tableName: "Carts", modelName: "Cart", underscored: true, }) diff --git a/db/models/CartLineItem.ts b/db/models/CartLineItem.ts index 9e9e5aa2..06da1951 100644 --- a/db/models/CartLineItem.ts +++ b/db/models/CartLineItem.ts @@ -17,6 +17,7 @@ interface CartLineItemAttributes { } @Table({ + tableName: "Cart_Line_Items", modelName: "CartLineItem", underscored: true, }) diff --git a/db/models/Item.ts b/db/models/Item.ts index 177f048a..54f1312c 100644 --- a/db/models/Item.ts +++ b/db/models/Item.ts @@ -10,6 +10,7 @@ interface ItemAttributes { @Table({ modelName: "Item", + tableName: "Items", underscored: true, }) export class Item extends Model { diff --git a/db/models/Room.ts b/db/models/Room.ts index 1b3836f3..a2e14c5d 100644 --- a/db/models/Room.ts +++ b/db/models/Room.ts @@ -18,6 +18,7 @@ interface RoomAttributes { } @Table({ + tableName: "Rooms", modelName: "Room", underscored: true, }) diff --git a/db/models/RoomItem.ts b/db/models/RoomItem.ts index 9743d157..d8da9d43 100644 --- a/db/models/RoomItem.ts +++ b/db/models/RoomItem.ts @@ -18,7 +18,8 @@ interface RoomItemAttributes { } @Table({ - modelName: "Room_Item", + tableName: "Room_Items", + modelName: "RoomItem", underscored: true, }) export class RoomItem extends Model { diff --git a/db/models/Transaction.ts b/db/models/Transaction.ts index cb3c2124..9677e39a 100644 --- a/db/models/Transaction.ts +++ b/db/models/Transaction.ts @@ -14,6 +14,7 @@ interface TransactionAttributes { } @Table({ + tableName: "Transactions", modelName: "Transaction", underscored: true, }) diff --git a/db/models/User.ts b/db/models/User.ts index f56cb941..c5537cb9 100644 --- a/db/models/User.ts +++ b/db/models/User.ts @@ -1,30 +1,4 @@ "use strict"; -// const { Model } = require("sequelize"); -// module.exports = (sequelize, DataTypes) => { -// class User extends Model { -// /** -// * Helper method for defining associations. -// * This method is not a part of Sequelize lifecycle. -// * The `models/index` file will call this method automatically. -// */ -// static associate(models) { -// // define association here -// } -// } -// User.init( -// { -// name: DataTypes.STRING, -// email: DataTypes.STRING, -// profile_img_url: DataTypes.STRING, -// }, -// { -// sequelize, -// modelName: "User", -// } -// ); -// return User; -// }; - import { Table, Column, @@ -43,6 +17,7 @@ interface UserAttributes { } @Table({ + tableName: "Users", modelName: "User", underscored: true, }) diff --git a/db/models/index.ts b/db/models/index.ts index acc0e582..4eb1240e 100644 --- a/db/models/index.ts +++ b/db/models/index.ts @@ -1,52 +1,59 @@ -"use strict"; import { Sequelize } from "sequelize-typescript"; -import * as fs from "fs"; -import * as path from "path"; -import process from "process"; +import { Item } from "./Item"; +import { Cart } from "./Cart"; +import { Building } from "./Building"; +import { BuildingUser } from "./BuildingUser"; +import { CartLineItem } from "./CartLineItem"; +import { Room } from "./Room"; +import { RoomItem } from "./RoomItem"; +import { Transaction } from "./Transaction"; +import { User } from "./User"; +import { Dialect } from "sequelize"; +import dotenv from "dotenv"; +dotenv.config(); -// const process = require("process"); -const basename = path.basename(__filename); -const env = process.env.NODE_ENV || "development"; -const config = require(__dirname + "/../../config/database.js")[env]; -const db: any = {}; - -let sequelize: Sequelize; -if (config.use_env_variable) { - const databaseUrl = process.env[config.use_env_variable] as string; - sequelize = new Sequelize(databaseUrl, config); - // sequelize = new Sequelize(process.env[config.use_env_variable], config); -} else { - sequelize = new Sequelize( - config.database, - config.username, - config.password, - config - ); -} - -// Read all model files and import them -fs.readdirSync(__dirname) - .filter((file) => { - return ( - file.indexOf(".") !== 0 && - file !== basename && - file.slice(-3) === ".ts" && - file.indexOf(".test.ts") === -1 - ); - }) - .forEach((file) => { - const model = require(path.join(__dirname, file)).default; - db[model.name] = model; - }); - -Object.keys(db).forEach((modelName) => { - if (db[modelName].associate) { - db[modelName].associate(db); - } +const sequelize = new Sequelize({ + username: process.env.DB_USERNAME, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + host: process.env.DB_HOST, + dialect: process.env.DB_DIALECT as Dialect, + models: [ + Building, + BuildingUser, + CartLineItem, + Item, + Cart, + Room, + RoomItem, + Transaction, + User, + ], }); -// Export sequelize instance and models -db.sequelize = sequelize; -db.Sequelize = Sequelize; +// Attach models to Sequelize instance +sequelize.addModels([ + Building, + BuildingUser, + CartLineItem, + Item, + Cart, + Room, + RoomItem, + Transaction, + User, +]); -module.exports = db; +// Export model instance +export { + sequelize, + Item, + Cart, + Building, + BuildingUser, + CartLineItem, + Room, + RoomItem, + Transaction, + User, +}; diff --git a/db/seeders/20240326034148-demo-user.ts b/db/seeders/20240326034148-demo-user.ts index c03a7833..4a15cfc5 100644 --- a/db/seeders/20240326034148-demo-user.ts +++ b/db/seeders/20240326034148-demo-user.ts @@ -10,22 +10,22 @@ module.exports = { name: "Paloma Diamond", email: "pdiamond@gmail.com", profile_img_url: null, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, { name: "Lynn Kelogg", email: "lynnk@gmail.com", profile_img_url: null, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, { name: "Lorelai Lynch", email: "lorelailynch@gmail.com", profile_img_url: null, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, ]); @@ -34,57 +34,57 @@ module.exports = { serial_num: "0005-84-129-C", item_name: "clotrimazole 1% CREAM 15G/20G", par_level: 200, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, { serial_num: "0005-84-002-E", item_name: "chlorhexidine 1% CREAM 15G", par_level: 100, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, { serial_num: "0005-84-082-C", item_name: "tetracycline 3% SKIN oint 15G", par_level: 50, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, { serial_num: "0005-84-108-K", item_name: "betamethasone 0.025%/CLIOQUINOL 3% cream 15G", par_level: 250, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, { serial_num: "0000-21-18X-2", item_name: "etoricoxib <90mg> tab", par_level: 250, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, { serial_num: "0005-84-153-F", item_name: "KETOPROFEN 30MG PLAST(KEFENTECH)7S/8S/9S", par_level: 250, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, { serial_num: "0004-40-022-F", item_name: "calcium CARBONATE 625mg tab", par_level: 350, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, { serial_num: "0463-49-68X-9", item_name: "IRON POLYMALTOSE 100MG CAP", par_level: 300, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, ]); @@ -93,8 +93,8 @@ module.exports = { name: "Health Plus", image_size: "250px", building_img_url: "https://www.buildingimgurl.com", - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, ]); }, diff --git a/db/seeders/20240326050435-secondary-seeds.ts b/db/seeders/20240326050435-secondary-seeds.ts index c1ae48b6..20e70353 100644 --- a/db/seeders/20240326050435-secondary-seeds.ts +++ b/db/seeders/20240326050435-secondary-seeds.ts @@ -10,22 +10,22 @@ module.exports = { name: "Main Area", room_coordinates: "pdiamond@gmail.com", building_id: 1, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, { name: "Store Room", room_coordinates: "pdiamond@gmail.com", building_id: 1, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, { name: "Satellite", room_coordinates: "pdiamond@gmail.com", building_id: 1, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, ]); @@ -33,20 +33,20 @@ module.exports = { { active: true, user_id: 1, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, { active: false, user_id: 2, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, { active: false, user_id: 3, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, ]); @@ -55,8 +55,8 @@ module.exports = { cart_id: 1, room_id: 1, cycle_count: false, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, ]); }, diff --git a/db/seeders/20240326050453-tertiary-seeds.ts b/db/seeders/20240326050453-tertiary-seeds.ts index cec1eb8f..f972634c 100644 --- a/db/seeders/20240326050453-tertiary-seeds.ts +++ b/db/seeders/20240326050453-tertiary-seeds.ts @@ -10,22 +10,22 @@ module.exports = { building_id: 1, user_id: 1, admin: false, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, { building_id: 1, user_id: 2, admin: false, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, { building_id: 1, user_id: 3, admin: true, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, ]); @@ -35,24 +35,24 @@ module.exports = { item_id: 1, quantity: 20, consumed: true, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, { cart_id: 1, item_id: 2, quantity: 30, consumed: false, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, { cart_id: 1, item_id: 3, quantity: 25, consumed: false, - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, ]); @@ -63,8 +63,8 @@ module.exports = { quantity: 20, uom: "TUBE", expiry_date: new Date("2024-12-31"), - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, { room_id: 1, @@ -72,8 +72,8 @@ module.exports = { quantity: 30, uom: "TUBE", expiry_date: new Date("2024-06-31"), - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, { room_id: 1, @@ -81,8 +81,8 @@ module.exports = { quantity: 25, uom: "TUBE", expiry_date: new Date("2025-09-31"), - createdAt: new Date(), - updatedAt: new Date(), + created_at: new Date(), + updated_at: new Date(), }, ]); }, diff --git a/index.js b/index.ts similarity index 59% rename from index.js rename to index.ts index 74c05f32..4b296f6d 100644 --- a/index.js +++ b/index.ts @@ -1,7 +1,10 @@ -const cors = require("cors"); -const express = require("express"); -const { auth } = require("express-oauth2-jwt-bearer"); -require("dotenv").config(); +import cors from "cors"; +import express from "express"; +import { auth } from "express-oauth2-jwt-bearer"; +import dotenv from "dotenv"; +import { ItemsRouter } from "./routers/itemsRouter"; + +dotenv.config(); const PORT = process.env.PORT; const app = express(); @@ -16,9 +19,9 @@ const checkJwt = auth({ // Enable CORS access to this server app.use(cors()); -app.get("/", (req, res) => { - res.send("Hello, World!"); -}); +// Routers +const itemsRouter = new ItemsRouter().routes(); +app.use(itemsRouter); app.listen(PORT, () => { console.log(`Express app listening on port ${PORT}!`); diff --git a/package-lock.json b/package-lock.json index 8c194153..b663bd0b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "sequelize-typescript": "^2.1.6" }, "devDependencies": { + "@types/cors": "^2.8.17", "@types/express": "^4.17.21", "@types/node": "^20.11.30", "@types/validator": "^13.11.9", @@ -243,6 +244,15 @@ "@types/node": "*" } }, + "node_modules/@types/cors": { + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/debug": { "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", @@ -3112,6 +3122,15 @@ "@types/node": "*" } }, + "@types/cors": { + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/debug": { "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", diff --git a/package.json b/package.json index 43baae69..98f73210 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,10 @@ "name": "project3-backend-bootcamp", "version": "1.0.0", "scripts": { - "start": "nodemon index.js" + "build": "rm -rf ./dist && npx tsc", + "start": "nodemon ./dist/index.js", + "dev": "npx tsc -w & nodemon ./dist/index.js", + "clean": "npx tsc --build --clean" }, "dependencies": { "cors": "^2.8.5", @@ -15,6 +18,7 @@ "sequelize-typescript": "^2.1.6" }, "devDependencies": { + "@types/cors": "^2.8.17", "@types/express": "^4.17.21", "@types/node": "^20.11.30", "@types/validator": "^13.11.9", diff --git a/routers/itemsRouter.ts b/routers/itemsRouter.ts new file mode 100644 index 00000000..2fee23c6 --- /dev/null +++ b/routers/itemsRouter.ts @@ -0,0 +1,12 @@ +import { ItemsController } from "../controllers/itemsController"; +import { Router } from "express"; + +const itemsController = new ItemsController(); + +export class ItemsRouter { + routes = () => { + const router = Router(); + router.get("/allitems", itemsController.getAllItems); + return router; + }; +} From 9c61c4b786f0805b7636f431c14712b329399a8a Mon Sep 17 00:00:00 2001 From: magiicloud Date: Wed, 27 Mar 2024 15:04:04 +0800 Subject: [PATCH 11/44] amended itemsController to show data from RoomItem and Room --- controllers/itemsController.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/controllers/itemsController.ts b/controllers/itemsController.ts index 81221f31..36dcf43f 100644 --- a/controllers/itemsController.ts +++ b/controllers/itemsController.ts @@ -1,10 +1,17 @@ import { Request, Response } from "express"; -import { Item } from "../db/models"; +import { Item, RoomItem, Room } from "../db/models"; export class ItemsController { async getAllItems(req: Request, res: Response) { try { - const output = await Item.findAll(); + const output = await Item.findAll({ + include: [ + { + model: RoomItem, + include: [{ model: Room, attributes: ["name"] }], + }, + ], + }); return res.json(output); } catch (err) { return res.status(400).json({ error: true, msg: (err as Error).message }); From 8899c38263f050af307ef9ed5f71dd94e724be3d Mon Sep 17 00:00:00 2001 From: patrickkok Date: Sat, 30 Mar 2024 20:17:34 +0800 Subject: [PATCH 12/44] Edit room model params, create building router and controller to send building and room data to frontend --- controllers/buildingController.ts | 38 + .../20240326012147-secondary_tables.ts | 16 +- db/models/Building.ts | 2 +- db/models/Room.ts | 13 +- db/seeders/20240326034148-demo-user.ts | 3 +- db/seeders/20240326050435-secondary-seeds.ts | 19 +- index.ts | 4 + package-lock.json | 3112 ++++------------- routers/buildingsRouter.ts | 13 + 9 files changed, 702 insertions(+), 2518 deletions(-) create mode 100644 controllers/buildingController.ts create mode 100644 routers/buildingsRouter.ts diff --git a/controllers/buildingController.ts b/controllers/buildingController.ts new file mode 100644 index 00000000..4228304b --- /dev/null +++ b/controllers/buildingController.ts @@ -0,0 +1,38 @@ +import { Request, Response } from "express"; +import { Building, BuildingUser, Room } from "../db/models"; + +export class BuildingsController { + async getAllBuildings(req: Request, res: Response) { + try { + const output = await Building.findAll({ + include: [ + { + model: Room, + }, + ], + }); + return res.json(output); + } catch (err) { + return res.status(400).json({ error: true, msg: (err as Error).message }); + } + } + + async AddNewBuilding(req: Request, res: Response) { + const building = req.body.building; + const rooms = req.body.rooms; + try { + const newBuilding = await Building.create(building); + const newRooms: number[] = []; + rooms.map(async (obj: Object) => { + const newRoom = { ...obj }; + newRoom["building_id" as keyof Object] = newBuilding.id; + const newRoomInstance = await rooms.create(newRoom); + newRooms.push(newRoomInstance.id); + }); + // const newBuildingRooms = newBuilding.setRooms(newRooms); + return res.json(newBuilding); + } catch (err) { + return res.status(400).json({ error: true, msg: err }); + } + } +} diff --git a/db/migrations/20240326012147-secondary_tables.ts b/db/migrations/20240326012147-secondary_tables.ts index d28469fe..bbce5ccd 100644 --- a/db/migrations/20240326012147-secondary_tables.ts +++ b/db/migrations/20240326012147-secondary_tables.ts @@ -15,9 +15,21 @@ module.exports = { allowNull: false, type: Sequelize.STRING, }, - room_coordinates: { + left: { allowNull: false, - type: Sequelize.STRING, + type: Sequelize.FLOAT, + }, + top: { + allowNull: false, + type: Sequelize.FLOAT, + }, + height: { + allowNull: false, + type: Sequelize.FLOAT, + }, + width: { + allowNull: false, + type: Sequelize.FLOAT, }, building_id: { allowNull: false, diff --git a/db/models/Building.ts b/db/models/Building.ts index 8f2ace0e..2cd13a21 100644 --- a/db/models/Building.ts +++ b/db/models/Building.ts @@ -35,6 +35,6 @@ export class Building extends Model { @HasMany(() => Room) rooms!: Room[]; - @BelongsToMany(() => User, () => BuildingUser) + @HasMany(() => BuildingUser) users!: User[]; } diff --git a/db/models/Room.ts b/db/models/Room.ts index a2e14c5d..5a38cc1e 100644 --- a/db/models/Room.ts +++ b/db/models/Room.ts @@ -26,8 +26,17 @@ export class Room extends Model { @Column(DataType.STRING) name!: string; - @Column(DataType.STRING) - room_coordinates!: string; + @Column(DataType.FLOAT) + left!: Float64Array; + + @Column(DataType.FLOAT) + top!: Float64Array; + + @Column(DataType.FLOAT) + height!: Float64Array; + + @Column(DataType.FLOAT) + width!: Float64Array; @ForeignKey(() => Building) @Column(DataType.INTEGER) diff --git a/db/seeders/20240326034148-demo-user.ts b/db/seeders/20240326034148-demo-user.ts index 4a15cfc5..944d62f9 100644 --- a/db/seeders/20240326034148-demo-user.ts +++ b/db/seeders/20240326034148-demo-user.ts @@ -92,7 +92,8 @@ module.exports = { { name: "Health Plus", image_size: "250px", - building_img_url: "https://www.buildingimgurl.com", + building_img_url: + "https://firebasestorage.googleapis.com/v0/b/rocket-academy-proj3.appspot.com/o/floorplans%2FWorkplace%201?alt=media&token=43b7e8a1-b4dd-4059-9f03-96b1d87cc0fe", created_at: new Date(), updated_at: new Date(), }, diff --git a/db/seeders/20240326050435-secondary-seeds.ts b/db/seeders/20240326050435-secondary-seeds.ts index 20e70353..f3d2d738 100644 --- a/db/seeders/20240326050435-secondary-seeds.ts +++ b/db/seeders/20240326050435-secondary-seeds.ts @@ -7,22 +7,31 @@ module.exports = { async up(queryInterface: QueryInterface, Sequelize: typeof DataTypes) { await queryInterface.bulkInsert("Rooms", [ { - name: "Main Area", - room_coordinates: "pdiamond@gmail.com", + name: "Bedroom", + left: 12, + top: 17, + height: 30, + width: 17, building_id: 1, created_at: new Date(), updated_at: new Date(), }, { name: "Store Room", - room_coordinates: "pdiamond@gmail.com", + left: 12, + top: 49, + height: 23.5, + width: 7, building_id: 1, created_at: new Date(), updated_at: new Date(), }, { - name: "Satellite", - room_coordinates: "pdiamond@gmail.com", + name: "Kitchen", + left: 68, + top: 58, + height: 27, + width: 21, building_id: 1, created_at: new Date(), updated_at: new Date(), diff --git a/index.ts b/index.ts index 4b296f6d..e03553cc 100644 --- a/index.ts +++ b/index.ts @@ -3,6 +3,7 @@ import express from "express"; import { auth } from "express-oauth2-jwt-bearer"; import dotenv from "dotenv"; import { ItemsRouter } from "./routers/itemsRouter"; +import { BuildingsRouter } from "./routers/buildingsRouter"; dotenv.config(); @@ -21,7 +22,10 @@ app.use(cors()); // Routers const itemsRouter = new ItemsRouter().routes(); +const buildingsRouter = new BuildingsRouter().routes(); + app.use(itemsRouter); +app.use(buildingsRouter); app.listen(PORT, () => { console.log(`Express app listening on port ${PORT}!`); diff --git a/package-lock.json b/package-lock.json index b663bd0b..aae2cefd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,7 +1,7 @@ { "name": "project3-backend-bootcamp", "version": "1.0.0", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -27,16 +27,49 @@ "typescript": "^5.4.3" } }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", + "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", - "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.2", - "globals": "^13.15.0", + "espree": "^9.6.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -45,72 +78,51 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, - "dependencies": { - "ms": "2.1.2" - }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@eslint/eslintrc/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", + "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, - "node_modules/@humanwhocodes/config-array/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, - "dependencies": { - "ms": "2.1.2" - }, "engines": { - "node": ">=6.0" + "node": ">=12.22" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/config-array/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", "dev": true }, "node_modules/@isaacs/cliui": { @@ -209,6 +221,41 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@one-ini/wasm": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", @@ -303,9 +350,9 @@ "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" }, "node_modules/@types/node": { - "version": "20.11.30", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.30.tgz", - "integrity": "sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==", + "version": "20.12.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.2.tgz", + "integrity": "sha512-zQ0NYO87hyN6Xrclcqp7f8ZbXNbRfoGWNcMvHTPQp9UUrwI0mI7XBz+cu7/W6/VClYo2g63B0cjull/srU7LgQ==", "dependencies": { "undici-types": "~5.26.4" } @@ -348,6 +395,12 @@ "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.9.tgz", "integrity": "sha512-FCTsikRozryfayPuiI46QzH3fnrOoctTjvOYZkho9BTFLCOZ2rgZJHMOVgCOfttjPJcgOx52EpkY0CMfy87MIw==" }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/abbrev": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", @@ -370,9 +423,9 @@ } }, "node_modules/acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -462,20 +515,20 @@ "dev": true }, "node_modules/body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dependencies": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.10.3", - "raw-body": "2.5.1", + "qs": "6.11.0", + "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" }, @@ -484,6 +537,19 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -510,12 +576,18 @@ } }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -603,7 +675,7 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/config-chain": { "version": "1.1.13", @@ -627,17 +699,17 @@ } }, "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "engines": { "node": ">= 0.6" } }, "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "engines": { "node": ">= 0.6" } @@ -645,7 +717,7 @@ "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, "node_modules/cors": { "version": "2.8.5", @@ -687,11 +759,19 @@ } }, "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { - "ms": "2.0.0" + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/deep-is": { @@ -700,6 +780,22 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -796,7 +892,7 @@ "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/emoji-regex": { "version": "8.0.0", @@ -807,11 +903,30 @@ "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "engines": { "node": ">= 0.8" } }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es5-ext": { "version": "0.10.64", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", @@ -876,7 +991,7 @@ "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" }, "node_modules/escape-string-regexp": { "version": "4.0.0", @@ -891,46 +1006,49 @@ } }, "node_modules/eslint": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.16.0.tgz", - "integrity": "sha512-MBndsoXY/PeVTDJeWsYj7kLZ5hQpJOfMYLsF6LicLHQWbRDG19lK5jOix4DPl8yY4SUFcE3txy86OzFLWT+yoA==", - "dev": true, - "dependencies": { - "@eslint/eslintrc": "^1.3.0", - "@humanwhocodes/config-array": "^0.9.2", - "ajv": "^6.10.0", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.2", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" @@ -943,9 +1061,9 @@ } }, "node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -953,67 +1071,23 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "node_modules/esniff": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", @@ -1030,23 +1104,26 @@ } }, "node_modules/espree": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", - "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { - "acorn": "^8.7.1", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -1088,7 +1165,7 @@ "node_modules/etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "engines": { "node": ">= 0.6" } @@ -1104,16 +1181,16 @@ } }, "node_modules/express": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", - "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.0", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -1129,7 +1206,7 @@ "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.10.3", + "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "0.18.0", @@ -1155,6 +1232,19 @@ "node": "^12.19.0 || ^14.15.0 || ^16.13.0 || ^18.12.0 || ^20.2.0" } }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, "node_modules/ext": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", @@ -1179,9 +1269,18 @@ "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, + "node_modules/fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -1211,13 +1310,43 @@ "node": ">= 0.8" } }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", "dev": true, "dependencies": { - "flatted": "^3.1.0", + "flatted": "^3.2.9", + "keyv": "^4.5.3", "rimraf": "^3.0.2" }, "engines": { @@ -1225,9 +1354,9 @@ } }, "node_modules/flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, "node_modules/foreground-child": { @@ -1257,7 +1386,7 @@ "node_modules/fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "engines": { "node": ">= 0.6" } @@ -1280,7 +1409,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/function-bind": { "version": "1.1.2", @@ -1290,12 +1419,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -1306,13 +1429,18 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1351,9 +1479,9 @@ } }, "node_modules/globals": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", - "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -1365,22 +1493,28 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true }, "node_modules/has-flag": { "version": "4.0.0", @@ -1391,10 +1525,32 @@ "node": ">=8" } }, - "node_modules/has-symbols": { + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "engines": { "node": ">= 0.4" }, @@ -1406,7 +1562,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -1441,9 +1596,9 @@ } }, "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { "node": ">= 4" @@ -1468,7 +1623,7 @@ "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "engines": { "node": ">=0.8.19" @@ -1485,7 +1640,7 @@ "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -1525,7 +1680,7 @@ "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "engines": { "node": ">=0.10.0" @@ -1552,6 +1707,15 @@ "node": ">=0.10.0" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-promise": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", @@ -1561,7 +1725,7 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, "node_modules/jackspeak": { @@ -1621,16 +1785,16 @@ } }, "node_modules/js-beautify/node_modules/glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", + "version": "10.3.12", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz", + "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==", "dev": true, "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", + "jackspeak": "^2.3.6", "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" + "minipass": "^7.0.4", + "path-scurry": "^1.10.2" }, "bin": { "glob": "dist/esm/bin.mjs" @@ -1643,9 +1807,9 @@ } }, "node_modules/js-beautify/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -1678,6 +1842,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -1687,7 +1857,7 @@ "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "node_modules/jsonfile": { @@ -1702,6 +1872,15 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -1715,6 +1894,21 @@ "node": ">= 0.8.0" } }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -1749,7 +1943,7 @@ "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "engines": { "node": ">= 0.6" } @@ -1773,12 +1967,12 @@ "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "engines": { "node": ">= 0.6" } @@ -1853,14 +2047,14 @@ } }, "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, "node_modules/negotiator": { @@ -1901,9 +2095,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.1.tgz", - "integrity": "sha512-Y/jF6vnvEtOPGiKD1+q+X0CiUYRQtEHp89MLLUJ7TUivtH8Ugn2+3A7Rynqk7BRsAoqeOQWnFnjpDrKSxDgIGA==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -1922,28 +2116,58 @@ "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dependencies": { "wrappy": "1" } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/packet-reader": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", @@ -1969,10 +2193,19 @@ "node": ">= 0.8" } }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "engines": { "node": ">=0.10.0" } @@ -1993,12 +2226,12 @@ "dev": true }, "node_modules/path-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz", + "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==", "dev": true, "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", + "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { @@ -2020,7 +2253,7 @@ "node_modules/path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, "node_modules/pg": { "version": "8.11.3", @@ -2168,18 +2401,18 @@ } }, "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "engines": { "node": ">=6" } }, "node_modules/qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dependencies": { "side-channel": "^1.0.4" }, @@ -2190,6 +2423,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "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/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -2199,9 +2452,9 @@ } }, "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", @@ -2213,21 +2466,9 @@ } }, "node_modules/reflect-metadata": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz", - "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==" - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==" }, "node_modules/require-directory": { "version": "2.1.1", @@ -2269,6 +2510,16 @@ "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-7.0.4.tgz", "integrity": "sha512-XgmCoxKWkDofwH8WddD0w85ZfqYz+ZHlr5yo+3YUCfycWawU56T5ckWXsScsj5B8tqUcIG67DxXByo3VUgiAdA==" }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -2284,6 +2535,29 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -2345,15 +2619,28 @@ "node": ">= 0.8.0" } }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + }, "node_modules/send/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/sequelize": { - "version": "6.37.1", - "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.37.1.tgz", - "integrity": "sha512-vIKKzQ9dGp2aBOxQRD1FmUYViuQiKXSJ8yah8TsaBx4U3BokJt+Y2A0qz2C4pj08uX59qpWxRqSLEfRmVOEgQw==", + "version": "6.37.2", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.37.2.tgz", + "integrity": "sha512-bnb7swGANONXCTrVyebpOOZssLwQrVkYX2tcC6qOIvH+P+OhsoMBi7c3GXI5bC+Z4b4tOl+kQy6yeqLCZ1YQAQ==", "funding": [ { "type": "opencollective", @@ -2477,27 +2764,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/sequelize/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/sequelize/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "node_modules/serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", @@ -2512,6 +2778,22 @@ "node": ">= 0.8.0" } }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -2539,13 +2821,17 @@ } }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2672,7 +2958,7 @@ "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, "node_modules/timers-ext": { @@ -2782,7 +3068,7 @@ "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "engines": { "node": ">= 0.8" } @@ -2799,7 +3085,7 @@ "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "engines": { "node": ">= 0.4.0" } @@ -2812,12 +3098,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, "node_modules/validator": { "version": "13.11.0", "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", @@ -2829,7 +3109,7 @@ "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "engines": { "node": ">= 0.8" } @@ -2857,15 +3137,6 @@ "@types/node": "*" } }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -2904,7 +3175,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/xtend": { "version": "4.0.2", @@ -2954,2191 +3225,18 @@ "engines": { "node": ">=10" } - } - }, - "dependencies": { - "@eslint/eslintrc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", - "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.3.2", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, - "requires": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + "engines": { + "node": ">=10" }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true - }, - "ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true - }, - "emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "requires": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - } - }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - }, - "wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "requires": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - } - } - } - }, - "@one-ini/wasm": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz", - "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==", - "dev": true - }, - "@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true - }, - "@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "dev": true, - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/cors": { - "version": "2.8.17", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", - "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "requires": { - "@types/ms": "*" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } - }, - "@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "dev": true, - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.17.43", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz", - "integrity": "sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", - "dev": true - }, - "@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true - }, - "@types/ms": { - "version": "0.7.34", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", - "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" - }, - "@types/node": { - "version": "20.11.30", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.30.tgz", - "integrity": "sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==", - "requires": { - "undici-types": "~5.26.4" - } - }, - "@types/qs": { - "version": "6.9.14", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.14.tgz", - "integrity": "sha512-5khscbd3SwWMhFqylJBLQ0zIu7c1K6Vz0uBIt915BI3zV0q1nfjRQD3RqSBcPaO6PHEF4ov/t9y89fSiyThlPA==", - "dev": true - }, - "@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true - }, - "@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "dev": true, - "requires": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "@types/serve-static": { - "version": "1.15.5", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.5.tgz", - "integrity": "sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ==", - "dev": true, - "requires": { - "@types/http-errors": "*", - "@types/mime": "*", - "@types/node": "*" - } - }, - "@types/validator": { - "version": "13.11.9", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.9.tgz", - "integrity": "sha512-FCTsikRozryfayPuiI46QzH3fnrOoctTjvOYZkho9BTFLCOZ2rgZJHMOVgCOfttjPJcgOx52EpkY0CMfy87MIw==" - }, - "abbrev": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", - "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", - "dev": true - }, - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "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" - } - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.10.3", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "buffer-writer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", - "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==" - }, - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "cli-color": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.4.tgz", - "integrity": "sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==", - "dev": true, - "requires": { - "d": "^1.0.1", - "es5-ext": "^0.10.64", - "es6-iterator": "^2.0.3", - "memoizee": "^0.4.15", - "timers-ext": "^0.1.7" - } - }, - "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-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" - } - }, - "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 - }, - "commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "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==", - "dev": true, - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, - "content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "requires": { - "safe-buffer": "5.2.1" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "d": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", - "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", - "dev": true, - "requires": { - "es5-ext": "^0.10.64", - "type": "^2.7.2" - } - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dotenv": { - "version": "16.4.5", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", - "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==" - }, - "dottie": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.6.tgz", - "integrity": "sha512-iGCHkfUc5kFekGiqhe8B/mdaurD+lakO9txNnTvKtA6PISrw86LgqHvRzWYPyoE2Ph5aMIrCw9/uko6XHTKCwA==" - }, - "eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, - "editorconfig": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz", - "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==", - "dev": true, - "requires": { - "@one-ini/wasm": "0.1.1", - "commander": "^10.0.0", - "minimatch": "9.0.1", - "semver": "^7.5.3" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "minimatch": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz", - "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "es5-ext": { - "version": "0.10.64", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", - "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", - "dev": true, - "requires": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "esniff": "^2.0.1", - "next-tick": "^1.1.0" - } - }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "es6-symbol": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", - "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", - "dev": true, - "requires": { - "d": "^1.0.2", - "ext": "^1.7.0" - } - }, - "es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, - "escalade": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", - "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.16.0.tgz", - "integrity": "sha512-MBndsoXY/PeVTDJeWsYj7kLZ5hQpJOfMYLsF6LicLHQWbRDG19lK5jOix4DPl8yY4SUFcE3txy86OzFLWT+yoA==", - "dev": true, - "requires": { - "@eslint/eslintrc": "^1.3.0", - "@humanwhocodes/config-array": "^0.9.2", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.2", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, - "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - }, - "esniff": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", - "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", - "dev": true, - "requires": { - "d": "^1.0.1", - "es5-ext": "^0.10.62", - "event-emitter": "^0.3.5", - "type": "^2.7.2" - } - }, - "espree": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", - "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", - "dev": true, - "requires": { - "acorn": "^8.7.1", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - } - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", - "dev": true, - "requires": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "express": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", - "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.0", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.10.3", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - } - }, - "express-oauth2-jwt-bearer": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/express-oauth2-jwt-bearer/-/express-oauth2-jwt-bearer-1.6.0.tgz", - "integrity": "sha512-HXnez7vocYlOqlfF3ozPcf/WE3zxT7zfUNfeg5FHJnvNwhBYlNXiPOvuCtBalis8xcigvwtInzEKhBuH87+9ug==", - "requires": { - "jose": "^4.13.1" - } - }, - "ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "dev": true, - "requires": { - "type": "^2.7.2" - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - } - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", - "dev": true - }, - "foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - } - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "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 - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "globals": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", - "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - }, - "hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "requires": { - "function-bind": "^1.1.2" - } - }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflection": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.4.tgz", - "integrity": "sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" - }, - "is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dev": true, - "requires": { - "hasown": "^2.0.0" - } - }, - "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 - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-glob": { - "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" - } - }, - "is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", - "dev": true, - "requires": { - "@isaacs/cliui": "^8.0.2", - "@pkgjs/parseargs": "^0.11.0" - } - }, - "jose": { - "version": "4.15.5", - "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", - "integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==" - }, - "js-beautify": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.1.tgz", - "integrity": "sha512-ESjNzSlt/sWE8sciZH8kBF8BPlwXPwhR6pWKAw8bw4Bwj+iZcnKW6ONWUutJ7eObuBZQpiIb8S7OYspWrKt7rA==", - "dev": true, - "requires": { - "config-chain": "^1.1.13", - "editorconfig": "^1.0.4", - "glob": "^10.3.3", - "js-cookie": "^3.0.5", - "nopt": "^7.2.0" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "glob": { - "version": "10.3.10", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", - "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", - "dev": true, - "requires": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - } - }, - "minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "js-cookie": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz", - "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "lru-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", - "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", - "dev": true, - "requires": { - "es5-ext": "~0.10.2" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "memoizee": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", - "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", - "dev": true, - "requires": { - "d": "^1.0.1", - "es5-ext": "^0.10.53", - "es6-weak-map": "^2.0.3", - "event-emitter": "^0.3.5", - "is-promise": "^2.2.2", - "lru-queue": "^0.1.0", - "next-tick": "^1.1.0", - "timers-ext": "^0.1.7" - } - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { - "mime-db": "1.52.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", - "dev": true - }, - "moment": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", - "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==" - }, - "moment-timezone": { - "version": "0.5.45", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz", - "integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==", - "requires": { - "moment": "^2.29.4" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" - }, - "next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true - }, - "nopt": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.0.tgz", - "integrity": "sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA==", - "dev": true, - "requires": { - "abbrev": "^2.0.0" - } - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" - }, - "object-inspect": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.1.tgz", - "integrity": "sha512-Y/jF6vnvEtOPGiKD1+q+X0CiUYRQtEHp89MLLUJ7TUivtH8Ugn2+3A7Rynqk7BRsAoqeOQWnFnjpDrKSxDgIGA==" - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "packet-reader": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", - "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-scurry": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", - "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", - "dev": true, - "requires": { - "lru-cache": "^9.1.1 || ^10.0.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", - "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", - "dev": true - } - } - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "pg": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.3.tgz", - "integrity": "sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==", - "requires": { - "buffer-writer": "2.0.0", - "packet-reader": "1.0.0", - "pg-cloudflare": "^1.1.1", - "pg-connection-string": "^2.6.2", - "pg-pool": "^3.6.1", - "pg-protocol": "^1.6.0", - "pg-types": "^2.1.0", - "pgpass": "1.x" - } - }, - "pg-cloudflare": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", - "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", - "optional": true - }, - "pg-connection-string": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", - "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" - }, - "pg-int8": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", - "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" - }, - "pg-pool": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz", - "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==", - "requires": {} - }, - "pg-protocol": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", - "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" - }, - "pg-types": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", - "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", - "requires": { - "pg-int8": "1.0.1", - "postgres-array": "~2.0.0", - "postgres-bytea": "~1.0.0", - "postgres-date": "~1.0.4", - "postgres-interval": "^1.1.0" - } - }, - "pgpass": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", - "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", - "requires": { - "split2": "^4.1.0" - } - }, - "postgres-array": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", - "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" - }, - "postgres-bytea": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", - "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==" - }, - "postgres-date": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", - "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==" - }, - "postgres-interval": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", - "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", - "requires": { - "xtend": "^4.0.0" - } - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", - "dev": true - }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "requires": { - "side-channel": "^1.0.4" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "reflect-metadata": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.1.tgz", - "integrity": "sha512-i5lLI6iw9AU3Uu4szRNPPEkomnkjRTaVt9hy/bn5g/oSzekBSMeLZblcjP74AW0vBabqERLLIrz+gR8QYR54Tw==" - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "requires": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "retry-as-promised": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-7.0.4.tgz", - "integrity": "sha512-XgmCoxKWkDofwH8WddD0w85ZfqYz+ZHlr5yo+3YUCfycWawU56T5ckWXsScsj5B8tqUcIG67DxXByo3VUgiAdA==" - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "semver": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", - "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "requires": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "dependencies": { - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "sequelize": { - "version": "6.37.1", - "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.37.1.tgz", - "integrity": "sha512-vIKKzQ9dGp2aBOxQRD1FmUYViuQiKXSJ8yah8TsaBx4U3BokJt+Y2A0qz2C4pj08uX59qpWxRqSLEfRmVOEgQw==", - "requires": { - "@types/debug": "^4.1.8", - "@types/validator": "^13.7.17", - "debug": "^4.3.4", - "dottie": "^2.0.6", - "inflection": "^1.13.4", - "lodash": "^4.17.21", - "moment": "^2.29.4", - "moment-timezone": "^0.5.43", - "pg-connection-string": "^2.6.1", - "retry-as-promised": "^7.0.4", - "semver": "^7.5.4", - "sequelize-pool": "^7.1.0", - "toposort-class": "^1.0.1", - "uuid": "^8.3.2", - "validator": "^13.9.0", - "wkx": "^0.5.0" - }, - "dependencies": { - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "sequelize-cli": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/sequelize-cli/-/sequelize-cli-6.6.2.tgz", - "integrity": "sha512-V8Oh+XMz2+uquLZltZES6MVAD+yEnmMfwfn+gpXcDiwE3jyQygLt4xoI0zG8gKt6cRcs84hsKnXAKDQjG/JAgg==", - "dev": true, - "requires": { - "cli-color": "^2.0.3", - "fs-extra": "^9.1.0", - "js-beautify": "^1.14.5", - "lodash": "^4.17.21", - "resolve": "^1.22.1", - "umzug": "^2.3.0", - "yargs": "^16.2.0" - } - }, - "sequelize-pool": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-7.1.0.tgz", - "integrity": "sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==" - }, - "sequelize-typescript": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/sequelize-typescript/-/sequelize-typescript-2.1.6.tgz", - "integrity": "sha512-Vc2N++3en346RsbGjL3h7tgAl2Y7V+2liYTAOZ8XL0KTw3ahFHsyAUzOwct51n+g70I1TOUDgs06Oh6+XGcFkQ==", - "requires": { - "glob": "7.2.0" - }, - "dependencies": { - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } - } - }, - "serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - } - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true - }, - "split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==" - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "string-width-cjs": { - "version": "npm:string-width@4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-ansi-cjs": { - "version": "npm:strip-ansi@6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "timers-ext": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", - "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", - "dev": true, - "requires": { - "es5-ext": "~0.10.46", - "next-tick": "1" - } - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" - }, - "toposort-class": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", - "integrity": "sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg==" - }, - "type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", - "dev": true - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typescript": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz", - "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==", - "dev": true - }, - "umzug": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/umzug/-/umzug-2.3.0.tgz", - "integrity": "sha512-Z274K+e8goZK8QJxmbRPhl89HPO1K+ORFtm6rySPhFKfKc5GHhqdzD0SGhSWHkzoXasqJuItdhorSvY7/Cgflw==", - "dev": true, - "requires": { - "bluebird": "^3.7.2" - } - }, - "undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "validator": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", - "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==" - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "wkx": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.5.0.tgz", - "integrity": "sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==", - "requires": { - "@types/node": "*" - } - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wrap-ansi": { - "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", - "strip-ansi": "^6.0.0" - } - }, - "wrap-ansi-cjs": { - "version": "npm:wrap-ansi@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", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "yargs": { - "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", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true } } } diff --git a/routers/buildingsRouter.ts b/routers/buildingsRouter.ts new file mode 100644 index 00000000..fd0cb84a --- /dev/null +++ b/routers/buildingsRouter.ts @@ -0,0 +1,13 @@ +import { BuildingsController } from "../controllers/buildingController"; +import { Router } from "express"; + +const buildingsController = new BuildingsController(); + +export class BuildingsRouter { + routes = () => { + const router = Router(); + router.get("/buildings", buildingsController.getAllBuildings); + router.post("/buildings", buildingsController.AddNewBuilding); + return router; + }; +} From e9fd0f9e56a1a88080ac0c255a6b4fcf0d63fc93 Mon Sep 17 00:00:00 2001 From: magiicloud Date: Sun, 31 Mar 2024 18:17:24 +0800 Subject: [PATCH 13/44] added logic to search via serial num or via pk --- controllers/itemsController.ts | 39 ++++++++++++++++++++++++++++++++++ routers/itemsRouter.ts | 2 ++ 2 files changed, 41 insertions(+) diff --git a/controllers/itemsController.ts b/controllers/itemsController.ts index 36dcf43f..987a69b3 100644 --- a/controllers/itemsController.ts +++ b/controllers/itemsController.ts @@ -17,4 +17,43 @@ export class ItemsController { return res.status(400).json({ error: true, msg: (err as Error).message }); } } + + async findOneItem(req: Request, res: Response) { + try { + const { itemId } = req.params; + const { roomId } = req.params; + const output = await Item.findByPk(itemId, { + include: [ + { + model: RoomItem, + where: { room_id: roomId }, + include: [{ model: Room, attributes: ["name"] }], + }, + ], + }); + return res.json(output); + } catch (err) { + return res.status(400).json({ error: true, msg: (err as Error).message }); + } + } + + async findBySerial(req: Request, res: Response) { + try { + const { serialNum } = req.params; + const { roomId } = req.params; + const output = await Item.findOne({ + include: [ + { + model: RoomItem, + where: { room_id: roomId }, + include: [{ model: Room, attributes: ["name"] }], + }, + ], + where: { serial_num: serialNum }, + }); + return res.json(output); + } catch (err) { + return res.status(400).json({ error: true, msg: (err as Error).message }); + } + } } diff --git a/routers/itemsRouter.ts b/routers/itemsRouter.ts index 2fee23c6..46f7a177 100644 --- a/routers/itemsRouter.ts +++ b/routers/itemsRouter.ts @@ -7,6 +7,8 @@ export class ItemsRouter { routes = () => { const router = Router(); router.get("/allitems", itemsController.getAllItems); + router.get("/finditem/:itemId/:roomId", itemsController.findOneItem); + router.get("/findserial/:serialNum/:roomId", itemsController.findBySerial); return router; }; } From 6b27096ea642f768daebb37f33d5e0d7b0d63100 Mon Sep 17 00:00:00 2001 From: magiicloud Date: Sun, 31 Mar 2024 23:30:34 +0800 Subject: [PATCH 14/44] added update item controller and sort get all by id --- controllers/itemsController.ts | 33 +++++++++++++++++++++++++++++++++ index.ts | 3 +++ routers/itemsRouter.ts | 2 ++ 3 files changed, 38 insertions(+) diff --git a/controllers/itemsController.ts b/controllers/itemsController.ts index 987a69b3..adc69f9f 100644 --- a/controllers/itemsController.ts +++ b/controllers/itemsController.ts @@ -11,6 +11,7 @@ export class ItemsController { include: [{ model: Room, attributes: ["name"] }], }, ], + order: [["id", "ASC"]], }); return res.json(output); } catch (err) { @@ -18,6 +19,15 @@ export class ItemsController { } } + async getAllRooms(req: Request, res: Response) { + try { + const output = await Room.findAll({ order: [["id", "ASC"]] }); + return res.json(output); + } catch (err) { + return res.status(400).json({ error: true, msg: (err as Error).message }); + } + } + async findOneItem(req: Request, res: Response) { try { const { itemId } = req.params; @@ -56,4 +66,27 @@ export class ItemsController { return res.status(400).json({ error: true, msg: (err as Error).message }); } } + + async updateItem(req: Request, res: Response) { + try { + const { serialNum, quantity, expiryDate, roomSelect } = req.body; + + // Find the item by serial number + const item = await Item.findOne({ where: { serial_num: serialNum } }); + + if (!item) { + return res.status(404).json({ error: true, msg: "Item not found." }); + } + + // Update RoomItem entries + const updated = await RoomItem.update( + { quantity, expiry_date: expiryDate }, + { where: { room_id: roomSelect, item_id: item.id } } + ); + + return res.json({ success: true, updated }); + } catch (err) { + return res.status(400).json({ error: true, msg: (err as Error).message }); + } + } } diff --git a/index.ts b/index.ts index 4b296f6d..ea0ea8a5 100644 --- a/index.ts +++ b/index.ts @@ -19,6 +19,9 @@ const checkJwt = auth({ // Enable CORS access to this server app.use(cors()); +//JSON middleware +app.use(express.json()); + // Routers const itemsRouter = new ItemsRouter().routes(); app.use(itemsRouter); diff --git a/routers/itemsRouter.ts b/routers/itemsRouter.ts index 46f7a177..14e03826 100644 --- a/routers/itemsRouter.ts +++ b/routers/itemsRouter.ts @@ -7,8 +7,10 @@ export class ItemsRouter { routes = () => { const router = Router(); router.get("/allitems", itemsController.getAllItems); + router.get("/allrooms", itemsController.getAllRooms); router.get("/finditem/:itemId/:roomId", itemsController.findOneItem); router.get("/findserial/:serialNum/:roomId", itemsController.findBySerial); + router.put("/updateitem", itemsController.updateItem); return router; }; } From 563b07b10a53cd37856ab22f7c48b3abdc2a3419 Mon Sep 17 00:00:00 2001 From: magiicloud Date: Mon, 1 Apr 2024 22:15:46 +0800 Subject: [PATCH 15/44] added controller and route for adding new items --- controllers/itemsController.ts | 32 ++++++++++++++++++++++++++++++++ routers/itemsRouter.ts | 1 + 2 files changed, 33 insertions(+) diff --git a/controllers/itemsController.ts b/controllers/itemsController.ts index adc69f9f..12f24ab7 100644 --- a/controllers/itemsController.ts +++ b/controllers/itemsController.ts @@ -89,4 +89,36 @@ export class ItemsController { return res.status(400).json({ error: true, msg: (err as Error).message }); } } + + async addNewItem(req: Request, res: Response) { + try { + const { + serialNum, + itemName, + quantity, + expiryDate, + roomSelect, + par, + uom, + } = req.body; + + const item = await Item.create({ + serial_num: serialNum, + item_name: itemName, + par_level: par, + }); + + const roomItem = await RoomItem.create({ + item_id: item.id, + quantity: quantity as number, + expiry_date: expiryDate as Date, + uom: uom as string, + room_id: roomSelect as number, + }); + + return res.json({ success: true, item: item, roomItem: roomItem }); + } catch (err) { + return res.status(400).json({ error: true, msg: (err as Error).message }); + } + } } diff --git a/routers/itemsRouter.ts b/routers/itemsRouter.ts index 14e03826..0151293e 100644 --- a/routers/itemsRouter.ts +++ b/routers/itemsRouter.ts @@ -11,6 +11,7 @@ export class ItemsRouter { router.get("/finditem/:itemId/:roomId", itemsController.findOneItem); router.get("/findserial/:serialNum/:roomId", itemsController.findBySerial); router.put("/updateitem", itemsController.updateItem); + router.post("/addnewitem", itemsController.addNewItem); return router; }; } From a10a89cb0eec83d7c5c10b753f65ae1c948c71d2 Mon Sep 17 00:00:00 2001 From: patrickkok Date: Tue, 2 Apr 2024 00:58:48 +0800 Subject: [PATCH 16/44] Add controller method to add new building and associated rooms --- controllers/buildingController.ts | 30 +++++++--- db/models/Room.ts | 5 +- package-lock.json | 96 +++++++++++++++++++++++++++++++ package.json | 1 + 4 files changed, 124 insertions(+), 8 deletions(-) diff --git a/controllers/buildingController.ts b/controllers/buildingController.ts index 4228304b..7c65976d 100644 --- a/controllers/buildingController.ts +++ b/controllers/buildingController.ts @@ -1,5 +1,23 @@ import { Request, Response } from "express"; -import { Building, BuildingUser, Room } from "../db/models"; +import { Building, BuildingUser, User, Room } from "../db/models"; +import { Sequelize } from "sequelize-typescript"; +import { Dialect, Transaction } from "sequelize"; + +interface RoomAttributes { + name: string; + left: Float64Array; + top: Float64Array; + width: Float64Array; + height: Float64Array; + building_id: number; +} + +// const sequelize = new Sequelize({ +// database: process.env.DB_NAME, +// username: process.env.DB_USERNAME, +// dialect: process.env.DB_DIALECT as Dialect, +// models: [Building, BuildingUser, Room, User], // Import your model classes +// }); export class BuildingsController { async getAllBuildings(req: Request, res: Response) { @@ -20,16 +38,14 @@ export class BuildingsController { async AddNewBuilding(req: Request, res: Response) { const building = req.body.building; const rooms = req.body.rooms; + // const transaction: Transaction = await sequelize.transaction(); try { const newBuilding = await Building.create(building); - const newRooms: number[] = []; - rooms.map(async (obj: Object) => { + rooms.map(async (obj: RoomAttributes) => { const newRoom = { ...obj }; - newRoom["building_id" as keyof Object] = newBuilding.id; - const newRoomInstance = await rooms.create(newRoom); - newRooms.push(newRoomInstance.id); + newRoom["building_id"] = newBuilding.id; + await Room.create(newRoom); }); - // const newBuildingRooms = newBuilding.setRooms(newRooms); return res.json(newBuilding); } catch (err) { return res.status(400).json({ error: true, msg: err }); diff --git a/db/models/Room.ts b/db/models/Room.ts index 5a38cc1e..274c92fc 100644 --- a/db/models/Room.ts +++ b/db/models/Room.ts @@ -13,7 +13,10 @@ import { RoomItem } from "./RoomItem"; interface RoomAttributes { name: string; - room_coordinates: string; + left: Float64Array; + top: Float64Array; + width: Float64Array; + height: Float64Array; building_id: number; } diff --git a/package-lock.json b/package-lock.json index aae2cefd..5917273a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "dotenv": "^16.4.5", "express": "^4.18.1", "express-oauth2-jwt-bearer": "^1.6.0", + "mysql2": "^3.9.3", "pg": "^8.11.3", "reflect-metadata": "^0.2.1", "sequelize": "^6.37.1", @@ -796,6 +797,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "engines": { + "node": ">=0.10" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -1419,6 +1428,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dependencies": { + "is-property": "^1.0.2" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -1722,6 +1739,11 @@ "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", "dev": true }, + "node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -1920,6 +1942,11 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -2051,6 +2078,62 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/mysql2": { + "version": "3.9.3", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.9.3.tgz", + "integrity": "sha512-+ZaoF0llESUy7BffccHG+urErHcWPZ/WuzYAA9TEeLaDYyke3/3D+VQDzK9xzRnXpd0eMtRf0WNOeo4Q1Baung==", + "dependencies": { + "denque": "^2.1.0", + "generate-function": "^2.3.1", + "iconv-lite": "^0.6.3", + "long": "^5.2.1", + "lru-cache": "^8.0.0", + "named-placeholders": "^1.1.3", + "seq-queue": "^0.0.5", + "sqlstring": "^2.3.2" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/mysql2/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mysql2/node_modules/lru-cache": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", + "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", + "engines": { + "node": ">=16.14" + } + }, + "node_modules/named-placeholders": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz", + "integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==", + "dependencies": { + "lru-cache": "^7.14.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/named-placeholders/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "engines": { + "node": ">=12" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -2637,6 +2720,11 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, + "node_modules/seq-queue": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", + "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" + }, "node_modules/sequelize": { "version": "6.37.2", "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.37.2.tgz", @@ -2857,6 +2945,14 @@ "node": ">= 10.x" } }, + "node_modules/sqlstring": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", + "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", diff --git a/package.json b/package.json index 98f73210..a0a6ae1f 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "dotenv": "^16.4.5", "express": "^4.18.1", "express-oauth2-jwt-bearer": "^1.6.0", + "mysql2": "^3.9.3", "pg": "^8.11.3", "reflect-metadata": "^0.2.1", "sequelize": "^6.37.1", From d993e41d92965c0a41929dc808fc3e318b96f18c Mon Sep 17 00:00:00 2001 From: magiicloud Date: Tue, 2 Apr 2024 11:33:04 +0800 Subject: [PATCH 17/44] added route protection logic to index.ts --- index.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/index.ts b/index.ts index 3fa2f6cd..91455042 100644 --- a/index.ts +++ b/index.ts @@ -17,6 +17,22 @@ const checkJwt = auth({ issuerBaseURL: process.env.AUTH_DOMAIN, }); +// This route doesn't need authentication +app.get("/api/public", function (req, res) { + res.json({ + message: + "Hello from a public endpoint! You don't need to be authenticated to see this.", + }); +}); + +// This route needs authentication +app.get("/api/private", checkJwt, function (req, res) { + res.json({ + message: + "Hello from a private endpoint! You need to be authenticated to see this.", + }); +}); + // Enable CORS access to this server app.use(cors()); From b32249c70d9a1fc05eed190249a6305701023981 Mon Sep 17 00:00:00 2001 From: magiicloud Date: Tue, 2 Apr 2024 19:34:58 +0800 Subject: [PATCH 18/44] added new logic to add new items if it exist already --- controllers/itemsController.ts | 48 ++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/controllers/itemsController.ts b/controllers/itemsController.ts index 12f24ab7..e113fdf9 100644 --- a/controllers/itemsController.ts +++ b/controllers/itemsController.ts @@ -102,20 +102,46 @@ export class ItemsController { uom, } = req.body; - const item = await Item.create({ - serial_num: serialNum, - item_name: itemName, - par_level: par, - }); + let item = await Item.findOne({ where: { serial_num: serialNum } }); + + if (item) { + // Update existing item + await item.update({ + item_name: itemName, + par_level: par, + }); + } else { + item = await Item.create({ + serial_num: serialNum, + item_name: itemName, + par_level: par, + }); + } - const roomItem = await RoomItem.create({ - item_id: item.id, - quantity: quantity as number, - expiry_date: expiryDate as Date, - uom: uom as string, - room_id: roomSelect as number, + // Check if a RoomItem entry exists for this item and room + let roomItem = await RoomItem.findOne({ + where: { item_id: item.id, room_id: roomSelect }, }); + if (roomItem) { + // Update existing RoomItem entry + await roomItem.update({ + quantity: quantity, + expiry_date: expiryDate, + uom: uom, + }); + } else { + // Create a new RoomItem entry + + const roomItem = await RoomItem.create({ + item_id: item.id, + quantity: quantity as number, + expiry_date: expiryDate as Date, + uom: uom as string, + room_id: roomSelect as number, + }); + } + return res.json({ success: true, item: item, roomItem: roomItem }); } catch (err) { return res.status(400).json({ error: true, msg: (err as Error).message }); From dde662d5fb21d2134739dfcd5e5971e9b74252ba Mon Sep 17 00:00:00 2001 From: magiicloud Date: Tue, 2 Apr 2024 20:51:23 +0800 Subject: [PATCH 19/44] added logic to delete item in room and entire item set --- controllers/itemsController.ts | 70 +++++++++++++++++++++++++++++++++- routers/itemsRouter.ts | 2 + 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/controllers/itemsController.ts b/controllers/itemsController.ts index e113fdf9..ad4a5280 100644 --- a/controllers/itemsController.ts +++ b/controllers/itemsController.ts @@ -1,5 +1,5 @@ import { Request, Response } from "express"; -import { Item, RoomItem, Room } from "../db/models"; +import { Item, RoomItem, Room, CartLineItem } from "../db/models"; export class ItemsController { async getAllItems(req: Request, res: Response) { @@ -119,7 +119,7 @@ export class ItemsController { } // Check if a RoomItem entry exists for this item and room - let roomItem = await RoomItem.findOne({ + const roomItem = await RoomItem.findOne({ where: { item_id: item.id, room_id: roomSelect }, }); @@ -147,4 +147,70 @@ export class ItemsController { return res.status(400).json({ error: true, msg: (err as Error).message }); } } + + async deleteItem(req: Request, res: Response) { + try { + const { serialNum } = req.body; + + // Find the item by serial number + let item = await Item.findOne({ where: { serial_num: serialNum } }); + + if (!item) { + return res.status(404).json({ error: true, msg: "Item not found." }); + } + + // Delete associated RoomItem entries before deleting the Item + await RoomItem.destroy({ + where: { item_id: item.id }, + }); + // Delete associated CartLineItem entries before deleting the Item + await CartLineItem.destroy({ + where: { item_id: item.id }, + }); + + // Delete the item after its associated RoomItem entries have been deleted + await item.destroy(); + + return res.json({ + success: true, + msg: "Item and associated RoomItem entries deleted successfully.", + }); + } catch (err) { + return res.status(400).json({ error: true, msg: (err as Error).message }); + } + } + + async deleteRoomItem(req: Request, res: Response) { + try { + const { serialNum, roomSelect } = req.body; + + // Find the item by serial number + let item = await Item.findOne({ where: { serial_num: serialNum } }); + + if (!item) { + return res.status(404).json({ error: true, msg: "Item not found." }); + } + + // Attempt to delete the RoomItem entry linking the item to the specified room + const deletionResult = await RoomItem.destroy({ + where: { item_id: item.id, room_id: roomSelect }, + }); + + // Check if a RoomItem entry was deleted + if (deletionResult === 0) { + // No RoomItem entry was deleted, possibly because it didn't exist + return res + .status(404) + .json({ error: true, msg: "Item not found in the specified room." }); + } + + // Successfully deleted the RoomItem entry + return res.json({ + success: true, + msg: "Item deleted from the specified room successfully.", + }); + } catch (err) { + return res.status(400).json({ error: true, msg: (err as Error).message }); + } + } } diff --git a/routers/itemsRouter.ts b/routers/itemsRouter.ts index 0151293e..0e3dcd10 100644 --- a/routers/itemsRouter.ts +++ b/routers/itemsRouter.ts @@ -12,6 +12,8 @@ export class ItemsRouter { router.get("/findserial/:serialNum/:roomId", itemsController.findBySerial); router.put("/updateitem", itemsController.updateItem); router.post("/addnewitem", itemsController.addNewItem); + router.delete("/deleteroomitem", itemsController.deleteRoomItem); + router.delete("/deleteitem", itemsController.deleteItem); return router; }; } From 5738602e23f631ef30ce2f07b47db479465b6cf5 Mon Sep 17 00:00:00 2001 From: magiicloud Date: Tue, 2 Apr 2024 22:14:53 +0800 Subject: [PATCH 20/44] edited create item such that if item exist only update par and not iten_name --- controllers/itemsController.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/controllers/itemsController.ts b/controllers/itemsController.ts index ad4a5280..a70f4306 100644 --- a/controllers/itemsController.ts +++ b/controllers/itemsController.ts @@ -107,7 +107,6 @@ export class ItemsController { if (item) { // Update existing item await item.update({ - item_name: itemName, par_level: par, }); } else { From cf2cd38f71833613f7cdace9d719bee341565f90 Mon Sep 17 00:00:00 2001 From: patrickkok Date: Tue, 2 Apr 2024 22:38:47 +0800 Subject: [PATCH 21/44] Implement transactions --- controllers/buildingController.ts | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/controllers/buildingController.ts b/controllers/buildingController.ts index 7c65976d..9d56969a 100644 --- a/controllers/buildingController.ts +++ b/controllers/buildingController.ts @@ -1,5 +1,5 @@ import { Request, Response } from "express"; -import { Building, BuildingUser, User, Room } from "../db/models"; +import { Building, BuildingUser, User, Room, sequelize } from "../db/models"; import { Sequelize } from "sequelize-typescript"; import { Dialect, Transaction } from "sequelize"; @@ -12,13 +12,6 @@ interface RoomAttributes { building_id: number; } -// const sequelize = new Sequelize({ -// database: process.env.DB_NAME, -// username: process.env.DB_USERNAME, -// dialect: process.env.DB_DIALECT as Dialect, -// models: [Building, BuildingUser, Room, User], // Import your model classes -// }); - export class BuildingsController { async getAllBuildings(req: Request, res: Response) { try { @@ -38,16 +31,20 @@ export class BuildingsController { async AddNewBuilding(req: Request, res: Response) { const building = req.body.building; const rooms = req.body.rooms; - // const transaction: Transaction = await sequelize.transaction(); + const transaction: Transaction = await sequelize.transaction(); try { - const newBuilding = await Building.create(building); + const newBuilding = await Building.create(building, { + transaction, + }); rooms.map(async (obj: RoomAttributes) => { const newRoom = { ...obj }; newRoom["building_id"] = newBuilding.id; - await Room.create(newRoom); + await Room.create(newRoom, { transaction }); }); + await transaction.commit(); return res.json(newBuilding); } catch (err) { + await transaction.rollback(); return res.status(400).json({ error: true, msg: err }); } } From f0cab7a6c490f256f0bffaba3089f429a55240b2 Mon Sep 17 00:00:00 2001 From: magiicloud Date: Thu, 4 Apr 2024 14:41:01 +0800 Subject: [PATCH 22/44] added cart router to make cart transactions --- index.ts | 3 +++ routers/cartRouter.ts | 14 ++++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 routers/cartRouter.ts diff --git a/index.ts b/index.ts index 91455042..cc60f3d7 100644 --- a/index.ts +++ b/index.ts @@ -4,6 +4,7 @@ import { auth } from "express-oauth2-jwt-bearer"; import dotenv from "dotenv"; import { ItemsRouter } from "./routers/itemsRouter"; import { BuildingsRouter } from "./routers/buildingsRouter"; +import { CartRouter } from "./routers/cartRouter"; dotenv.config(); @@ -42,9 +43,11 @@ app.use(express.json()); // Routers const itemsRouter = new ItemsRouter().routes(); const buildingsRouter = new BuildingsRouter().routes(); +const cartRouter = new CartRouter().routes(); app.use(itemsRouter); app.use(buildingsRouter); +app.use(cartRouter); app.listen(PORT, () => { console.log(`Express app listening on port ${PORT}!`); diff --git a/routers/cartRouter.ts b/routers/cartRouter.ts new file mode 100644 index 00000000..7bfcfcd1 --- /dev/null +++ b/routers/cartRouter.ts @@ -0,0 +1,14 @@ +import { CartController } from "../controllers/cartController"; +import { Router } from "express"; + +const cartController = new CartController(); + +export class CartRouter { + routes = () => { + const router = Router(); + router.get("/getactivecart", cartController.retrieveActiveCart); + router.post("/additemcart", cartController.addItemToCart); + router.put("/checkoutcyclecount", cartController.checkoutCart); + return router; + }; +} From 0a026fb926174c5a7c411710769ffd3311ac349e Mon Sep 17 00:00:00 2001 From: magiicloud Date: Thu, 4 Apr 2024 14:41:41 +0800 Subject: [PATCH 23/44] added cart controllers to add item to cart, checkout cart and view active cart --- controllers/cartController.ts | 142 ++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 controllers/cartController.ts diff --git a/controllers/cartController.ts b/controllers/cartController.ts new file mode 100644 index 00000000..c76ce336 --- /dev/null +++ b/controllers/cartController.ts @@ -0,0 +1,142 @@ +import { Request, Response } from "express"; +import { Item, Cart, CartLineItem, RoomItem } from "../db/models"; +import { sequelize } from "../db/models"; + +export class CartController { + async retrieveActiveCart(req: Request, res: Response) { + const userId = 1; //req.user.id; // Assuming you have the user's ID from session/authentication + + try { + const cart = await Cart.findOne({ + where: { user_id: userId, active: true }, + include: [ + { + model: CartLineItem, + include: [Item], // Include details of items in the cart + }, + ], + }); + + if (!cart) { + return res + .status(404) + .json({ message: "No active cart found for the user." }); + } + + res.json(cart); + } catch (err) { + console.error("Error retrieving cart:", err); + res.status(500).json({ message: "Failed to retrieve cart." }); + } + } + + async addItemToCart(req: Request, res: Response) { + const { serialNum, quantity, expiryDate, roomId, userId } = req.body; + + try { + // Step 1: Find the item by serial number to get the itemId + const item = await Item.findOne({ where: { serial_num: serialNum } }); + if (!item) { + return res + .status(404) + .json({ error: true, message: "Item not found." }); + } + + // Step 2: Ensure the user has a cart + const [cart] = await Cart.findOrCreate({ + where: { user_id: userId, active: true }, + defaults: { user_id: userId, active: true }, + }); + + // Step 3: Add or update the item in the cart + const [itemInCart, itemCreated] = await CartLineItem.findOrCreate({ + where: { + cart_id: cart.id, + item_id: item.id, // Use the item's id obtained in Step 1 + room_id: roomId, + }, + defaults: { + cart_id: cart.id, + item_id: item.id, + room_id: roomId, + quantity: quantity, + expiry_date: expiryDate, + }, + }); + + if (!itemCreated) { + // The item exists in the cart, so update its quantity and possibly other details + itemInCart.quantity = quantity; + itemInCart.expiry_date = expiryDate; + // Update other fields as necessary + await itemInCart.save(); + } + + res.json({ + success: true, + message: "Item added to cart successfully", + cartItem: itemInCart, + }); + } catch (err) { + console.error("Failed to add item to cart:", err); + res.status(500).json({ + success: false, + message: "Failed to add item to cart", + error: (err as Error).message, + }); + } + } + + async checkoutCart(req: Request, res: Response) { + const userId = 1; //req.body.userId; // Or obtain the userId from session/authentication + + try { + // Sequelize managed transaction + await sequelize.transaction(async (transaction) => { + // Step 1: Retrieve the active cart for the user + const cart = await Cart.findOne({ + where: { user_id: userId, active: true }, + include: [{ model: CartLineItem, include: [Item] }], + transaction, + }); + + if (!cart) { + throw new Error("Active cart not found."); + } + + // Step 2: Batch update inventory quantities based on cart items + for (const cartLineItem of cart.cartLineItems) { + await RoomItem.update( + { + quantity: cartLineItem.quantity, + expiry_date: cartLineItem.expiry_date, + }, + { + where: { + room_id: cartLineItem.room_id, + item_id: cartLineItem.item_id, + }, + transaction, + } + ); + } + + // Step 3: Mark the cart as inactive or clear cart items + await Cart.update( + { active: false }, + { where: { id: cart.id }, transaction } + ); + }); + + // If the transaction is successful, respond with success + res.json({ success: true, message: "Checkout successful." }); + } catch (err) { + console.error("Checkout process failed:", err); + res.status(500).json({ + success: false, + message: "Checkout process failed", + error: (err as Error).message, + }); + } + } +} From d177a9a0189b6e2a21f82ad3dfb168532fdea5a9 Mon Sep 17 00:00:00 2001 From: magiicloud Date: Thu, 4 Apr 2024 14:43:57 +0800 Subject: [PATCH 24/44] modified migrations, models to associate Rooms and Cart_Line_Items. removed consumed column and adjusted the Cart_Line_Items table to below Room_Items table --- .../20240326012343-tertiary_tables.ts | 34 ++++++++----- db/models/Cart.ts | 8 +++ db/models/CartLineItem.ts | 15 ++++-- db/models/Room.ts | 4 ++ db/seeders/20240326034148-demo-user.ts | 21 -------- db/seeders/20240326050453-tertiary-seeds.ts | 51 ++++++++++++++++--- 6 files changed, 90 insertions(+), 43 deletions(-) diff --git a/db/migrations/20240326012343-tertiary_tables.ts b/db/migrations/20240326012343-tertiary_tables.ts index e76b7c46..9665e31b 100644 --- a/db/migrations/20240326012343-tertiary_tables.ts +++ b/db/migrations/20240326012343-tertiary_tables.ts @@ -41,18 +41,18 @@ module.exports = { }, }); - await queryInterface.createTable("Cart_Line_Items", { + await queryInterface.createTable("Room_Items", { id: { allowNull: false, autoIncrement: true, primaryKey: true, type: Sequelize.INTEGER, }, - cart_id: { + room_id: { allowNull: false, type: Sequelize.INTEGER, references: { - model: "Carts", + model: "Rooms", key: "id", }, }, @@ -68,9 +68,13 @@ module.exports = { allowNull: false, type: Sequelize.INTEGER, }, - consumed: { + uom: { allowNull: false, - type: Sequelize.BOOLEAN, + type: Sequelize.STRING, + }, + expiry_date: { + allowNull: false, + type: Sequelize.DATE, }, created_at: { allowNull: false, @@ -82,18 +86,18 @@ module.exports = { }, }); - await queryInterface.createTable("Room_Items", { + await queryInterface.createTable("Cart_Line_Items", { id: { allowNull: false, autoIncrement: true, primaryKey: true, type: Sequelize.INTEGER, }, - room_id: { + cart_id: { allowNull: false, type: Sequelize.INTEGER, references: { - model: "Rooms", + model: "Carts", key: "id", }, }, @@ -105,13 +109,17 @@ module.exports = { key: "id", }, }, - quantity: { + room_id: { allowNull: false, type: Sequelize.INTEGER, + references: { + model: "Rooms", + key: "id", + }, }, - uom: { + quantity: { allowNull: false, - type: Sequelize.STRING, + type: Sequelize.INTEGER, }, expiry_date: { allowNull: false, @@ -128,8 +136,8 @@ module.exports = { }); }, async down(queryInterface: QueryInterface, Sequelize: typeof DataTypes) { - await queryInterface.dropTable("Room_Items"); - await queryInterface.dropTable("Cart_Line_Items"); await queryInterface.dropTable("Building_Users"); + await queryInterface.dropTable("Cart_Line_Items"); + await queryInterface.dropTable("Room_Items"); }, }; diff --git a/db/models/Cart.ts b/db/models/Cart.ts index 11e8ba78..742a87f6 100644 --- a/db/models/Cart.ts +++ b/db/models/Cart.ts @@ -6,11 +6,14 @@ import { ForeignKey, BelongsTo, HasMany, + PrimaryKey, + AutoIncrement, } from "sequelize-typescript"; import { User } from "./User"; import { CartLineItem } from "./CartLineItem"; interface CartAttributes { + id?: number; active: boolean; user_id: number; } @@ -21,6 +24,11 @@ interface CartAttributes { underscored: true, }) export class Cart extends Model { + @PrimaryKey + @AutoIncrement + @Column(DataType.INTEGER) + id!: number; + @Column(DataType.BOOLEAN) active!: boolean; diff --git a/db/models/CartLineItem.ts b/db/models/CartLineItem.ts index 06da1951..95cf8701 100644 --- a/db/models/CartLineItem.ts +++ b/db/models/CartLineItem.ts @@ -8,12 +8,14 @@ import { } from "sequelize-typescript"; import { Cart } from "./Cart"; import { Item } from "./Item"; +import { Room } from "./Room"; interface CartLineItemAttributes { cart_id: number; item_id: number; + room_id: number; quantity: number; - consumed: boolean; + expiry_date: Date; } @Table({ @@ -30,11 +32,15 @@ export class CartLineItem extends Model { @Column(DataType.INTEGER) item_id!: number; + @ForeignKey(() => Room) + @Column(DataType.INTEGER) + room_id!: number; + @Column(DataType.INTEGER) quantity!: number; - @Column(DataType.BOOLEAN) - consumed!: boolean; + @Column(DataType.DATE) + expiry_date!: Date; // Associations can be defined here if needed @BelongsTo(() => Cart) @@ -42,4 +48,7 @@ export class CartLineItem extends Model { @BelongsTo(() => Item) item!: Item; + + @BelongsTo(() => Room) + room!: Room; } diff --git a/db/models/Room.ts b/db/models/Room.ts index 274c92fc..96cffc36 100644 --- a/db/models/Room.ts +++ b/db/models/Room.ts @@ -10,6 +10,7 @@ import { import { Building } from "./Building"; import { Transaction } from "./Transaction"; import { RoomItem } from "./RoomItem"; +import { CartLineItem } from "./CartLineItem"; interface RoomAttributes { name: string; @@ -54,4 +55,7 @@ export class Room extends Model { @HasMany(() => RoomItem) roomItems!: RoomItem[]; + + @HasMany(() => CartLineItem) + cartLineItems!: CartLineItem[]; } diff --git a/db/seeders/20240326034148-demo-user.ts b/db/seeders/20240326034148-demo-user.ts index 944d62f9..68b2e465 100644 --- a/db/seeders/20240326034148-demo-user.ts +++ b/db/seeders/20240326034148-demo-user.ts @@ -65,27 +65,6 @@ module.exports = { created_at: new Date(), updated_at: new Date(), }, - { - serial_num: "0005-84-153-F", - item_name: "KETOPROFEN 30MG PLAST(KEFENTECH)7S/8S/9S", - par_level: 250, - created_at: new Date(), - updated_at: new Date(), - }, - { - serial_num: "0004-40-022-F", - item_name: "calcium CARBONATE 625mg tab", - par_level: 350, - created_at: new Date(), - updated_at: new Date(), - }, - { - serial_num: "0463-49-68X-9", - item_name: "IRON POLYMALTOSE 100MG CAP", - par_level: 300, - created_at: new Date(), - updated_at: new Date(), - }, ]); await queryInterface.bulkInsert("Buildings", [ diff --git a/db/seeders/20240326050453-tertiary-seeds.ts b/db/seeders/20240326050453-tertiary-seeds.ts index f972634c..758b2619 100644 --- a/db/seeders/20240326050453-tertiary-seeds.ts +++ b/db/seeders/20240326050453-tertiary-seeds.ts @@ -33,24 +33,27 @@ module.exports = { { cart_id: 1, item_id: 1, - quantity: 20, - consumed: true, + room_id: 1, + quantity: 100, + expiry_date: new Date("2024-12-31"), created_at: new Date(), updated_at: new Date(), }, { cart_id: 1, item_id: 2, - quantity: 30, - consumed: false, + room_id: 3, + quantity: 2500, + expiry_date: new Date("2024-11-31"), created_at: new Date(), updated_at: new Date(), }, { cart_id: 1, item_id: 3, - quantity: 25, - consumed: false, + room_id: 1, + quantity: 250, + expiry_date: new Date("2024-10-31"), created_at: new Date(), updated_at: new Date(), }, @@ -66,6 +69,15 @@ module.exports = { created_at: new Date(), updated_at: new Date(), }, + { + room_id: 2, + item_id: 1, + quantity: 15, + uom: "TUBE", + expiry_date: new Date("2024-12-31"), + created_at: new Date(), + updated_at: new Date(), + }, { room_id: 1, item_id: 2, @@ -75,6 +87,15 @@ module.exports = { created_at: new Date(), updated_at: new Date(), }, + { + room_id: 3, + item_id: 2, + quantity: 38, + uom: "TUBE", + expiry_date: new Date("2024-06-31"), + created_at: new Date(), + updated_at: new Date(), + }, { room_id: 1, item_id: 3, @@ -84,6 +105,24 @@ module.exports = { created_at: new Date(), updated_at: new Date(), }, + { + room_id: 1, + item_id: 4, + quantity: 25, + uom: "TUBE", + expiry_date: new Date("2025-11-31"), + created_at: new Date(), + updated_at: new Date(), + }, + { + room_id: 1, + item_id: 5, + quantity: 250, + uom: "TAB", + expiry_date: new Date("2025-10-31"), + created_at: new Date(), + updated_at: new Date(), + }, ]); }, From ac7b53671c59475be4dfa95f42ab421e59c9ab6c Mon Sep 17 00:00:00 2001 From: magiicloud Date: Thu, 4 Apr 2024 22:05:47 +0800 Subject: [PATCH 25/44] amended roomId to roomSelect --- controllers/cartController.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/controllers/cartController.ts b/controllers/cartController.ts index c76ce336..0d7b9848 100644 --- a/controllers/cartController.ts +++ b/controllers/cartController.ts @@ -31,7 +31,7 @@ export class CartController { } async addItemToCart(req: Request, res: Response) { - const { serialNum, quantity, expiryDate, roomId, userId } = req.body; + const { serialNum, quantity, expiryDate, roomSelect, userId } = req.body; try { // Step 1: Find the item by serial number to get the itemId @@ -53,12 +53,12 @@ export class CartController { where: { cart_id: cart.id, item_id: item.id, // Use the item's id obtained in Step 1 - room_id: roomId, + room_id: roomSelect, }, defaults: { cart_id: cart.id, item_id: item.id, - room_id: roomId, + room_id: roomSelect, quantity: quantity, expiry_date: expiryDate, }, From a25c20bcf23a826b21c8c817eae971a404769776 Mon Sep 17 00:00:00 2001 From: patrickkok Date: Sat, 6 Apr 2024 09:39:10 +0800 Subject: [PATCH 26/44] Add transactions --- controllers/buildingController.ts | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/controllers/buildingController.ts b/controllers/buildingController.ts index 9d56969a..4c127334 100644 --- a/controllers/buildingController.ts +++ b/controllers/buildingController.ts @@ -31,20 +31,21 @@ export class BuildingsController { async AddNewBuilding(req: Request, res: Response) { const building = req.body.building; const rooms = req.body.rooms; - const transaction: Transaction = await sequelize.transaction(); try { - const newBuilding = await Building.create(building, { - transaction, + const result = await sequelize.transaction(async (t) => { + const newBuilding = await Building.create(building, { + transaction: t, + }); + await Promise.all( + rooms.map(async (obj: RoomAttributes) => { + const newRoom = { ...obj }; + newRoom["building_id"] = newBuilding.id; + await Room.create(newRoom, { transaction: t }); + }) + ); }); - rooms.map(async (obj: RoomAttributes) => { - const newRoom = { ...obj }; - newRoom["building_id"] = newBuilding.id; - await Room.create(newRoom, { transaction }); - }); - await transaction.commit(); - return res.json(newBuilding); + return res.json(result); } catch (err) { - await transaction.rollback(); return res.status(400).json({ error: true, msg: err }); } } From c3c6ddff331046011f4cf8d566061ca861264247 Mon Sep 17 00:00:00 2001 From: magiicloud Date: Sat, 6 Apr 2024 23:32:57 +0800 Subject: [PATCH 27/44] added protection to all routes except / --- index.ts | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/index.ts b/index.ts index cc60f3d7..b15cb1db 100644 --- a/index.ts +++ b/index.ts @@ -18,22 +18,6 @@ const checkJwt = auth({ issuerBaseURL: process.env.AUTH_DOMAIN, }); -// This route doesn't need authentication -app.get("/api/public", function (req, res) { - res.json({ - message: - "Hello from a public endpoint! You don't need to be authenticated to see this.", - }); -}); - -// This route needs authentication -app.get("/api/private", checkJwt, function (req, res) { - res.json({ - message: - "Hello from a private endpoint! You need to be authenticated to see this.", - }); -}); - // Enable CORS access to this server app.use(cors()); @@ -45,9 +29,9 @@ const itemsRouter = new ItemsRouter().routes(); const buildingsRouter = new BuildingsRouter().routes(); const cartRouter = new CartRouter().routes(); -app.use(itemsRouter); -app.use(buildingsRouter); -app.use(cartRouter); +app.use(checkJwt, itemsRouter); +app.use(checkJwt, buildingsRouter); +app.use(checkJwt, cartRouter); app.listen(PORT, () => { console.log(`Express app listening on port ${PORT}!`); From b27630d973a123b27c6438b6f46a0c4aad7a688e Mon Sep 17 00:00:00 2001 From: magiicloud Date: Sun, 7 Apr 2024 09:47:07 +0800 Subject: [PATCH 28/44] added delete item from cart logic --- controllers/cartController.ts | 29 +++++++++++++++++++++++++++++ routers/cartRouter.ts | 1 + 2 files changed, 30 insertions(+) diff --git a/controllers/cartController.ts b/controllers/cartController.ts index 0d7b9848..a3b36bef 100644 --- a/controllers/cartController.ts +++ b/controllers/cartController.ts @@ -87,6 +87,35 @@ export class CartController { } } + async deleteItemInCart(req: Request, res: Response) { + const { cartLineItemId } = req.body; + console.log(cartLineItemId); + + try { + // Step 1: Find the CartLineItem by PK + const cartLineItem = await CartLineItem.findByPk(cartLineItemId); + if (!cartLineItem) { + return res + .status(404) + .json({ error: true, message: "Cart item not found." }); + } + // Step 2: Delete the CartLineItem + await cartLineItem.destroy(); + + res.json({ + success: true, + message: "Item removed from cart successfully.", + }); + } catch (err) { + console.error("Failed to delete item from cart:", err); + res.status(500).json({ + success: false, + message: "Failed to delete item from cart", + error: (err as Error).message, + }); + } + } + async checkoutCart(req: Request, res: Response) { const userId = 1; //req.body.userId; // Or obtain the userId from session/authentication diff --git a/routers/cartRouter.ts b/routers/cartRouter.ts index 7bfcfcd1..7ec8d763 100644 --- a/routers/cartRouter.ts +++ b/routers/cartRouter.ts @@ -8,6 +8,7 @@ export class CartRouter { const router = Router(); router.get("/getactivecart", cartController.retrieveActiveCart); router.post("/additemcart", cartController.addItemToCart); + router.delete("/deleteitemincart", cartController.deleteItemInCart); router.put("/checkoutcyclecount", cartController.checkoutCart); return router; }; From 93d805f9966da1d8944207bdb4590bb7a6d57517 Mon Sep 17 00:00:00 2001 From: magiicloud Date: Sun, 7 Apr 2024 12:48:40 +0800 Subject: [PATCH 29/44] added dashboard router and controller to retrieve near expiry and below par items --- controllers/dashController.ts | 87 +++++++++++++++++++++++++++++++++++ index.ts | 15 ++++-- routers/dashRouter.ts | 13 ++++++ 3 files changed, 111 insertions(+), 4 deletions(-) create mode 100644 controllers/dashController.ts create mode 100644 routers/dashRouter.ts diff --git a/controllers/dashController.ts b/controllers/dashController.ts new file mode 100644 index 00000000..269f3b49 --- /dev/null +++ b/controllers/dashController.ts @@ -0,0 +1,87 @@ +import { Request, Response } from "express"; +import { Op } from "sequelize"; +import { Item, RoomItem, Room, CartLineItem } from "../db/models"; +import { sequelize } from "../db/models"; + +export class DashController { + async getExpiringItemsCount(req: Request, res: Response) { + try { + const sixMonthsFromNow = new Date(); + sixMonthsFromNow.setMonth(sixMonthsFromNow.getMonth() + 6); + + const output = await RoomItem.findAndCountAll({ + where: { + expiry_date: { + [Op.lt]: sixMonthsFromNow, + }, + }, + include: [ + { + model: Item, + attributes: ["serial_num", "item_name"], + }, + { + model: Room, + attributes: ["name"], + }, + ], + }); + res.json({ success: true, count: output.count, items: output.rows }); + } catch (error) { + console.error("Error getting expiring items count:", error); + res.status(500).json({ + success: false, + message: "Failed to get expiring items count", + }); + } + } + + async getItemsBelowPar(req: Request, res: Response) { + try { + const itemsBelowPar = await RoomItem.findAll({ + include: [ + { + model: Item, + attributes: ["par_level", "serial_num", "item_name"], + }, + { + model: Room, + attributes: ["name"], + }, + ], + where: sequelize.where( + sequelize.literal(`item.par_level * 0.5`), + Op.gte, + sequelize.col(`"RoomItem"."quantity"`) + ), + // attributes: { + // include: [ + // // Include a custom attribute that flags if the quantity is below 50% of the par level + // [ + // sequelize.literal( + // `item.par_level * 0.5 >= "RoomItem"."quantity"` + // ), + // "isBelowPar", + // ], + // ], + // }, + }); + + // interface RoomItemWithVirtual extends RoomItem { + // isBelowPar: boolean; + // } + + // const filteredItems = itemsBelowPar.filter((item) => + // (item as any).getDataValue("isBelowPar") + // ); + + res.json({ success: true, items: itemsBelowPar }); + } catch (error) { + console.error("Error getting items below par level:", error); + res.status(500).json({ + success: false, + message: "Failed to get items below par level", + }); + } + } +} diff --git a/index.ts b/index.ts index b15cb1db..ef8e56dc 100644 --- a/index.ts +++ b/index.ts @@ -5,6 +5,7 @@ import dotenv from "dotenv"; import { ItemsRouter } from "./routers/itemsRouter"; import { BuildingsRouter } from "./routers/buildingsRouter"; import { CartRouter } from "./routers/cartRouter"; +import { DashRouter } from "./routers/dashRouter"; dotenv.config(); @@ -28,10 +29,16 @@ app.use(express.json()); const itemsRouter = new ItemsRouter().routes(); const buildingsRouter = new BuildingsRouter().routes(); const cartRouter = new CartRouter().routes(); - -app.use(checkJwt, itemsRouter); -app.use(checkJwt, buildingsRouter); -app.use(checkJwt, cartRouter); +const dashRouter = new DashRouter().routes(); + +// app.use(checkJwt, itemsRouter); +// app.use(checkJwt, buildingsRouter); +// app.use(checkJwt, cartRouter); +// app.use(checkJwt, dashRouter); +app.use(itemsRouter); +app.use(buildingsRouter); +app.use(cartRouter); +app.use(dashRouter); app.listen(PORT, () => { console.log(`Express app listening on port ${PORT}!`); diff --git a/routers/dashRouter.ts b/routers/dashRouter.ts new file mode 100644 index 00000000..0f55eba4 --- /dev/null +++ b/routers/dashRouter.ts @@ -0,0 +1,13 @@ +import { DashController } from "../controllers/dashController"; +import { Router } from "express"; + +const dashController = new DashController(); + +export class DashRouter { + routes = () => { + const router = Router(); + router.get("/getexpiry", dashController.getExpiringItemsCount); + router.get("/getbelowpar", dashController.getItemsBelowPar); + return router; + }; +} From f5289d2cb47e78c5746eff56f0cffd9b3300a5e2 Mon Sep 17 00:00:00 2001 From: patrickkok Date: Sun, 7 Apr 2024 13:15:02 +0800 Subject: [PATCH 30/44] Add route and controller method to get room items --- controllers/itemsController.ts | 18 ++++++++++++++++++ routers/itemsRouter.ts | 1 + 2 files changed, 19 insertions(+) diff --git a/controllers/itemsController.ts b/controllers/itemsController.ts index a70f4306..78315c3b 100644 --- a/controllers/itemsController.ts +++ b/controllers/itemsController.ts @@ -67,6 +67,24 @@ export class ItemsController { } } + async getRoomItems(req: Request, res: Response) { + try { + const { roomId } = req.params; + const output = await Item.findAll({ + include: [ + { + model: RoomItem, + where: { room_id: roomId }, + include: [{ model: Room, attributes: ["name"] }], + }, + ], + }); + return res.json(output); + } catch (err) { + return res.status(400).json({ error: true, msg: (err as Error).message }); + } + } + async updateItem(req: Request, res: Response) { try { const { serialNum, quantity, expiryDate, roomSelect } = req.body; diff --git a/routers/itemsRouter.ts b/routers/itemsRouter.ts index 0e3dcd10..eaffb5aa 100644 --- a/routers/itemsRouter.ts +++ b/routers/itemsRouter.ts @@ -10,6 +10,7 @@ export class ItemsRouter { router.get("/allrooms", itemsController.getAllRooms); router.get("/finditem/:itemId/:roomId", itemsController.findOneItem); router.get("/findserial/:serialNum/:roomId", itemsController.findBySerial); + router.get("/items/:roomId", itemsController.getRoomItems); router.put("/updateitem", itemsController.updateItem); router.post("/addnewitem", itemsController.addNewItem); router.delete("/deleteroomitem", itemsController.deleteRoomItem); From bf7eea6c2df866bbb67956f2ce589cf1b4f31f8e Mon Sep 17 00:00:00 2001 From: patrickkok Date: Sun, 7 Apr 2024 19:02:08 +0800 Subject: [PATCH 31/44] Add user router and controller to findOrCreate user by email, made name an optional field in user model --- controllers/usersController.ts | 25 +++++++++++++++++++ .../20240325145721-initial-migration.ts | 1 - db/models/User.ts | 4 +-- index.ts | 3 +++ routers/usersRouter.ts | 12 +++++++++ 5 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 controllers/usersController.ts create mode 100644 routers/usersRouter.ts diff --git a/controllers/usersController.ts b/controllers/usersController.ts new file mode 100644 index 00000000..10d07b60 --- /dev/null +++ b/controllers/usersController.ts @@ -0,0 +1,25 @@ +import { Request, Response } from "express"; +import { Building, BuildingUser, User, Room, sequelize } from "../db/models"; +import { Sequelize } from "sequelize-typescript"; +import { Dialect, Transaction } from "sequelize"; + +interface RoomAttributes { + name: string; + left: Float64Array; + top: Float64Array; + width: Float64Array; + height: Float64Array; + building_id: number; +} + +export class UsersController { + async updateUser(req: Request, res: Response) { + const user = req.body; + try { + const output = await User.findOrCreate({ where: user }); + return res.json(output); + } catch (err) { + return res.status(400).json({ error: true, msg: (err as Error).message }); + } + } +} diff --git a/db/migrations/20240325145721-initial-migration.ts b/db/migrations/20240325145721-initial-migration.ts index ce011d52..02cc9818 100644 --- a/db/migrations/20240325145721-initial-migration.ts +++ b/db/migrations/20240325145721-initial-migration.ts @@ -12,7 +12,6 @@ module.exports = { type: Sequelize.INTEGER, }, name: { - allowNull: false, type: Sequelize.STRING, }, email: { diff --git a/db/models/User.ts b/db/models/User.ts index c5537cb9..e7911c1f 100644 --- a/db/models/User.ts +++ b/db/models/User.ts @@ -11,7 +11,7 @@ import { Cart } from "./Cart"; import { BuildingUser } from "./BuildingUser"; interface UserAttributes { - name: string; + name?: string; email: string; profile_img_url?: string; } @@ -23,7 +23,7 @@ interface UserAttributes { }) export class User extends Model { @Column(DataType.STRING) - name!: string; + name?: string; @Column(DataType.STRING) email!: string; diff --git a/index.ts b/index.ts index cc60f3d7..ef5ee628 100644 --- a/index.ts +++ b/index.ts @@ -5,6 +5,7 @@ import dotenv from "dotenv"; import { ItemsRouter } from "./routers/itemsRouter"; import { BuildingsRouter } from "./routers/buildingsRouter"; import { CartRouter } from "./routers/cartRouter"; +import { UsersRouter } from "./routers/usersRouter"; dotenv.config(); @@ -44,10 +45,12 @@ app.use(express.json()); const itemsRouter = new ItemsRouter().routes(); const buildingsRouter = new BuildingsRouter().routes(); const cartRouter = new CartRouter().routes(); +const usersrouter = new UsersRouter().routes(); app.use(itemsRouter); app.use(buildingsRouter); app.use(cartRouter); +app.use(usersrouter); app.listen(PORT, () => { console.log(`Express app listening on port ${PORT}!`); diff --git a/routers/usersRouter.ts b/routers/usersRouter.ts new file mode 100644 index 00000000..b5421946 --- /dev/null +++ b/routers/usersRouter.ts @@ -0,0 +1,12 @@ +import { UsersController } from "../controllers/usersController"; +import { Router } from "express"; + +const usersController = new UsersController(); + +export class UsersRouter { + routes = () => { + const router = Router(); + router.post("/users", usersController.updateUser); + return router; + }; +} From 8f97736e976aab5ddb760162adb7bf6061fe6101 Mon Sep 17 00:00:00 2001 From: magiicloud Date: Sun, 7 Apr 2024 21:05:34 +0800 Subject: [PATCH 32/44] sorted getExpiringItemsCount and modified getParItems by doing rawQuery as sequelize cannot handle complex equations --- controllers/dashController.ts | 125 +++++++++++++++++++++++++++++++--- 1 file changed, 115 insertions(+), 10 deletions(-) diff --git a/controllers/dashController.ts b/controllers/dashController.ts index 269f3b49..96ae3eeb 100644 --- a/controllers/dashController.ts +++ b/controllers/dashController.ts @@ -1,7 +1,8 @@ import { Request, Response } from "express"; import { Op } from "sequelize"; -import { Item, RoomItem, Room, CartLineItem } from "../db/models"; +import { Item, RoomItem, Room } from "../db/models"; import { sequelize } from "../db/models"; +import { QueryTypes } from "sequelize"; export class DashController { async getExpiringItemsCount(req: Request, res: Response) { @@ -25,6 +26,7 @@ export class DashController { attributes: ["name"], }, ], + order: [["expiry_date", "ASC"]], }); res.json({ success: true, count: output.count, items: output.rows }); } catch (error) { @@ -36,9 +38,9 @@ export class DashController { } } - async getItemsBelowPar(req: Request, res: Response) { + async getItemsBelowParOLD(req: Request, res: Response) { try { - const itemsBelowPar = await RoomItem.findAll({ + const itemsBelowPar = await RoomItem.findAndCountAll({ include: [ { model: Item, @@ -66,16 +68,119 @@ export class DashController { // ], // }, }); + res.json({ + success: true, + count: itemsBelowPar.count, + items: itemsBelowPar.rows, + }); + } catch (error) { + console.error("Error getting items below par level:", error); + res.status(500).json({ + success: false, + message: "Failed to get items below par level", + }); + } + } + + // async getItemsBelowParNEW(req: Request, res: Response) { + // try { + // const itemsBelowPar = await RoomItem.findAndCountAll({ + // include: [ + // { + // model: Item, + // attributes: ["par_level", "serial_num", "item_name"], + // }, + // { + // model: Room, + // attributes: ["name"], + // }, + // ], + // attributes: { + // include: [ + // // Include a custom attribute that flags if the quantity is below 50% of the par level + // [ + // sequelize.literal( + // `item.par_level * 0.5 >= "RoomItem"."quantity"` + // ), + // "isBelowPar", + // ], + // ], + // }, + // }); - // interface RoomItemWithVirtual extends RoomItem { - // isBelowPar: boolean; - // } + // res.json({ + // success: true, + // count: itemsBelowPar.count, + // items: itemsBelowPar.rows, + // }); + // } catch (error) { + // console.error("Error getting items below par level:", error); + // res.status(500).json({ + // success: false, + // message: "Failed to get items below par level", + // }); + // } + // } - // const filteredItems = itemsBelowPar.filter((item) => - // (item as any).getDataValue("isBelowPar") - // ); + async getItemsBelowPar(req: Request, res: Response) { + const rawFindQuery = `SELECT * FROM + (SELECT "Item"."id", "Item"."serial_num", "Item"."item_name", "Item"."par_level", + (SELECT SUM(quantity) FROM "Room_Items" AS "roomItems" WHERE "roomItems"."item_id" = "Item"."id") AS "itemTotal" + FROM "Items" AS "Item") + AS FilteredItems WHERE "itemTotal" <= ("par_level" * 1.5) + ORDER BY "itemTotal" ASC;`; - res.json({ success: true, items: itemsBelowPar }); + const rawCountQuery = `SELECT COUNT(*) FROM + (SELECT "Item"."id", "Item"."serial_num", "Item"."item_name", "Item"."par_level", + (SELECT SUM(quantity) FROM "Room_Items" AS "roomItems" WHERE "roomItems"."item_id" = "Item"."id") AS "itemTotal" + FROM "Items" AS "Item") + AS FilteredItems WHERE "itemTotal" <= ("par_level" * 1.5);`; + + try { + const itemsBelowPar = await sequelize.query(rawFindQuery, { + type: QueryTypes.SELECT, + }); + const countItemsBelowPar = await sequelize.query(rawCountQuery, { + type: QueryTypes.SELECT, + }); + // const itemsBelowPar = await Item.findAll({ + // include: [ + // { + // model: RoomItem, + // attributes: ["quantity", "item_id", "uom"], + // include: [ + // { + // model: Room, + // attributes: ["name"], + // }, + // ], + // }, + // ], + // attributes: { + // include: [ + // // Subquery to calculate the sum of quantities from RoomItems for each Item + // [ + // sequelize.literal(`( + // SELECT SUM(quantity) + // FROM "Room_Items" AS "roomItems" + // WHERE "roomItems"."item_id" = "Item"."id" + // )`), + // "itemTotal", + // ], + // ], + // }, + // where: sequelize.where( + // sequelize.literal(`"items"."par_level" * 0.5`), + // Op.gte, + // sequelize.col(`"items"."itemTotal"`) + // ), + // }); + + res.json({ + success: true, + items: itemsBelowPar, + count: countItemsBelowPar, + }); } catch (error) { console.error("Error getting items below par level:", error); res.status(500).json({ From de096c214fe084d262c61eb879a5626f06c1a4c0 Mon Sep 17 00:00:00 2001 From: patrickkok Date: Mon, 8 Apr 2024 21:57:10 +0800 Subject: [PATCH 33/44] Add building controller methods and routes to only display buildings a user is a part of, create buildingUser row when creating new building --- controllers/buildingController.ts | 27 +++++++++++++++++++++++++++ routers/buildingsRouter.ts | 1 + 2 files changed, 28 insertions(+) diff --git a/controllers/buildingController.ts b/controllers/buildingController.ts index 4c127334..9bc2a0c2 100644 --- a/controllers/buildingController.ts +++ b/controllers/buildingController.ts @@ -13,6 +13,25 @@ interface RoomAttributes { } export class BuildingsController { + async getBuildingsByUser(req: Request, res: Response) { + const userEmail = req.params.userEmail; + try { + const user = await User.findOne({ where: { email: userEmail } }); + if (user) { + const output = await Building.findAll({ + include: [ + { + model: Room, + }, + { model: BuildingUser, where: { user_id: user.id } }, + ], + }); + return res.json(output); + } + } catch (err) { + return res.status(400).json({ error: true, msg: (err as Error).message }); + } + } async getAllBuildings(req: Request, res: Response) { try { const output = await Building.findAll({ @@ -31,6 +50,7 @@ export class BuildingsController { async AddNewBuilding(req: Request, res: Response) { const building = req.body.building; const rooms = req.body.rooms; + const userEmail = req.body.userEmail; try { const result = await sequelize.transaction(async (t) => { const newBuilding = await Building.create(building, { @@ -43,6 +63,13 @@ export class BuildingsController { await Room.create(newRoom, { transaction: t }); }) ); + const user = await User.findOne({ where: { email: userEmail } }); + const newBuildingUser = { + building_id: newBuilding.id, + user_id: user?.id, + admin: true, + }; + await BuildingUser.create(newBuildingUser, { transaction: t }); }); return res.json(result); } catch (err) { diff --git a/routers/buildingsRouter.ts b/routers/buildingsRouter.ts index fd0cb84a..87513e84 100644 --- a/routers/buildingsRouter.ts +++ b/routers/buildingsRouter.ts @@ -6,6 +6,7 @@ const buildingsController = new BuildingsController(); export class BuildingsRouter { routes = () => { const router = Router(); + router.get("/buildings/:userEmail", buildingsController.getBuildingsByUser); router.get("/buildings", buildingsController.getAllBuildings); router.post("/buildings", buildingsController.AddNewBuilding); return router; From 40852f4a8871d0e68a2a9ef47a01e84d69045453 Mon Sep 17 00:00:00 2001 From: magiicloud Date: Tue, 9 Apr 2024 10:17:10 +0800 Subject: [PATCH 34/44] amended the usercontroller migrations and seeder for retreival of userinfo after logging in --- controllers/usersController.ts | 12 ++++++++++-- db/migrations/20240325145721-initial-migration.ts | 4 ++++ db/models/User.ts | 4 ++++ db/seeders/20240326034148-demo-user.ts | 3 +++ 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/controllers/usersController.ts b/controllers/usersController.ts index 10d07b60..67b57723 100644 --- a/controllers/usersController.ts +++ b/controllers/usersController.ts @@ -14,9 +14,17 @@ interface RoomAttributes { export class UsersController { async updateUser(req: Request, res: Response) { - const user = req.body; + const { email, name, id, photoUrl } = req.body; try { - const output = await User.findOrCreate({ where: user }); + const output = await User.findOrCreate({ + where: { email: email }, + defaults: { + auth_id: id, + email: email, + name: name, + profile_img_url: photoUrl, + }, + }); return res.json(output); } catch (err) { return res.status(400).json({ error: true, msg: (err as Error).message }); diff --git a/db/migrations/20240325145721-initial-migration.ts b/db/migrations/20240325145721-initial-migration.ts index 02cc9818..9f3d2c45 100644 --- a/db/migrations/20240325145721-initial-migration.ts +++ b/db/migrations/20240325145721-initial-migration.ts @@ -11,6 +11,10 @@ module.exports = { primaryKey: true, type: Sequelize.INTEGER, }, + auth_id: { + allowNull: false, + type: Sequelize.STRING, + }, name: { type: Sequelize.STRING, }, diff --git a/db/models/User.ts b/db/models/User.ts index e7911c1f..38833f4a 100644 --- a/db/models/User.ts +++ b/db/models/User.ts @@ -11,6 +11,7 @@ import { Cart } from "./Cart"; import { BuildingUser } from "./BuildingUser"; interface UserAttributes { + auth_id: string; name?: string; email: string; profile_img_url?: string; @@ -22,6 +23,9 @@ interface UserAttributes { underscored: true, }) export class User extends Model { + @Column(DataType.STRING) + auth_id!: string; + @Column(DataType.STRING) name?: string; diff --git a/db/seeders/20240326034148-demo-user.ts b/db/seeders/20240326034148-demo-user.ts index 68b2e465..e95a3c20 100644 --- a/db/seeders/20240326034148-demo-user.ts +++ b/db/seeders/20240326034148-demo-user.ts @@ -7,6 +7,7 @@ module.exports = { async up(queryInterface: QueryInterface, Sequelize: typeof DataTypes) { await queryInterface.bulkInsert("Users", [ { + auth_id: "lkajlsdliiosvnlk", name: "Paloma Diamond", email: "pdiamond@gmail.com", profile_img_url: null, @@ -14,6 +15,7 @@ module.exports = { updated_at: new Date(), }, { + auth_id: "akjshfkjhgoivknlas", name: "Lynn Kelogg", email: "lynnk@gmail.com", profile_img_url: null, @@ -21,6 +23,7 @@ module.exports = { updated_at: new Date(), }, { + auth_id: "akjhsgihioljla", name: "Lorelai Lynch", email: "lorelailynch@gmail.com", profile_img_url: null, From b37e1342bb18a1ab8e0ab139620f509fe2df5ea4 Mon Sep 17 00:00:00 2001 From: magiicloud Date: Tue, 9 Apr 2024 19:41:29 +0800 Subject: [PATCH 35/44] amended the default userId 1 to accept userId from params or req body --- controllers/cartController.ts | 5 ++--- controllers/usersController.ts | 12 +++++++++++- routers/cartRouter.ts | 2 +- routers/usersRouter.ts | 1 + 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/controllers/cartController.ts b/controllers/cartController.ts index a3b36bef..a8cb6b58 100644 --- a/controllers/cartController.ts +++ b/controllers/cartController.ts @@ -4,7 +4,7 @@ import { sequelize } from "../db/models"; export class CartController { async retrieveActiveCart(req: Request, res: Response) { - const userId = 1; //req.user.id; // Assuming you have the user's ID from session/authentication + const { userId } = req.params; try { const cart = await Cart.findOne({ @@ -89,7 +89,6 @@ export class CartController { async deleteItemInCart(req: Request, res: Response) { const { cartLineItemId } = req.body; - console.log(cartLineItemId); try { // Step 1: Find the CartLineItem by PK @@ -117,7 +116,7 @@ export class CartController { } async checkoutCart(req: Request, res: Response) { - const userId = 1; //req.body.userId; // Or obtain the userId from session/authentication + const { userId } = req.body; try { // Sequelize managed transaction diff --git a/controllers/usersController.ts b/controllers/usersController.ts index 67b57723..c93df996 100644 --- a/controllers/usersController.ts +++ b/controllers/usersController.ts @@ -1,7 +1,7 @@ import { Request, Response } from "express"; import { Building, BuildingUser, User, Room, sequelize } from "../db/models"; import { Sequelize } from "sequelize-typescript"; -import { Dialect, Transaction } from "sequelize"; +import { Dialect, Transaction, where } from "sequelize"; interface RoomAttributes { name: string; @@ -30,4 +30,14 @@ export class UsersController { return res.status(400).json({ error: true, msg: (err as Error).message }); } } + + async findUserByEmail(req: Request, res: Response) { + const { email } = req.body; + try { + const output = await User.findOne({ where: { email: email } }); + return res.json(output); + } catch (err) { + return res.status(400).json({ error: true, msg: (err as Error).message }); + } + } } diff --git a/routers/cartRouter.ts b/routers/cartRouter.ts index 7ec8d763..c094de61 100644 --- a/routers/cartRouter.ts +++ b/routers/cartRouter.ts @@ -6,7 +6,7 @@ const cartController = new CartController(); export class CartRouter { routes = () => { const router = Router(); - router.get("/getactivecart", cartController.retrieveActiveCart); + router.get("/getactivecart/:userId", cartController.retrieveActiveCart); router.post("/additemcart", cartController.addItemToCart); router.delete("/deleteitemincart", cartController.deleteItemInCart); router.put("/checkoutcyclecount", cartController.checkoutCart); diff --git a/routers/usersRouter.ts b/routers/usersRouter.ts index b5421946..a58c3d9c 100644 --- a/routers/usersRouter.ts +++ b/routers/usersRouter.ts @@ -7,6 +7,7 @@ export class UsersRouter { routes = () => { const router = Router(); router.post("/users", usersController.updateUser); + router.get("/finduser", usersController.findUserByEmail); return router; }; } From c45b686aba969978fd82e8da949c35ad27ae28d4 Mon Sep 17 00:00:00 2001 From: patrickkok Date: Wed, 10 Apr 2024 13:30:52 +0800 Subject: [PATCH 36/44] Update building controller and router to accept userId instead of UserEmail --- controllers/buildingController.ts | 29 +++++++++++++---------------- routers/buildingsRouter.ts | 2 +- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/controllers/buildingController.ts b/controllers/buildingController.ts index 9bc2a0c2..5c61c559 100644 --- a/controllers/buildingController.ts +++ b/controllers/buildingController.ts @@ -14,20 +14,17 @@ interface RoomAttributes { export class BuildingsController { async getBuildingsByUser(req: Request, res: Response) { - const userEmail = req.params.userEmail; + const userId = req.params.userId; try { - const user = await User.findOne({ where: { email: userEmail } }); - if (user) { - const output = await Building.findAll({ - include: [ - { - model: Room, - }, - { model: BuildingUser, where: { user_id: user.id } }, - ], - }); - return res.json(output); - } + const output = await Building.findAll({ + include: [ + { + model: Room, + }, + { model: BuildingUser, where: { user_id: userId } }, + ], + }); + return res.json(output); } catch (err) { return res.status(400).json({ error: true, msg: (err as Error).message }); } @@ -50,7 +47,7 @@ export class BuildingsController { async AddNewBuilding(req: Request, res: Response) { const building = req.body.building; const rooms = req.body.rooms; - const userEmail = req.body.userEmail; + const userId = req.body.userId; try { const result = await sequelize.transaction(async (t) => { const newBuilding = await Building.create(building, { @@ -63,13 +60,13 @@ export class BuildingsController { await Room.create(newRoom, { transaction: t }); }) ); - const user = await User.findOne({ where: { email: userEmail } }); const newBuildingUser = { building_id: newBuilding.id, - user_id: user?.id, + user_id: userId, admin: true, }; await BuildingUser.create(newBuildingUser, { transaction: t }); + return newBuilding; }); return res.json(result); } catch (err) { diff --git a/routers/buildingsRouter.ts b/routers/buildingsRouter.ts index 87513e84..38b889ca 100644 --- a/routers/buildingsRouter.ts +++ b/routers/buildingsRouter.ts @@ -6,7 +6,7 @@ const buildingsController = new BuildingsController(); export class BuildingsRouter { routes = () => { const router = Router(); - router.get("/buildings/:userEmail", buildingsController.getBuildingsByUser); + router.get("/buildings/:userId", buildingsController.getBuildingsByUser); router.get("/buildings", buildingsController.getAllBuildings); router.post("/buildings", buildingsController.AddNewBuilding); return router; From c02bccb3720c6165fffed5bbf26928aac766529b Mon Sep 17 00:00:00 2001 From: patrickkok Date: Wed, 10 Apr 2024 19:13:35 +0800 Subject: [PATCH 37/44] Add logic to add users to buildings --- controllers/buildingController.ts | 26 ++++++++++++++++++++++++++ controllers/itemsController.ts | 1 + routers/buildingsRouter.ts | 1 + 3 files changed, 28 insertions(+) diff --git a/controllers/buildingController.ts b/controllers/buildingController.ts index 5c61c559..c8bea074 100644 --- a/controllers/buildingController.ts +++ b/controllers/buildingController.ts @@ -73,4 +73,30 @@ export class BuildingsController { return res.status(400).json({ error: true, msg: err }); } } + + async AddBuildingUser(req: Request, res: Response) { + const { buildingId, newUserEmail, admin } = req.body; + try { + const result = await sequelize.transaction(async (t) => { + const user = await User.findOne({ where: { email: newUserEmail } }); + if (!user) { + throw new Error("User not found"); + } else { + const newBuildingUser = { + building_id: buildingId, + user_id: user.id, + admin: false, + }; + return await BuildingUser.create(newBuildingUser, { transaction: t }); + } + }); + return res.json(result); + } catch (err) { + if (err instanceof Error) { + return res.status(400).json({ error: true, msg: err.message }); + } else { + return res.status(400).json({ error: true, msg: err }); + } + } + } } diff --git a/controllers/itemsController.ts b/controllers/itemsController.ts index 78315c3b..d59cd492 100644 --- a/controllers/itemsController.ts +++ b/controllers/itemsController.ts @@ -70,6 +70,7 @@ export class ItemsController { async getRoomItems(req: Request, res: Response) { try { const { roomId } = req.params; + console.log(roomId); const output = await Item.findAll({ include: [ { diff --git a/routers/buildingsRouter.ts b/routers/buildingsRouter.ts index 38b889ca..a78fb567 100644 --- a/routers/buildingsRouter.ts +++ b/routers/buildingsRouter.ts @@ -9,6 +9,7 @@ export class BuildingsRouter { router.get("/buildings/:userId", buildingsController.getBuildingsByUser); router.get("/buildings", buildingsController.getAllBuildings); router.post("/buildings", buildingsController.AddNewBuilding); + router.post("/buildings/user", buildingsController.AddBuildingUser); return router; }; } From 34d7477c44ffc6e47971769bbeb664b1415c5a55 Mon Sep 17 00:00:00 2001 From: patrickkok Date: Sat, 13 Apr 2024 14:52:28 +0800 Subject: [PATCH 38/44] Update getItemsBelowPar and getExpiringItemsCount to only get items the user has access to --- controllers/dashController.ts | 155 ++++++---------------------------- routers/dashRouter.ts | 4 +- 2 files changed, 30 insertions(+), 129 deletions(-) diff --git a/controllers/dashController.ts b/controllers/dashController.ts index 96ae3eeb..647716c2 100644 --- a/controllers/dashController.ts +++ b/controllers/dashController.ts @@ -6,6 +6,7 @@ import { QueryTypes } from "sequelize"; export class DashController { async getExpiringItemsCount(req: Request, res: Response) { + const buildingId = req.params.buildingId; try { const sixMonthsFromNow = new Date(); sixMonthsFromNow.setMonth(sixMonthsFromNow.getMonth() + 6); @@ -23,7 +24,8 @@ export class DashController { }, { model: Room, - attributes: ["name"], + attributes: ["name", "building_id"], + where: { building_id: buildingId }, }, ], order: [["expiry_date", "ASC"]], @@ -38,9 +40,10 @@ export class DashController { } } - async getItemsBelowParOLD(req: Request, res: Response) { + async getItemsBelowPar(req: Request, res: Response) { + const buildingId = req.params.buildingId; try { - const itemsBelowPar = await RoomItem.findAndCountAll({ + const itemsBelowPar = await RoomItem.findAll({ include: [ { model: Item, @@ -48,138 +51,36 @@ export class DashController { }, { model: Room, - attributes: ["name"], + attributes: ["name", "building_id"], + where: { building_id: buildingId }, }, ], - where: sequelize.where( - sequelize.literal(`item.par_level * 0.5`), - Op.gte, - sequelize.col(`"RoomItem"."quantity"`) + attributes: { + include: [ + // Include a custom attribute that flags if the quantity is below 50% of the par level + [ + sequelize.literal(`"RoomItem"."quantity" * 100 /item.par_level`), + "parPercent", + ], + ], + }, + where: sequelize.literal( + // only include items 150% or below par level + `"RoomItem"."quantity" * 100 /item.par_level <= 150` ), - // attributes: { - // include: [ - // // Include a custom attribute that flags if the quantity is below 50% of the par level - // [ - // sequelize.literal( - // `item.par_level * 0.5 >= "RoomItem"."quantity"` - // ), - // "isBelowPar", - // ], - // ], - // }, - }); - res.json({ - success: true, - count: itemsBelowPar.count, - items: itemsBelowPar.rows, - }); - } catch (error) { - console.error("Error getting items below par level:", error); - res.status(500).json({ - success: false, - message: "Failed to get items below par level", - }); - } - } - - // async getItemsBelowParNEW(req: Request, res: Response) { - // try { - // const itemsBelowPar = await RoomItem.findAndCountAll({ - // include: [ - // { - // model: Item, - // attributes: ["par_level", "serial_num", "item_name"], - // }, - // { - // model: Room, - // attributes: ["name"], - // }, - // ], - // attributes: { - // include: [ - // // Include a custom attribute that flags if the quantity is below 50% of the par level - // [ - // sequelize.literal( - // `item.par_level * 0.5 >= "RoomItem"."quantity"` - // ), - // "isBelowPar", - // ], - // ], - // }, - // }); - - // res.json({ - // success: true, - // count: itemsBelowPar.count, - // items: itemsBelowPar.rows, - // }); - // } catch (error) { - // console.error("Error getting items below par level:", error); - // res.status(500).json({ - // success: false, - // message: "Failed to get items below par level", - // }); - // } - // } - - async getItemsBelowPar(req: Request, res: Response) { - const rawFindQuery = `SELECT * FROM - (SELECT "Item"."id", "Item"."serial_num", "Item"."item_name", "Item"."par_level", - (SELECT SUM(quantity) FROM "Room_Items" AS "roomItems" WHERE "roomItems"."item_id" = "Item"."id") AS "itemTotal" - FROM "Items" AS "Item") - AS FilteredItems WHERE "itemTotal" <= ("par_level" * 1.5) - ORDER BY "itemTotal" ASC;`; - - const rawCountQuery = `SELECT COUNT(*) FROM - (SELECT "Item"."id", "Item"."serial_num", "Item"."item_name", "Item"."par_level", - (SELECT SUM(quantity) FROM "Room_Items" AS "roomItems" WHERE "roomItems"."item_id" = "Item"."id") AS "itemTotal" - FROM "Items" AS "Item") - AS FilteredItems WHERE "itemTotal" <= ("par_level" * 1.5);`; - - try { - const itemsBelowPar = await sequelize.query(rawFindQuery, { - type: QueryTypes.SELECT, - }); - const countItemsBelowPar = await sequelize.query(rawCountQuery, { - type: QueryTypes.SELECT, + order: [ + // Order the results by the custom attribute isBelowPar in ascending order + [ + sequelize.literal(`"RoomItem"."quantity" * 100 /item.par_level`), + "ASC", + ], + ], }); - // const itemsBelowPar = await Item.findAll({ - // include: [ - // { - // model: RoomItem, - // attributes: ["quantity", "item_id", "uom"], - // include: [ - // { - // model: Room, - // attributes: ["name"], - // }, - // ], - // }, - // ], - // attributes: { - // include: [ - // // Subquery to calculate the sum of quantities from RoomItems for each Item - // [ - // sequelize.literal(`( - // SELECT SUM(quantity) - // FROM "Room_Items" AS "roomItems" - // WHERE "roomItems"."item_id" = "Item"."id" - // )`), - // "itemTotal", - // ], - // ], - // }, - // where: sequelize.where( - // sequelize.literal(`"items"."par_level" * 0.5`), - // Op.gte, - // sequelize.col(`"items"."itemTotal"`) - // ), - // }); res.json({ success: true, + count: itemsBelowPar.length, items: itemsBelowPar, - count: countItemsBelowPar, }); } catch (error) { console.error("Error getting items below par level:", error); diff --git a/routers/dashRouter.ts b/routers/dashRouter.ts index 0f55eba4..83e37c58 100644 --- a/routers/dashRouter.ts +++ b/routers/dashRouter.ts @@ -6,8 +6,8 @@ const dashController = new DashController(); export class DashRouter { routes = () => { const router = Router(); - router.get("/getexpiry", dashController.getExpiringItemsCount); - router.get("/getbelowpar", dashController.getItemsBelowPar); + router.get("/getexpiry/:buildingId", dashController.getExpiringItemsCount); + router.get("/getbelowpar/:buildingId", dashController.getItemsBelowPar); return router; }; } From afd461eade9106e43de63239b4d08f3fbe781106 Mon Sep 17 00:00:00 2001 From: patrickkok Date: Sat, 13 Apr 2024 17:30:26 +0800 Subject: [PATCH 39/44] Update getAllItems method to only return Items in Rooms the user has access to --- controllers/buildingController.ts | 2 +- controllers/itemsController.ts | 42 +++++++++++++++++++++++-------- routers/itemsRouter.ts | 2 +- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/controllers/buildingController.ts b/controllers/buildingController.ts index c8bea074..c931a7b7 100644 --- a/controllers/buildingController.ts +++ b/controllers/buildingController.ts @@ -85,7 +85,7 @@ export class BuildingsController { const newBuildingUser = { building_id: buildingId, user_id: user.id, - admin: false, + admin: admin, }; return await BuildingUser.create(newBuildingUser, { transaction: t }); } diff --git a/controllers/itemsController.ts b/controllers/itemsController.ts index d59cd492..dc41ab52 100644 --- a/controllers/itemsController.ts +++ b/controllers/itemsController.ts @@ -1,19 +1,41 @@ import { Request, Response } from "express"; -import { Item, RoomItem, Room, CartLineItem } from "../db/models"; +import { sequelize } from "../db/models"; +import { Op } from "sequelize"; +import { + Item, + RoomItem, + Room, + CartLineItem, + Building, + BuildingUser, +} from "../db/models"; export class ItemsController { async getAllItems(req: Request, res: Response) { + const userId = req.params.userId; try { - const output = await Item.findAll({ - include: [ - { - model: RoomItem, - include: [{ model: Room, attributes: ["name"] }], - }, - ], - order: [["id", "ASC"]], + const result = await sequelize.transaction(async (t) => { + const buildings = await Building.findAll({ + include: [{ model: BuildingUser, where: { user_id: userId } }], + }); + const buildingIds = buildings.map((building) => building.id); + const rooms = await Room.findAll({ + where: { building_id: { [Op.in]: buildingIds } }, + }); + const roomIds = rooms.map((room) => room.id); + const output = await Item.findAll({ + include: [ + { + model: RoomItem, + include: [{ model: Room, attributes: ["name"] }], + where: { room_id: { [Op.in]: roomIds } }, + }, + ], + order: [["id", "ASC"]], + }); + return output; }); - return res.json(output); + return res.json(result); } catch (err) { return res.status(400).json({ error: true, msg: (err as Error).message }); } diff --git a/routers/itemsRouter.ts b/routers/itemsRouter.ts index eaffb5aa..1f1481fc 100644 --- a/routers/itemsRouter.ts +++ b/routers/itemsRouter.ts @@ -6,7 +6,7 @@ const itemsController = new ItemsController(); export class ItemsRouter { routes = () => { const router = Router(); - router.get("/allitems", itemsController.getAllItems); + router.get("/allitems/:userId", itemsController.getAllItems); router.get("/allrooms", itemsController.getAllRooms); router.get("/finditem/:itemId/:roomId", itemsController.findOneItem); router.get("/findserial/:serialNum/:roomId", itemsController.findBySerial); From 9ecc8b833c9a6cd422346bcbe3efe30ea626f4b2 Mon Sep 17 00:00:00 2001 From: patrickkok Date: Sat, 13 Apr 2024 17:39:55 +0800 Subject: [PATCH 40/44] Update getAllRooms to only show the rooms the user is part of --- controllers/itemsController.ts | 14 ++++++++++++-- routers/itemsRouter.ts | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/controllers/itemsController.ts b/controllers/itemsController.ts index dc41ab52..295de29a 100644 --- a/controllers/itemsController.ts +++ b/controllers/itemsController.ts @@ -42,9 +42,19 @@ export class ItemsController { } async getAllRooms(req: Request, res: Response) { + const userId = req.params.userId; try { - const output = await Room.findAll({ order: [["id", "ASC"]] }); - return res.json(output); + const result = await sequelize.transaction(async (t) => { + const buildings = await Building.findAll({ + include: [{ model: BuildingUser, where: { user_id: userId } }], + }); + const buildingIds = buildings.map((building) => building.id); + const rooms = await Room.findAll({ + where: { building_id: { [Op.in]: buildingIds } }, + }); + return rooms; + }); + return res.json(result); } catch (err) { return res.status(400).json({ error: true, msg: (err as Error).message }); } diff --git a/routers/itemsRouter.ts b/routers/itemsRouter.ts index 1f1481fc..927fcd75 100644 --- a/routers/itemsRouter.ts +++ b/routers/itemsRouter.ts @@ -7,7 +7,7 @@ export class ItemsRouter { routes = () => { const router = Router(); router.get("/allitems/:userId", itemsController.getAllItems); - router.get("/allrooms", itemsController.getAllRooms); + router.get("/allrooms/:userId", itemsController.getAllRooms); router.get("/finditem/:itemId/:roomId", itemsController.findOneItem); router.get("/findserial/:serialNum/:roomId", itemsController.findBySerial); router.get("/items/:roomId", itemsController.getRoomItems); From fddfe390feed07a37bf312f6e007b3bef95f5f8c Mon Sep 17 00:00:00 2001 From: magiicloud Date: Sun, 14 Apr 2024 14:36:52 +0800 Subject: [PATCH 41/44] changed back to rawQuery to sum par quantities --- controllers/dashController.ts | 68 ++++++++++++++++------------------- 1 file changed, 31 insertions(+), 37 deletions(-) diff --git a/controllers/dashController.ts b/controllers/dashController.ts index 647716c2..dc0167a0 100644 --- a/controllers/dashController.ts +++ b/controllers/dashController.ts @@ -42,52 +42,46 @@ export class DashController { async getItemsBelowPar(req: Request, res: Response) { const buildingId = req.params.buildingId; + + const rawFindQuery = ` + SELECT "Item"."id", "Item"."serial_num", "Item"."item_name", "Item"."par_level", COALESCE(SUM("roomItems"."quantity"), 0) AS "itemTotal" + FROM "Items" AS "Item" + LEFT JOIN "Room_Items" AS "roomItems" ON "roomItems"."item_id" = "Item"."id" + LEFT JOIN "Rooms" AS "Rooms" ON "Rooms"."id" = "roomItems"."room_id" + WHERE "Rooms"."building_id" = ${buildingId} + GROUP BY "Item"."id", "Item"."serial_num", "Item"."item_name", "Item"."par_level" + HAVING COALESCE(SUM("roomItems"."quantity"), 0) <= ("Item"."par_level" * 1.5) + ORDER BY "itemTotal" ASC; + `; + + const rawCountQuery = ` + SELECT COUNT(*) + FROM ( + SELECT "Item"."id" + FROM "Items" AS "Item" + LEFT JOIN "Room_Items" AS "roomItems" ON "roomItems"."item_id" = "Item"."id" + LEFT JOIN "Rooms" AS "Rooms" ON "Rooms"."id" = "roomItems"."room_id" + WHERE "Rooms"."building_id" = ${buildingId} + GROUP BY "Item"."id" + HAVING COALESCE(SUM("roomItems"."quantity"), 0) <= ("Item"."par_level" * 1.5) + ) AS FilteredItems; + `; + try { - const itemsBelowPar = await RoomItem.findAll({ - include: [ - { - model: Item, - attributes: ["par_level", "serial_num", "item_name"], - }, - { - model: Room, - attributes: ["name", "building_id"], - where: { building_id: buildingId }, - }, - ], - attributes: { - include: [ - // Include a custom attribute that flags if the quantity is below 50% of the par level - [ - sequelize.literal(`"RoomItem"."quantity" * 100 /item.par_level`), - "parPercent", - ], - ], - }, - where: sequelize.literal( - // only include items 150% or below par level - `"RoomItem"."quantity" * 100 /item.par_level <= 150` - ), - order: [ - // Order the results by the custom attribute isBelowPar in ascending order - [ - sequelize.literal(`"RoomItem"."quantity" * 100 /item.par_level`), - "ASC", - ], - ], + const itemsBelowPar = await sequelize.query(rawFindQuery, { + type: QueryTypes.SELECT, + }); + const countItemsBelowPar = await sequelize.query(rawCountQuery, { + type: QueryTypes.SELECT, }); res.json({ success: true, - count: itemsBelowPar.length, items: itemsBelowPar, + count: countItemsBelowPar, }); } catch (error) { console.error("Error getting items below par level:", error); - res.status(500).json({ - success: false, - message: "Failed to get items below par level", - }); } } } From a06a7b1568eca5c26f668b151ab28090af969717 Mon Sep 17 00:00:00 2001 From: patrickkok Date: Sun, 14 Apr 2024 23:58:36 +0800 Subject: [PATCH 42/44] Update readme --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b95e64a9..d52c044d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ # Rocket Academy Coding Bootcamp: Project 3 Backend -Run `npm i` to install NPM packages, then `npm start` to start the Express server. +The backend for Stock Trackr, a project by Patrick Kok and Hong Yun + +Run `npm i` to install NPM packages, then `npm run build` followed by `npm run start` to start the Express server. From 8c36f7ce485a90dc3fc203ad1df916b4ba025c87 Mon Sep 17 00:00:00 2001 From: magiicloud Date: Tue, 16 Apr 2024 16:31:32 +0800 Subject: [PATCH 43/44] added fly io deployment configs --- .dockerignore | 3 + .gitignore | 3 +- Dockerfile | 34 ++++++++++ config/database.js | 7 ++ config/database.ts | 18 +++++ db/models/index.ts | 113 +++++++++++++++++++++++--------- index.ts | 21 +++--- package-lock.json | 160 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 3 +- release.sh | 3 + 10 files changed, 323 insertions(+), 42 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 config/database.ts create mode 100644 release.sh diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..b3eb616a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +node_modules/ +.env +dist/ \ No newline at end of file diff --git a/.gitignore b/.gitignore index b3eb616a..2858ab87 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules/ .env -dist/ \ No newline at end of file +dist/ +fly.toml \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..bc570a0e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,34 @@ +FROM debian:bullseye as builder + +ENV PATH=/usr/local/node/bin:$PATH +ARG NODE_VERSION=16.15.1 + +RUN apt-get update; apt install -y curl python-is-python3 pkg-config build-essential && \ + curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \ + /tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \ +rm -rf /tmp/node-build-master + +RUN mkdir /app +WORKDIR /app + +COPY . . + +RUN npm install +RUN npm run build + +FROM debian:bullseye-slim + +LABEL fly_launch_runtime="nodejs" + +COPY --from=builder /usr/local/node /usr/local/node +COPY --from=builder /app /app +COPY release.sh /release.sh + +WORKDIR /app +ENV NODE_ENV production +ENV PATH /usr/local/node/bin:$PATH + +# Debug: List contents of app directory +RUN ls -al /app + +CMD [ "npm", "run", "start" ] \ No newline at end of file diff --git a/config/database.js b/config/database.js index bed84df2..667b2048 100644 --- a/config/database.js +++ b/config/database.js @@ -8,4 +8,11 @@ module.exports = { host: process.env.DB_HOST, dialect: process.env.DB_DIALECT, }, + production: { + username: process.env.USERNAME, + password: process.env.PASSWORD, + database: process.env.DATABASE, + host: process.env.HOST, + dialect: process.env.DIALECT, + }, }; diff --git a/config/database.ts b/config/database.ts new file mode 100644 index 00000000..667b2048 --- /dev/null +++ b/config/database.ts @@ -0,0 +1,18 @@ +require("dotenv").config(); + +module.exports = { + development: { + username: process.env.DB_USERNAME, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + host: process.env.DB_HOST, + dialect: process.env.DB_DIALECT, + }, + production: { + username: process.env.USERNAME, + password: process.env.PASSWORD, + database: process.env.DATABASE, + host: process.env.HOST, + dialect: process.env.DIALECT, + }, +}; diff --git a/db/models/index.ts b/db/models/index.ts index 4eb1240e..418bc2b1 100644 --- a/db/models/index.ts +++ b/db/models/index.ts @@ -10,39 +10,92 @@ import { Transaction } from "./Transaction"; import { User } from "./User"; import { Dialect } from "sequelize"; import dotenv from "dotenv"; +import path from "path"; dotenv.config(); -const sequelize = new Sequelize({ - username: process.env.DB_USERNAME, - password: process.env.DB_PASSWORD, - database: process.env.DB_NAME, - host: process.env.DB_HOST, - dialect: process.env.DB_DIALECT as Dialect, - models: [ - Building, - BuildingUser, - CartLineItem, - Item, - Cart, - Room, - RoomItem, - Transaction, - User, - ], -}); +const env = process.env.NODE_ENV || "development"; +const config = require(path.join( + __dirname, + "..", + "..", + "config", + "database.js" +))[env]; -// Attach models to Sequelize instance -sequelize.addModels([ - Building, - BuildingUser, - CartLineItem, - Item, - Cart, - Room, - RoomItem, - Transaction, - User, -]); +let sequelize: Sequelize; + +if (process.env.DATABASE_URL) { + sequelize = new Sequelize(process.env.DATABASE_URL, { + username: process.env.DB_USERNAME, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + host: process.env.DB_HOST, + dialect: process.env.DB_DIALECT as Dialect, + models: [ + Building, + BuildingUser, + CartLineItem, + Item, + Cart, + Room, + RoomItem, + Transaction, + User, + ], + }); +} else if (config.use_env_variable) { + // If your configuration specifies a variable (e.g., DATABASE_URL), use it + const dbUrl = process.env[config.use_env_variable]!; + sequelize = new Sequelize(dbUrl, config); +} else { + // Use the configuration file details + sequelize = new Sequelize(config.database, config.username, config.password, { + ...config, + models: [ + Building, + BuildingUser, + CartLineItem, + Item, + Cart, + Room, + RoomItem, + Transaction, + User, + ], + }); +} + +// const sequelize = new Sequelize({ +// username: process.env.DB_USERNAME, +// password: process.env.DB_PASSWORD, +// database: process.env.DB_NAME, +// host: process.env.DB_HOST, +// dialect: process.env.DB_DIALECT as Dialect, +// models: [ +// Building, +// BuildingUser, +// CartLineItem, +// Item, +// Cart, +// Room, +// RoomItem, +// Transaction, +// User, +// ], +// }); + +// // Attach models to Sequelize instance +// sequelize.addModels([ +// Building, +// BuildingUser, +// CartLineItem, +// Item, +// Cart, +// Room, +// RoomItem, +// Transaction, +// User, +// ]); // Export model instance export { diff --git a/index.ts b/index.ts index 85acbafe..67c9c129 100644 --- a/index.ts +++ b/index.ts @@ -10,7 +10,7 @@ import { UsersRouter } from "./routers/usersRouter"; dotenv.config(); -const PORT = process.env.PORT; +const PORT = process.env.PORT || 3000; const app = express(); // Authorization middleware. When used, the Access Token must @@ -33,15 +33,16 @@ const cartRouter = new CartRouter().routes(); const dashRouter = new DashRouter().routes(); const usersrouter = new UsersRouter().routes(); -// app.use(checkJwt, itemsRouter); -// app.use(checkJwt, buildingsRouter); -// app.use(checkJwt, cartRouter); -// app.use(checkJwt, dashRouter); -app.use(itemsRouter); -app.use(buildingsRouter); -app.use(cartRouter); -app.use(dashRouter); -app.use(usersrouter); +app.use(checkJwt, itemsRouter); +app.use(checkJwt, buildingsRouter); +app.use(checkJwt, cartRouter); +app.use(checkJwt, dashRouter); +app.use(checkJwt, usersrouter); +// app.use(itemsRouter); +// app.use(buildingsRouter); +// app.use(cartRouter); +// app.use(dashRouter); +// app.use(usersrouter); app.listen(PORT, () => { console.log(`Express app listening on port ${PORT}!`); diff --git a/package-lock.json b/package-lock.json index 5917273a..e611d113 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "sequelize-typescript": "^2.1.6" }, "devDependencies": { + "@flydotio/dockerfile": "^0.5.4", "@types/cors": "^2.8.17", "@types/express": "^4.17.21", "@types/node": "^20.11.30", @@ -93,6 +94,78 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@flydotio/dockerfile": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@flydotio/dockerfile/-/dockerfile-0.5.4.tgz", + "integrity": "sha512-pglzQeVXVjCk/UCoY+g/jtr4i0zN+1BRTR35rFB4mNWZx/4cxBVa70zH1+N80TvOQ9y3ydB1M8258flr0bM/CQ==", + "dev": true, + "dependencies": { + "chalk": "^5.3.0", + "diff": "^5.1.0", + "ejs": "^3.1.9", + "shell-quote": "^1.8.1", + "yargs": "^17.7.2" + }, + "bin": { + "dockerfile": "index.js" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@flydotio/dockerfile/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@flydotio/dockerfile/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@flydotio/dockerfile/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@flydotio/dockerfile/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", @@ -495,6 +568,12 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "dev": true + }, "node_modules/at-least-node": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", @@ -822,6 +901,15 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -903,6 +991,21 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -1302,6 +1405,36 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/finalhandler": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", @@ -1768,6 +1901,24 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/jake": { + "version": "10.8.7", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", + "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "dev": true, + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/jose": { "version": "4.15.5", "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz", @@ -2908,6 +3059,15 @@ "node": ">=8" } }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/side-channel": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", diff --git a/package.json b/package.json index a0a6ae1f..237a48bc 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "scripts": { "build": "rm -rf ./dist && npx tsc", - "start": "nodemon ./dist/index.js", + "start": "node ./dist/index.js", "dev": "npx tsc -w & nodemon ./dist/index.js", "clean": "npx tsc --build --clean" }, @@ -19,6 +19,7 @@ "sequelize-typescript": "^2.1.6" }, "devDependencies": { + "@flydotio/dockerfile": "^0.5.4", "@types/cors": "^2.8.17", "@types/express": "^4.17.21", "@types/node": "^20.11.30", diff --git a/release.sh b/release.sh new file mode 100644 index 00000000..f2feba5f --- /dev/null +++ b/release.sh @@ -0,0 +1,3 @@ +npx sequelize db:create +npx sequelize db:migrate +npx sequelize db:seed:all \ No newline at end of file From d5b1f4fdbd1cf39b5b2ba264144d24ea62641b25 Mon Sep 17 00:00:00 2001 From: magiicloud Date: Sat, 20 Apr 2024 18:27:06 +0800 Subject: [PATCH 44/44] added code to deploy to fly.io and cleaned up all codes --- .sequelizerc | 2 +- controllers/buildingController.ts | 2 - controllers/itemsController.ts | 1 - controllers/usersController.ts | 13 +---- db/models/Building.ts | 9 +--- db/models/index.ts | 60 ++++++++------------- db/seeders/20240326034148-demo-user.ts | 9 ++++ db/seeders/20240326050453-tertiary-seeds.ts | 7 +++ index.ts | 5 -- package.json | 1 - 10 files changed, 40 insertions(+), 69 deletions(-) diff --git a/.sequelizerc b/.sequelizerc index 466f578c..944f2499 100644 --- a/.sequelizerc +++ b/.sequelizerc @@ -1,7 +1,7 @@ const path = require("path"); module.exports = { - config: path.resolve("config", "database.js"), + config: path.resolve("dist", "config", "database.js"), "models-path": path.resolve("dist", "db", "models"), "seeders-path": path.resolve("dist", "db", "seeders"), "migrations-path": path.resolve("dist", "db", "migrations"), diff --git a/controllers/buildingController.ts b/controllers/buildingController.ts index c931a7b7..f185e92e 100644 --- a/controllers/buildingController.ts +++ b/controllers/buildingController.ts @@ -1,7 +1,5 @@ import { Request, Response } from "express"; import { Building, BuildingUser, User, Room, sequelize } from "../db/models"; -import { Sequelize } from "sequelize-typescript"; -import { Dialect, Transaction } from "sequelize"; interface RoomAttributes { name: string; diff --git a/controllers/itemsController.ts b/controllers/itemsController.ts index 295de29a..33c2bab7 100644 --- a/controllers/itemsController.ts +++ b/controllers/itemsController.ts @@ -102,7 +102,6 @@ export class ItemsController { async getRoomItems(req: Request, res: Response) { try { const { roomId } = req.params; - console.log(roomId); const output = await Item.findAll({ include: [ { diff --git a/controllers/usersController.ts b/controllers/usersController.ts index c93df996..4f4c2f85 100644 --- a/controllers/usersController.ts +++ b/controllers/usersController.ts @@ -1,16 +1,5 @@ import { Request, Response } from "express"; -import { Building, BuildingUser, User, Room, sequelize } from "../db/models"; -import { Sequelize } from "sequelize-typescript"; -import { Dialect, Transaction, where } from "sequelize"; - -interface RoomAttributes { - name: string; - left: Float64Array; - top: Float64Array; - width: Float64Array; - height: Float64Array; - building_id: number; -} +import { User } from "../db/models"; export class UsersController { async updateUser(req: Request, res: Response) { diff --git a/db/models/Building.ts b/db/models/Building.ts index 2cd13a21..b342f887 100644 --- a/db/models/Building.ts +++ b/db/models/Building.ts @@ -1,11 +1,4 @@ -import { - Table, - Column, - Model, - DataType, - HasMany, - BelongsToMany, -} from "sequelize-typescript"; +import { Table, Column, Model, DataType, HasMany } from "sequelize-typescript"; import { Room } from "./Room"; import { User } from "./User"; import { BuildingUser } from "./BuildingUser"; diff --git a/db/models/index.ts b/db/models/index.ts index 418bc2b1..e8ac8d56 100644 --- a/db/models/index.ts +++ b/db/models/index.ts @@ -25,12 +25,12 @@ const config = require(path.join( let sequelize: Sequelize; if (process.env.DATABASE_URL) { - sequelize = new Sequelize(process.env.DATABASE_URL, { - username: process.env.DB_USERNAME, - password: process.env.DB_PASSWORD, - database: process.env.DB_NAME, - host: process.env.DB_HOST, - dialect: process.env.DB_DIALECT as Dialect, + sequelize = new Sequelize({ + username: process.env.USERNAME, + password: process.env.PASSWORD, + database: process.env.DATABASE, + host: process.env.HOST, + dialect: process.env.DIALECT as Dialect, models: [ Building, BuildingUser, @@ -49,8 +49,12 @@ if (process.env.DATABASE_URL) { sequelize = new Sequelize(dbUrl, config); } else { // Use the configuration file details - sequelize = new Sequelize(config.database, config.username, config.password, { - ...config, + sequelize = new Sequelize({ + username: process.env.DB_USERNAME, + password: process.env.DB_PASSWORD, + database: process.env.DB_NAME, + host: process.env.DB_HOST, + dialect: process.env.DB_DIALECT as Dialect, models: [ Building, BuildingUser, @@ -65,37 +69,15 @@ if (process.env.DATABASE_URL) { }); } -// const sequelize = new Sequelize({ -// username: process.env.DB_USERNAME, -// password: process.env.DB_PASSWORD, -// database: process.env.DB_NAME, -// host: process.env.DB_HOST, -// dialect: process.env.DB_DIALECT as Dialect, -// models: [ -// Building, -// BuildingUser, -// CartLineItem, -// Item, -// Cart, -// Room, -// RoomItem, -// Transaction, -// User, -// ], -// }); - -// // Attach models to Sequelize instance -// sequelize.addModels([ -// Building, -// BuildingUser, -// CartLineItem, -// Item, -// Cart, -// Room, -// RoomItem, -// Transaction, -// User, -// ]); +// Confirms the connection to the database +(async () => { + try { + await sequelize.authenticate(); + console.log("Connected to the database!"); + } catch (err) { + console.error("Error connecting to the database:", err); + } +})(); // Export model instance export { diff --git a/db/seeders/20240326034148-demo-user.ts b/db/seeders/20240326034148-demo-user.ts index e95a3c20..30ba4512 100644 --- a/db/seeders/20240326034148-demo-user.ts +++ b/db/seeders/20240326034148-demo-user.ts @@ -30,6 +30,15 @@ module.exports = { created_at: new Date(), updated_at: new Date(), }, + { + auth_id: "windowslive|5ff4a6dbea093d1d", + name: "Hong Yun Wong", + email: "hongyun_rc@outlook.com", + profile_img_url: + "https://s.gravatar.com/avatar/52b9fc7d5c6203f683d78a11f75b0497?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fhy.png", + created_at: new Date(), + updated_at: new Date(), + }, ]); await queryInterface.bulkInsert("Items", [ diff --git a/db/seeders/20240326050453-tertiary-seeds.ts b/db/seeders/20240326050453-tertiary-seeds.ts index 758b2619..3a359ad8 100644 --- a/db/seeders/20240326050453-tertiary-seeds.ts +++ b/db/seeders/20240326050453-tertiary-seeds.ts @@ -27,6 +27,13 @@ module.exports = { created_at: new Date(), updated_at: new Date(), }, + { + building_id: 1, + user_id: 4, + admin: true, + created_at: new Date(), + updated_at: new Date(), + }, ]); await queryInterface.bulkInsert("Cart_Line_Items", [ diff --git a/index.ts b/index.ts index 67c9c129..2367dbca 100644 --- a/index.ts +++ b/index.ts @@ -38,11 +38,6 @@ app.use(checkJwt, buildingsRouter); app.use(checkJwt, cartRouter); app.use(checkJwt, dashRouter); app.use(checkJwt, usersrouter); -// app.use(itemsRouter); -// app.use(buildingsRouter); -// app.use(cartRouter); -// app.use(dashRouter); -// app.use(usersrouter); app.listen(PORT, () => { console.log(`Express app listening on port ${PORT}!`); diff --git a/package.json b/package.json index 237a48bc..79231b81 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,6 @@ "dotenv": "^16.4.5", "express": "^4.18.1", "express-oauth2-jwt-bearer": "^1.6.0", - "mysql2": "^3.9.3", "pg": "^8.11.3", "reflect-metadata": "^0.2.1", "sequelize": "^6.37.1",